Make transactions in execution layer integration tests (#3320)
## Issue Addressed Resolves #3159 ## Proposed Changes Sends transactions to the EE before requesting for a payload in the `execution_integration_tests`. Made some changes to the integration tests in order to be able to sign and publish transactions to the EE: 1. `genesis.json` for both geth and nethermind was modified to include pre-funded accounts that we know private keys for 2. Using the unauthenticated port again in order to make `eth_sendTransaction` and calls from the `personal` namespace to import keys Also added a `fcu` call with `PayloadAttributes` before calling `getPayload` in order to give EEs sufficient time to pack transactions into the payload.
This commit is contained in:
parent
2ed51c364d
commit
da7b7a0f60
190
Cargo.lock
generated
190
Cargo.lock
generated
@ -189,6 +189,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async_io_stream"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c"
|
||||||
|
dependencies = [
|
||||||
|
"futures",
|
||||||
|
"pharos",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asynchronous-codec"
|
name = "asynchronous-codec"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@ -224,6 +235,18 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "auto_impl"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -1865,14 +1888,53 @@ dependencies = [
|
|||||||
"tiny-keccak",
|
"tiny-keccak",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethers-providers"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "git+https://github.com/gakonst/ethers-rs?rev=02ad93a1cfb7b62eb051c77c61dc4c0218428e4a#02ad93a1cfb7b62eb051c77c61dc4c0218428e4a"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"auto_impl",
|
||||||
|
"base64",
|
||||||
|
"ethers-core",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-timer",
|
||||||
|
"futures-util",
|
||||||
|
"hex",
|
||||||
|
"http",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot 0.11.2",
|
||||||
|
"pin-project 1.0.11",
|
||||||
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-tungstenite 0.17.1",
|
||||||
|
"tracing",
|
||||||
|
"tracing-futures",
|
||||||
|
"url",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"wasm-timer",
|
||||||
|
"web-sys",
|
||||||
|
"ws_stream_wasm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "execution_engine_integration"
|
name = "execution_engine_integration"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"deposit_contract",
|
||||||
"environment",
|
"environment",
|
||||||
|
"ethers-core",
|
||||||
|
"ethers-providers",
|
||||||
"execution_layer",
|
"execution_layer",
|
||||||
"exit-future",
|
"exit-future",
|
||||||
"futures",
|
"futures",
|
||||||
|
"hex",
|
||||||
|
"reqwest",
|
||||||
"sensitive_url",
|
"sensitive_url",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"task_executor",
|
"task_executor",
|
||||||
@ -2620,6 +2682,19 @@ dependencies = [
|
|||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-rustls"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
|
||||||
|
dependencies = [
|
||||||
|
"http",
|
||||||
|
"hyper",
|
||||||
|
"rustls 0.20.6",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls 0.23.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-tls"
|
name = "hyper-tls"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -2758,6 +2833,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4351,6 +4429,16 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pharos"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414"
|
||||||
|
dependencies = [
|
||||||
|
"futures",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "0.4.30"
|
version = "0.4.30"
|
||||||
@ -5038,6 +5126,7 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"hyper-rustls",
|
||||||
"hyper-tls",
|
"hyper-tls",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@ -5047,17 +5136,21 @@ dependencies = [
|
|||||||
"native-tls",
|
"native-tls",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite 0.2.9",
|
"pin-project-lite 0.2.9",
|
||||||
|
"rustls 0.20.6",
|
||||||
|
"rustls-pemfile",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
|
"tokio-rustls 0.23.4",
|
||||||
"tokio-util 0.7.3",
|
"tokio-util 0.7.3",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
|
"webpki-roots",
|
||||||
"winreg 0.10.1",
|
"winreg 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -5219,6 +5312,15 @@ dependencies = [
|
|||||||
"webpki 0.22.0",
|
"webpki 0.22.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -5437,6 +5539,12 @@ dependencies = [
|
|||||||
"pest",
|
"pest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "send_wrapper"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sensitive_url"
|
name = "sensitive_url"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -6398,6 +6506,17 @@ dependencies = [
|
|||||||
"webpki 0.21.4",
|
"webpki 0.21.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.23.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.20.6",
|
||||||
|
"tokio",
|
||||||
|
"webpki 0.22.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@ -6420,7 +6539,23 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"pin-project 1.0.11",
|
"pin-project 1.0.11",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tungstenite",
|
"tungstenite 0.14.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-tungstenite"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06cda1232a49558c46f8a504d5b93101d42c0bf7f911f12a105ba48168f821ae"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"rustls 0.20.6",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls 0.23.4",
|
||||||
|
"tungstenite 0.17.2",
|
||||||
|
"webpki 0.22.0",
|
||||||
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6502,6 +6637,16 @@ dependencies = [
|
|||||||
"valuable",
|
"valuable",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-futures"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project 1.0.11",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-log"
|
name = "tracing-log"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -6644,6 +6789,27 @@ dependencies = [
|
|||||||
"utf-8",
|
"utf-8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.17.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"rustls 0.20.6",
|
||||||
|
"sha-1 0.10.0",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"utf-8",
|
||||||
|
"webpki 0.22.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twoway"
|
name = "twoway"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -6991,9 +7157,9 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls 0.22.0",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite 0.15.0",
|
||||||
"tokio-util 0.6.10",
|
"tokio-util 0.6.10",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -7378,6 +7544,24 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ws_stream_wasm"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47ca1ab42f5afed7fc332b22b6e932ca5414b209465412c8cdf0ad23bc0de645"
|
||||||
|
dependencies = [
|
||||||
|
"async_io_stream",
|
||||||
|
"futures",
|
||||||
|
"js-sys",
|
||||||
|
"pharos",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
"send_wrapper",
|
||||||
|
"thiserror",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wyz"
|
name = "wyz"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -15,3 +15,8 @@ execution_layer = { path = "../../beacon_node/execution_layer" }
|
|||||||
sensitive_url = { path = "../../common/sensitive_url" }
|
sensitive_url = { path = "../../common/sensitive_url" }
|
||||||
types = { path = "../../consensus/types" }
|
types = { path = "../../consensus/types" }
|
||||||
unused_port = { path = "../../common/unused_port" }
|
unused_port = { path = "../../common/unused_port" }
|
||||||
|
ethers-core = { git = "https://github.com/gakonst/ethers-rs", rev = "02ad93a1cfb7b62eb051c77c61dc4c0218428e4a" }
|
||||||
|
ethers-providers = { git = "https://github.com/gakonst/ethers-rs", rev = "02ad93a1cfb7b62eb051c77c61dc4c0218428e4a" }
|
||||||
|
deposit_contract = { path = "../../common/deposit_contract" }
|
||||||
|
reqwest = { version = "0.11.0", features = ["json"] }
|
||||||
|
hex = "0.4.2"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use ethers_providers::{Http, Provider};
|
||||||
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;
|
||||||
@ -5,6 +6,14 @@ use std::process::Child;
|
|||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp_port;
|
||||||
|
|
||||||
|
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
||||||
|
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
||||||
|
pub const ACCOUNT2: &str = "dA2DD7560DB7e212B945fC72cEB54B7D8C886D77";
|
||||||
|
pub const PRIVATE_KEYS: [&str; 2] = [
|
||||||
|
"115fe42a60e5ef45f5490e599add1f03c73aeaca129c2c41451eca6cf8ff9e04",
|
||||||
|
"6a692e710077d9000be1326acbe32f777b403902ac8779b19eb1398b849c99c3",
|
||||||
|
];
|
||||||
|
|
||||||
/// Defined for each EE type (e.g., Geth, Nethermind, etc).
|
/// Defined for each EE type (e.g., Geth, Nethermind, etc).
|
||||||
pub trait GenericExecutionEngine: Clone {
|
pub trait GenericExecutionEngine: Clone {
|
||||||
fn init_datadir() -> TempDir;
|
fn init_datadir() -> TempDir;
|
||||||
@ -22,8 +31,10 @@ pub struct ExecutionEngine<E> {
|
|||||||
engine: E,
|
engine: E,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
datadir: TempDir,
|
datadir: TempDir,
|
||||||
|
http_port: u16,
|
||||||
http_auth_port: u16,
|
http_auth_port: u16,
|
||||||
child: Child,
|
child: Child,
|
||||||
|
pub provider: Provider<Http>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> Drop for ExecutionEngine<E> {
|
impl<E> Drop for ExecutionEngine<E> {
|
||||||
@ -42,11 +53,15 @@ impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
|||||||
let http_port = unused_tcp_port().unwrap();
|
let http_port = unused_tcp_port().unwrap();
|
||||||
let http_auth_port = unused_tcp_port().unwrap();
|
let http_auth_port = unused_tcp_port().unwrap();
|
||||||
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
||||||
|
let provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
||||||
|
.expect("failed to instantiate ethers provider");
|
||||||
Self {
|
Self {
|
||||||
engine,
|
engine,
|
||||||
datadir,
|
datadir,
|
||||||
|
http_port,
|
||||||
http_auth_port,
|
http_auth_port,
|
||||||
child,
|
child,
|
||||||
|
provider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +69,10 @@ impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
|||||||
SensitiveUrl::parse(&format!("http://127.0.0.1:{}", self.http_auth_port)).unwrap()
|
SensitiveUrl::parse(&format!("http://127.0.0.1:{}", self.http_auth_port)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn http_url(&self) -> SensitiveUrl {
|
||||||
|
SensitiveUrl::parse(&format!("http://127.0.0.1:{}", self.http_port)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn datadir(&self) -> PathBuf {
|
pub fn datadir(&self) -> PathBuf {
|
||||||
self.datadir.path().to_path_buf()
|
self.datadir.path().to_path_buf()
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,12 @@ pub fn geth_genesis_json() -> Value {
|
|||||||
"mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
|
"mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
"coinbase":"0x0000000000000000000000000000000000000000",
|
"coinbase":"0x0000000000000000000000000000000000000000",
|
||||||
"alloc":{
|
"alloc":{
|
||||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b":{"balance":"0x6d6172697573766477000000"}
|
"0x7b8C3a386C0eea54693fFB0DA17373ffC9228139": {
|
||||||
|
"balance": "10000000000000000000000000"
|
||||||
|
},
|
||||||
|
"0xdA2DD7560DB7e212B945fC72cEB54B7D8C886D77": {
|
||||||
|
"balance": "10000000000000000000000000"
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"number":"0x0",
|
"number":"0x0",
|
||||||
"gasUsed":"0x0",
|
"gasUsed":"0x0",
|
||||||
@ -40,3 +45,87 @@ pub fn geth_genesis_json() -> Value {
|
|||||||
"baseFeePerGas":"0x7"
|
"baseFeePerGas":"0x7"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Modified kiln config
|
||||||
|
pub fn nethermind_genesis_json() -> Value {
|
||||||
|
json!(
|
||||||
|
{
|
||||||
|
"name": "lighthouse_test_network",
|
||||||
|
"engine": {
|
||||||
|
"Ethash": {
|
||||||
|
"params": {
|
||||||
|
"minimumDifficulty": "0x20000",
|
||||||
|
"difficultyBoundDivisor": "0x800",
|
||||||
|
"durationLimit": "0xd",
|
||||||
|
"blockReward": {
|
||||||
|
"0x0": "0x1BC16D674EC80000"
|
||||||
|
},
|
||||||
|
"homesteadTransition": "0x0",
|
||||||
|
"eip100bTransition": "0x0",
|
||||||
|
"difficultyBombDelays": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x400",
|
||||||
|
"registrar": "0x0000000000000000000000000000000000000000",
|
||||||
|
"accountStartNonce": "0x0",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID": "0x1469ca",
|
||||||
|
"MergeForkIdTransition": "0x3e8",
|
||||||
|
"eip150Transition": "0x0",
|
||||||
|
"eip158Transition": "0x0",
|
||||||
|
"eip160Transition": "0x0",
|
||||||
|
"eip161abcTransition": "0x0",
|
||||||
|
"eip161dTransition": "0x0",
|
||||||
|
"eip155Transition": "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": "0x1234",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x01",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x0",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "",
|
||||||
|
"gasLimit": "0x1C9C380"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0x7b8C3a386C0eea54693fFB0DA17373ffC9228139": {
|
||||||
|
"balance": "10000000000000000000000000"
|
||||||
|
},
|
||||||
|
"0xdA2DD7560DB7e212B945fC72cEB54B7D8C886D77": {
|
||||||
|
"balance": "10000000000000000000000000"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"nodes": []
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -90,13 +90,14 @@ impl GenericExecutionEngine for GethEngine {
|
|||||||
.arg(datadir.path().to_str().unwrap())
|
.arg(datadir.path().to_str().unwrap())
|
||||||
.arg("--http")
|
.arg("--http")
|
||||||
.arg("--http.api")
|
.arg("--http.api")
|
||||||
.arg("engine,eth")
|
.arg("engine,eth,personal")
|
||||||
.arg("--http.port")
|
.arg("--http.port")
|
||||||
.arg(http_port.to_string())
|
.arg(http_port.to_string())
|
||||||
.arg("--authrpc.port")
|
.arg("--authrpc.port")
|
||||||
.arg(http_auth_port.to_string())
|
.arg(http_auth_port.to_string())
|
||||||
.arg("--port")
|
.arg("--port")
|
||||||
.arg(network_port.to_string())
|
.arg(network_port.to_string())
|
||||||
|
.arg("--allow-insecure-unlock")
|
||||||
.arg("--authrpc.jwtsecret")
|
.arg("--authrpc.jwtsecret")
|
||||||
.arg(jwt_secret_path.as_path().to_str().unwrap())
|
.arg(jwt_secret_path.as_path().to_str().unwrap())
|
||||||
.stdout(build_utils::build_stdio())
|
.stdout(build_utils::build_stdio())
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![recursion_limit = "1024"]
|
||||||
/// This binary runs integration tests between Lighthouse and execution engines.
|
/// This binary runs integration tests between Lighthouse and execution engines.
|
||||||
///
|
///
|
||||||
/// 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.
|
||||||
@ -9,6 +10,7 @@ mod genesis_json;
|
|||||||
mod geth;
|
mod geth;
|
||||||
mod nethermind;
|
mod nethermind;
|
||||||
mod test_rig;
|
mod test_rig;
|
||||||
|
mod transactions;
|
||||||
|
|
||||||
use geth::GethEngine;
|
use geth::GethEngine;
|
||||||
use nethermind::NethermindEngine;
|
use nethermind::NethermindEngine;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use crate::build_utils;
|
use crate::build_utils;
|
||||||
use crate::execution_engine::GenericExecutionEngine;
|
use crate::execution_engine::GenericExecutionEngine;
|
||||||
|
use crate::genesis_json::nethermind_genesis_json;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Child, Command, Output};
|
use std::process::{Child, Command, Output};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
@ -69,33 +71,43 @@ impl NethermindEngine {
|
|||||||
|
|
||||||
impl GenericExecutionEngine for NethermindEngine {
|
impl GenericExecutionEngine for NethermindEngine {
|
||||||
fn init_datadir() -> TempDir {
|
fn init_datadir() -> TempDir {
|
||||||
TempDir::new().unwrap()
|
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(
|
fn start_client(
|
||||||
datadir: &TempDir,
|
datadir: &TempDir,
|
||||||
_http_port: u16,
|
http_port: u16,
|
||||||
http_auth_port: u16,
|
http_auth_port: u16,
|
||||||
jwt_secret_path: PathBuf,
|
jwt_secret_path: PathBuf,
|
||||||
) -> Child {
|
) -> Child {
|
||||||
let network_port = unused_tcp_port().unwrap();
|
let network_port = unused_tcp_port().unwrap();
|
||||||
|
let genesis_json_path = datadir.path().join("genesis.json");
|
||||||
|
|
||||||
Command::new(Self::binary_path())
|
Command::new(Self::binary_path())
|
||||||
.arg("--datadir")
|
.arg("--datadir")
|
||||||
.arg(datadir.path().to_str().unwrap())
|
.arg(datadir.path().to_str().unwrap())
|
||||||
.arg("--config")
|
.arg("--config")
|
||||||
.arg("kiln")
|
.arg("kiln")
|
||||||
|
.arg("--Init.ChainSpecPath")
|
||||||
|
.arg(genesis_json_path.to_str().unwrap())
|
||||||
.arg("--Merge.TerminalTotalDifficulty")
|
.arg("--Merge.TerminalTotalDifficulty")
|
||||||
.arg("0")
|
.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("--JsonRpc.AdditionalRpcUrls")
|
||||||
.arg(format!(
|
.arg(format!(
|
||||||
"http://localhost:{}|http;ws|net;eth;subscribe;engine;web3;client",
|
"http://localhost:{}|http;ws|net;eth;subscribe;engine;web3;client",
|
||||||
http_auth_port
|
http_auth_port
|
||||||
))
|
))
|
||||||
.arg("--JsonRpc.EnabledModules")
|
|
||||||
.arg("net,eth,subscribe,web3,admin,engine")
|
|
||||||
.arg("--JsonRpc.Port")
|
|
||||||
.arg(http_auth_port.to_string())
|
|
||||||
.arg("--Network.DiscoveryPort")
|
.arg("--Network.DiscoveryPort")
|
||||||
.arg(network_port.to_string())
|
.arg(network_port.to_string())
|
||||||
.arg("--Network.P2PPort")
|
.arg("--Network.P2PPort")
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
use crate::execution_engine::{ExecutionEngine, GenericExecutionEngine};
|
use crate::execution_engine::{
|
||||||
|
ExecutionEngine, GenericExecutionEngine, ACCOUNT1, ACCOUNT2, KEYSTORE_PASSWORD, PRIVATE_KEYS,
|
||||||
|
};
|
||||||
|
use crate::transactions::transactions;
|
||||||
|
use ethers_providers::Middleware;
|
||||||
use execution_layer::{ExecutionLayer, PayloadAttributes, PayloadStatus};
|
use execution_layer::{ExecutionLayer, PayloadAttributes, PayloadStatus};
|
||||||
|
use reqwest::{header::CONTENT_TYPE, Client};
|
||||||
|
use sensitive_url::SensitiveUrl;
|
||||||
|
use serde_json::{json, Value};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||||
use task_executor::TaskExecutor;
|
use task_executor::TaskExecutor;
|
||||||
@ -8,7 +15,6 @@ use types::{
|
|||||||
Address, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, FullPayload, Hash256,
|
Address, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, FullPayload, Hash256,
|
||||||
MainnetEthSpec, Slot, Uint256,
|
MainnetEthSpec, Slot, Uint256,
|
||||||
};
|
};
|
||||||
|
|
||||||
const EXECUTION_ENGINE_START_TIMEOUT: Duration = Duration::from_secs(20);
|
const EXECUTION_ENGINE_START_TIMEOUT: Duration = Duration::from_secs(20);
|
||||||
|
|
||||||
struct ExecutionPair<E, T: EthSpec> {
|
struct ExecutionPair<E, T: EthSpec> {
|
||||||
@ -32,6 +38,63 @@ pub struct TestRig<E, T: EthSpec = MainnetEthSpec> {
|
|||||||
_runtime_shutdown: exit_future::Signal,
|
_runtime_shutdown: exit_future::Signal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Import a private key into the execution engine and unlock it so that we can
|
||||||
|
/// make transactions with the corresponding account.
|
||||||
|
async fn import_and_unlock(http_url: SensitiveUrl, priv_keys: &[&str], password: &str) {
|
||||||
|
for priv_key in priv_keys {
|
||||||
|
let body = json!(
|
||||||
|
{
|
||||||
|
"jsonrpc":"2.0",
|
||||||
|
"method":"personal_importRawKey",
|
||||||
|
"params":[priv_key, password],
|
||||||
|
"id":1
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let client = Client::builder().build().unwrap();
|
||||||
|
let request = client
|
||||||
|
.post(http_url.full.clone())
|
||||||
|
.header(CONTENT_TYPE, "application/json")
|
||||||
|
.json(&body);
|
||||||
|
|
||||||
|
let response: Value = request
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.error_for_status()
|
||||||
|
.unwrap()
|
||||||
|
.json()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let account = response.get("result").unwrap().as_str().unwrap();
|
||||||
|
|
||||||
|
let body = json!(
|
||||||
|
{
|
||||||
|
"jsonrpc":"2.0",
|
||||||
|
"method":"personal_unlockAccount",
|
||||||
|
"params":[account, password],
|
||||||
|
"id":1
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let request = client
|
||||||
|
.post(http_url.full.clone())
|
||||||
|
.header(CONTENT_TYPE, "application/json")
|
||||||
|
.json(&body);
|
||||||
|
|
||||||
|
let _response: Value = request
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.error_for_status()
|
||||||
|
.unwrap()
|
||||||
|
.json()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: GenericExecutionEngine> TestRig<E> {
|
impl<E: GenericExecutionEngine> TestRig<E> {
|
||||||
pub fn new(generic_engine: E) -> Self {
|
pub fn new(generic_engine: E) -> Self {
|
||||||
let log = environment::null_logger().unwrap();
|
let log = environment::null_logger().unwrap();
|
||||||
@ -125,6 +188,20 @@ impl<E: GenericExecutionEngine> TestRig<E> {
|
|||||||
pub async fn perform_tests(&self) {
|
pub async fn perform_tests(&self) {
|
||||||
self.wait_until_synced().await;
|
self.wait_until_synced().await;
|
||||||
|
|
||||||
|
// Import and unlock all private keys to sign transactions
|
||||||
|
let _ = futures::future::join_all([&self.ee_a, &self.ee_b].iter().map(|ee| {
|
||||||
|
import_and_unlock(
|
||||||
|
ee.execution_engine.http_url(),
|
||||||
|
&PRIVATE_KEYS,
|
||||||
|
KEYSTORE_PASSWORD,
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// We hardcode the accounts here since some EEs start with a default unlocked account
|
||||||
|
let account1 = ethers_core::types::Address::from_slice(&hex::decode(&ACCOUNT1).unwrap());
|
||||||
|
let account2 = ethers_core::types::Address::from_slice(&hex::decode(&ACCOUNT2).unwrap());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the transition config endpoint.
|
* Check the transition config endpoint.
|
||||||
*/
|
*/
|
||||||
@ -157,6 +234,17 @@ impl<E: GenericExecutionEngine> TestRig<E> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Submit transactions before getting payload
|
||||||
|
let txs = transactions::<MainnetEthSpec>(account1, account2);
|
||||||
|
for tx in txs.clone().into_iter() {
|
||||||
|
self.ee_a
|
||||||
|
.execution_engine
|
||||||
|
.provider
|
||||||
|
.send_transaction(tx, None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execution Engine A:
|
* Execution Engine A:
|
||||||
*
|
*
|
||||||
@ -168,6 +256,45 @@ impl<E: GenericExecutionEngine> TestRig<E> {
|
|||||||
let prev_randao = Hash256::zero();
|
let prev_randao = Hash256::zero();
|
||||||
let finalized_block_hash = ExecutionBlockHash::zero();
|
let finalized_block_hash = ExecutionBlockHash::zero();
|
||||||
let proposer_index = 0;
|
let proposer_index = 0;
|
||||||
|
|
||||||
|
let prepared = self
|
||||||
|
.ee_a
|
||||||
|
.execution_layer
|
||||||
|
.insert_proposer(
|
||||||
|
Slot::new(1), // Insert proposer for the next slot
|
||||||
|
Hash256::zero(),
|
||||||
|
proposer_index,
|
||||||
|
PayloadAttributes {
|
||||||
|
timestamp,
|
||||||
|
prev_randao,
|
||||||
|
suggested_fee_recipient: Address::zero(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert!(!prepared, "Inserting proposer for the first time");
|
||||||
|
|
||||||
|
// Make a fcu call with the PayloadAttributes that we inserted previously
|
||||||
|
let prepare = self
|
||||||
|
.ee_a
|
||||||
|
.execution_layer
|
||||||
|
.notify_forkchoice_updated(
|
||||||
|
parent_hash,
|
||||||
|
finalized_block_hash,
|
||||||
|
Slot::new(0),
|
||||||
|
Hash256::zero(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(prepare, PayloadStatus::Valid);
|
||||||
|
|
||||||
|
// Add a delay to give the EE sufficient time to pack the
|
||||||
|
// submitted transactions into a payload.
|
||||||
|
// This is required when running on under resourced nodes and
|
||||||
|
// in CI.
|
||||||
|
sleep(Duration::from_secs(3)).await;
|
||||||
|
|
||||||
let valid_payload = self
|
let valid_payload = self
|
||||||
.ee_a
|
.ee_a
|
||||||
.execution_layer
|
.execution_layer
|
||||||
@ -184,6 +311,8 @@ impl<E: GenericExecutionEngine> TestRig<E> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.execution_payload;
|
.execution_payload;
|
||||||
|
|
||||||
|
assert_eq!(valid_payload.transactions.len(), txs.len());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execution Engine A:
|
* Execution Engine A:
|
||||||
*
|
*
|
||||||
|
87
testing/execution_engine_integration/src/transactions.rs
Normal file
87
testing/execution_engine_integration/src/transactions.rs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
use deposit_contract::{encode_eth1_tx_data, BYTECODE, CONTRACT_DEPLOY_GAS, DEPOSIT_GAS};
|
||||||
|
use ethers_core::types::{
|
||||||
|
transaction::{eip2718::TypedTransaction, eip2930::AccessList},
|
||||||
|
Address, Bytes, Eip1559TransactionRequest, TransactionRequest,
|
||||||
|
};
|
||||||
|
use types::{DepositData, EthSpec, Hash256, Keypair, Signature};
|
||||||
|
|
||||||
|
/// Hardcoded deposit contract address based on sender address and nonce
|
||||||
|
pub const DEPOSIT_CONTRACT_ADDRESS: &str = "64f43BEc7F86526686C931d65362bB8698872F90";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Transaction {
|
||||||
|
Transfer(Address, Address),
|
||||||
|
TransferLegacy(Address, Address),
|
||||||
|
TransferAccessList(Address, Address),
|
||||||
|
DeployDepositContract(Address),
|
||||||
|
DepositDepositContract {
|
||||||
|
sender: Address,
|
||||||
|
deposit_contract_address: Address,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list of transactions to publish to the execution layer.
|
||||||
|
pub fn transactions<E: EthSpec>(account1: Address, account2: Address) -> Vec<TypedTransaction> {
|
||||||
|
vec![
|
||||||
|
Transaction::Transfer(account1, account2).transaction::<E>(),
|
||||||
|
Transaction::TransferLegacy(account1, account2).transaction::<E>(),
|
||||||
|
Transaction::TransferAccessList(account1, account2).transaction::<E>(),
|
||||||
|
Transaction::DeployDepositContract(account1).transaction::<E>(),
|
||||||
|
Transaction::DepositDepositContract {
|
||||||
|
sender: account1,
|
||||||
|
deposit_contract_address: ethers_core::types::Address::from_slice(
|
||||||
|
&hex::decode(&DEPOSIT_CONTRACT_ADDRESS).unwrap(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
.transaction::<E>(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transaction {
|
||||||
|
pub fn transaction<E: EthSpec>(&self) -> TypedTransaction {
|
||||||
|
match &self {
|
||||||
|
Self::TransferLegacy(from, to) => TransactionRequest::new()
|
||||||
|
.from(*from)
|
||||||
|
.to(*to)
|
||||||
|
.value(1)
|
||||||
|
.into(),
|
||||||
|
Self::Transfer(from, to) => Eip1559TransactionRequest::new()
|
||||||
|
.from(*from)
|
||||||
|
.to(*to)
|
||||||
|
.value(1)
|
||||||
|
.into(),
|
||||||
|
Self::TransferAccessList(from, to) => TransactionRequest::new()
|
||||||
|
.from(*from)
|
||||||
|
.to(*to)
|
||||||
|
.value(1)
|
||||||
|
.with_access_list(AccessList::default())
|
||||||
|
.into(),
|
||||||
|
Self::DeployDepositContract(addr) => TransactionRequest::new()
|
||||||
|
.from(*addr)
|
||||||
|
.data(Bytes::from(BYTECODE.to_vec()))
|
||||||
|
.gas(CONTRACT_DEPLOY_GAS)
|
||||||
|
.into(),
|
||||||
|
Self::DepositDepositContract {
|
||||||
|
sender,
|
||||||
|
deposit_contract_address,
|
||||||
|
} => {
|
||||||
|
let keypair = Keypair::random();
|
||||||
|
|
||||||
|
let mut deposit = DepositData {
|
||||||
|
pubkey: keypair.pk.into(),
|
||||||
|
withdrawal_credentials: Hash256::zero(),
|
||||||
|
amount: 32_000_000_000,
|
||||||
|
signature: Signature::empty().into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
deposit.signature = deposit.create_signature(&keypair.sk, &E::default_spec());
|
||||||
|
TransactionRequest::new()
|
||||||
|
.from(*sender)
|
||||||
|
.to(*deposit_contract_address)
|
||||||
|
.data(Bytes::from(encode_eth1_tx_data(&deposit).unwrap()))
|
||||||
|
.gas(DEPOSIT_GAS)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user