Fallback nodes for eth1 access (#1918)

## Issue Addressed

part of  #1883

## Proposed Changes

Adds a new cli argument `--eth1-endpoints` that can be used instead of `--eth1-endpoint` to specify a comma-separated list of endpoints. If the first endpoint returns an error for some request the other endpoints are tried in the given order.

## Additional Info

Currently if the first endpoint fails the fallbacks are used silently (except for `try_fallback_test_endpoint` that is used in `do_update` which logs a `WARN` for each endpoint that is not reachable). A question is if we should add more logs so that the user gets warned if his main endpoint is for example just slow and sometimes hits timeouts.
This commit is contained in:
blacktemplar
2020-11-27 08:37:44 +00:00
parent 1312844f29
commit 38b15deccb
20 changed files with 930 additions and 225 deletions

View File

@@ -284,7 +284,18 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
Arg::with_name("eth1-endpoint")
.long("eth1-endpoint")
.value_name("HTTP-ENDPOINT")
.help("Specifies the server for a web3 connection to the Eth1 chain. Also enables the --eth1 flag. Defaults to http://127.0.0.1:8545.")
.help("Deprecated. Use --eth1-endpoints.")
.takes_value(true)
)
.arg(
Arg::with_name("eth1-endpoints")
.long("eth1-endpoints")
.value_name("HTTP-ENDPOINTS")
.conflicts_with("eth1-endpoint")
.help("One or more comma-delimited server endpoints for web3 connection. \
If multiple endpoints are given the endpoints are used as fallback in the \
given order. Also enables the --eth1 flag. \
Defaults to http://127.0.0.1:8545.")
.takes_value(true)
)
.arg(

View File

@@ -7,6 +7,7 @@ use eth2_libp2p::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSeri
use eth2_testnet_config::Eth2TestnetConfig;
use slog::{info, warn, Logger};
use std::cmp;
use std::cmp::max;
use std::fs;
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
use std::net::{TcpListener, UdpSocket};
@@ -194,7 +195,10 @@ pub fn get_config<E: EthSpec>(
// Defines the URL to reach the eth1 node.
if let Some(val) = cli_args.value_of("eth1-endpoint") {
client_config.sync_eth1_chain = true;
client_config.eth1.endpoint = val.to_string();
client_config.eth1.endpoints = vec![val.to_string()];
} else if let Some(val) = cli_args.value_of("eth1-endpoints") {
client_config.sync_eth1_chain = true;
client_config.eth1.endpoints = val.split(',').map(String::from).collect();
}
if let Some(val) = cli_args.value_of("eth1-blocks-per-log-query") {
@@ -264,6 +268,8 @@ pub fn get_config<E: EthSpec>(
client_config.eth1.lowest_cached_block_number =
client_config.eth1.deposit_contract_deploy_block;
client_config.eth1.follow_distance = spec.eth1_follow_distance;
client_config.eth1.node_far_behind_seconds =
max(5, spec.eth1_follow_distance / 2) * spec.seconds_per_eth1_block;
client_config.eth1.network_id = spec.deposit_network_id.into();
client_config.eth1.chain_id = spec.deposit_chain_id.into();
client_config.eth1.set_block_cache_truncation::<E>(spec);

View File

@@ -101,7 +101,7 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
info!(
log,
"Block production enabled";
"endpoint" => &client_config.eth1.endpoint,
"endpoints" => format!("{:?}", &client_config.eth1.endpoints),
"method" => "json rpc via http"
);
builder