Unify execution layer endpoints (#3214)

## Issue Addressed

Resolves #3069 

## Proposed Changes

Unify the `eth1-endpoints` and `execution-endpoints` flags in a backwards compatible way as described in https://github.com/sigp/lighthouse/issues/3069#issuecomment-1134219221

Users have 2 options:
1. Use multiple non auth execution endpoints for deposit processing pre-merge
2. Use a single jwt authenticated execution endpoint for both execution layer and deposit processing post merge

Related https://github.com/sigp/lighthouse/issues/3118

To enable jwt authenticated deposit processing, this PR removes the calls to `net_version` as the `net` namespace is not exposed in the auth server in execution clients. 
Moving away from using `networkId` is a good step in my opinion as it doesn't provide us with any added guarantees over `chainId`. See https://github.com/ethereum/consensus-specs/issues/2163 and https://github.com/sigp/lighthouse/issues/2115


Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
Pawan Dhananjay
2022-06-29 09:07:09 +00:00
parent 53b2b500db
commit 5de00b7ee8
31 changed files with 1113 additions and 992 deletions

View File

@@ -1,6 +1,7 @@
use beacon_node::ClientConfig as Config;
use crate::exec::{CommandLineTestExec, CompletedTest};
use eth1::Eth1Endpoint;
use lighthouse_network::PeerId;
use std::fs::File;
use std::io::Write;
@@ -66,7 +67,10 @@ fn staking_flag() {
.with_config(|config| {
assert!(config.http_api.enabled);
assert!(config.sync_eth1_chain);
assert_eq!(config.eth1.endpoints[0].to_string(), DEFAULT_ETH1_ENDPOINT);
assert_eq!(
config.eth1.endpoints.get_endpoints()[0].to_string(),
DEFAULT_ETH1_ENDPOINT
);
});
}
@@ -196,18 +200,21 @@ fn eth1_endpoints_flag() {
.run_with_zero_port()
.with_config(|config| {
assert_eq!(
config.eth1.endpoints[0].full.to_string(),
config.eth1.endpoints.get_endpoints()[0].full.to_string(),
"http://localhost:9545/"
);
assert_eq!(
config.eth1.endpoints[0].to_string(),
config.eth1.endpoints.get_endpoints()[0].to_string(),
"http://localhost:9545/"
);
assert_eq!(
config.eth1.endpoints[1].full.to_string(),
config.eth1.endpoints.get_endpoints()[1].full.to_string(),
"https://infura.io/secret"
);
assert_eq!(config.eth1.endpoints[1].to_string(), "https://infura.io/");
assert_eq!(
config.eth1.endpoints.get_endpoints()[1].to_string(),
"https://infura.io/"
);
assert!(config.sync_eth1_chain);
});
}
@@ -246,45 +253,107 @@ fn eth1_cache_follow_distance_manual() {
}
// Tests for Bellatrix flags.
#[test]
fn merge_flag() {
CommandLineTest::new()
.flag("merge", None)
.run_with_zero_port()
.with_config(|config| assert!(config.execution_layer.is_some()));
}
#[test]
fn merge_execution_endpoints_flag() {
fn run_merge_execution_endpoints_flag_test(flag: &str) {
use sensitive_url::SensitiveUrl;
let urls = vec!["http://sigp.io/no-way:1337", "http://infura.not_real:4242"];
let endpoints = urls
.iter()
.map(|s| SensitiveUrl::parse(s).unwrap())
.collect::<Vec<_>>();
// we don't support redundancy for execution-endpoints
// only the first provided endpoint is parsed.
let mut endpoint_arg = urls[0].to_string();
for url in urls.into_iter().skip(1) {
for url in urls.iter().skip(1) {
endpoint_arg.push(',');
endpoint_arg.push_str(url);
}
let (_dirs, jwts): (Vec<_>, Vec<_>) = (0..2)
.map(|i| {
let dir = TempDir::new().expect("Unable to create temporary directory");
let path = dir.path().join(format!("jwt-{}", i));
(dir, path)
})
.unzip();
let mut jwts_arg = jwts[0].as_os_str().to_str().unwrap().to_string();
for jwt in jwts.iter().skip(1) {
jwts_arg.push(',');
jwts_arg.push_str(jwt.as_os_str().to_str().unwrap());
}
// this is way better but intersperse is still a nightly feature :/
// let endpoint_arg: String = urls.into_iter().intersperse(",").collect();
CommandLineTest::new()
.flag("merge", None)
.flag("execution-endpoints", Some(&endpoint_arg))
.flag(flag, Some(&endpoint_arg))
.flag("execution-jwt", Some(&jwts_arg))
.run_with_zero_port()
.with_config(|config| {
let config = config.execution_layer.as_ref().unwrap();
assert_eq!(config.execution_endpoints, endpoints)
assert_eq!(config.execution_endpoints.len(), 1);
assert_eq!(
config.execution_endpoints[0],
SensitiveUrl::parse(&urls[0]).unwrap()
);
// Only the first secret file should be used.
assert_eq!(config.secret_files, vec![jwts[0].clone()]);
});
}
#[test]
fn merge_execution_endpoints_flag() {
run_merge_execution_endpoints_flag_test("execution-endpoints")
}
#[test]
fn merge_execution_endpoint_flag() {
run_merge_execution_endpoints_flag_test("execution-endpoint")
}
fn run_execution_endpoints_overrides_eth1_endpoints_test(eth1_flag: &str, execution_flag: &str) {
use sensitive_url::SensitiveUrl;
let eth1_endpoint = "http://bad.bad";
let execution_endpoint = "http://good.good";
assert!(eth1_endpoint != execution_endpoint);
let dir = TempDir::new().expect("Unable to create temporary directory");
let jwt_path = dir.path().join("jwt-file");
CommandLineTest::new()
.flag(eth1_flag, Some(&eth1_endpoint))
.flag(execution_flag, Some(&execution_endpoint))
.flag("execution-jwt", jwt_path.as_os_str().to_str())
.run_with_zero_port()
.with_config(|config| {
assert_eq!(
config.execution_layer.as_ref().unwrap().execution_endpoints,
vec![SensitiveUrl::parse(execution_endpoint).unwrap()]
);
// The eth1 endpoint should have been set to the --execution-endpoint value in defiance
// of --eth1-endpoints.
assert_eq!(
config.eth1.endpoints,
Eth1Endpoint::Auth {
endpoint: SensitiveUrl::parse(execution_endpoint).unwrap(),
jwt_path: jwt_path.clone(),
jwt_id: None,
jwt_version: None,
}
);
});
}
#[test]
fn execution_endpoints_overrides_eth1_endpoints() {
run_execution_endpoints_overrides_eth1_endpoints_test("eth1-endpoints", "execution-endpoints");
}
#[test]
fn execution_endpoint_overrides_eth1_endpoint() {
run_execution_endpoints_overrides_eth1_endpoints_test("eth1-endpoint", "execution-endpoint");
}
#[test]
fn merge_jwt_secrets_flag() {
let dir = TempDir::new().expect("Unable to create temporary directory");
let mut file = File::create(dir.path().join("jwtsecrets")).expect("Unable to create file");
file.write_all(b"0x3cbc11b0d8fa16f3344eacfd6ff6430b9d30734450e8adcf5400f88d327dcb33")
.expect("Unable to write to file");
CommandLineTest::new()
.flag("merge", None)
.flag("execution-endpoints", Some("http://localhost:8551/"))
.flag(
"jwt-secrets",
@@ -302,8 +371,13 @@ fn merge_jwt_secrets_flag() {
}
#[test]
fn merge_fee_recipient_flag() {
let dir = TempDir::new().expect("Unable to create temporary directory");
CommandLineTest::new()
.flag("merge", None)
.flag("execution-endpoint", Some("http://meow.cats"))
.flag(
"execution-jwt",
dir.path().join("jwt-file").as_os_str().to_str(),
)
.flag(
"suggested-fee-recipient",
Some("0x00000000219ab540356cbb839cbe05303d7705fa"),
@@ -317,19 +391,74 @@ fn merge_fee_recipient_flag() {
);
});
}
#[test]
fn jwt_optional_flags() {
fn run_payload_builder_flag_test(flag: &str, builders: &str) {
use sensitive_url::SensitiveUrl;
let dir = TempDir::new().expect("Unable to create temporary directory");
let all_builders: Vec<_> = builders
.split(",")
.map(|builder| SensitiveUrl::parse(builder).expect("valid builder url"))
.collect();
CommandLineTest::new()
.flag("merge", None)
.flag("jwt-id", Some("bn-1"))
.flag("jwt-version", Some("Lighthouse-v2.1.3"))
.flag("execution-endpoint", Some("http://meow.cats"))
.flag(
"execution-jwt",
dir.path().join("jwt-file").as_os_str().to_str(),
)
.flag(flag, Some(builders))
.run_with_zero_port()
.with_config(|config| {
let config = config.execution_layer.as_ref().unwrap();
assert_eq!(config.jwt_id, Some("bn-1".to_string()));
assert_eq!(config.jwt_version, Some("Lighthouse-v2.1.3".to_string()));
// Only first provided endpoint is parsed as we don't support
// redundancy.
assert_eq!(&config.builder_endpoints, &all_builders[..1]);
});
}
#[test]
fn payload_builder_flags() {
run_payload_builder_flag_test("payload-builder", "http://meow.cats");
run_payload_builder_flag_test("payload-builders", "http://meow.cats,http://woof.dogs");
run_payload_builder_flag_test("payload-builders", "http://meow.cats,http://woof.dogs");
}
fn run_jwt_optional_flags_test(jwt_flag: &str, jwt_id_flag: &str, jwt_version_flag: &str) {
use sensitive_url::SensitiveUrl;
let dir = TempDir::new().expect("Unable to create temporary directory");
let execution_endpoint = "http://meow.cats";
let jwt_file = "jwt-file";
let id = "bn-1";
let version = "Lighthouse-v2.1.3";
CommandLineTest::new()
.flag("execution-endpoint", Some(execution_endpoint.clone()))
.flag(jwt_flag, dir.path().join(jwt_file).as_os_str().to_str())
.flag(jwt_id_flag, Some(id))
.flag(jwt_version_flag, Some(version))
.run_with_zero_port()
.with_config(|config| {
let el_config = config.execution_layer.as_ref().unwrap();
assert_eq!(el_config.jwt_id, Some(id.to_string()));
assert_eq!(el_config.jwt_version, Some(version.to_string()));
assert_eq!(
config.eth1.endpoints,
Eth1Endpoint::Auth {
endpoint: SensitiveUrl::parse(execution_endpoint).unwrap(),
jwt_path: dir.path().join(jwt_file),
jwt_id: Some(id.to_string()),
jwt_version: Some(version.to_string()),
}
);
});
}
#[test]
fn jwt_optional_flags() {
run_jwt_optional_flags_test("execution-jwt", "execution-jwt-id", "execution-jwt-version");
}
#[test]
fn jwt_optional_alias_flags() {
run_jwt_optional_flags_test("jwt-secrets", "jwt-id", "jwt-version");
}
#[test]
fn terminal_total_difficulty_override_flag() {
use beacon_node::beacon_chain::types::Uint256;