Serve Bellatrix preset in BN API (#3425)

## Issue Addressed

Resolves #3388
Resolves #2638

## Proposed Changes

- Return the `BellatrixPreset` on `/eth/v1/config/spec` by default.
- Allow users to opt out of this by providing `--http-spec-fork=altair` (unless there's a Bellatrix fork epoch set).
- Add the Altair constants from #2638 and make serving the constants non-optional (the `http-disable-legacy-spec` flag is deprecated).
- Modify the VC to only read the `Config` and not to log extra fields. This prevents it from having to muck around parsing the `ConfigAndPreset` fields it doesn't need.

## Additional Info

This change is backwards-compatible for the VC and the BN, but is marked as a breaking change for the removal of `--http-disable-legacy-spec`.

I tried making `Config` a `superstruct` too, but getting the automatic decoding to work was a huge pain and was going to require a lot of hacks, so I gave up in favour of keeping the default-based approach we have now.
This commit is contained in:
Michael Sproul
2022-08-10 07:52:59 +00:00
parent c25934956b
commit 4e05f19fb5
19 changed files with 167 additions and 142 deletions

View File

@@ -7,7 +7,7 @@ use crate::http_metrics::metrics::{inc_counter_vec, ENDPOINT_ERRORS, ENDPOINT_RE
use environment::RuntimeContext;
use eth2::BeaconNodeHttpClient;
use futures::future;
use slog::{debug, error, info, warn, Logger};
use slog::{error, info, warn, Logger};
use slot_clock::SlotClock;
use std::fmt;
use std::fmt::Debug;
@@ -16,7 +16,7 @@ use std::marker::PhantomData;
use std::sync::Arc;
use std::time::Duration;
use tokio::{sync::RwLock, time::sleep};
use types::{ChainSpec, EthSpec};
use types::{ChainSpec, Config, EthSpec};
/// The number of seconds *prior* to slot start that we will try and update the state of fallback
/// nodes.
@@ -213,9 +213,9 @@ impl<E: EthSpec> CandidateBeaconNode<E> {
/// Checks if the node has the correct specification.
async fn is_compatible(&self, spec: &ChainSpec, log: &Logger) -> Result<(), CandidateError> {
let config_and_preset = self
let config = self
.beacon_node
.get_config_spec()
.get_config_spec::<Config>()
.await
.map_err(|e| {
error!(
@@ -228,25 +228,15 @@ impl<E: EthSpec> CandidateBeaconNode<E> {
})?
.data;
let beacon_node_spec =
ChainSpec::from_config::<E>(&config_and_preset.config).ok_or_else(|| {
error!(
log,
"The minimal/mainnet spec type of the beacon node does not match the validator \
client. See the --network command.";
"endpoint" => %self.beacon_node,
);
CandidateError::Incompatible
})?;
if !config_and_preset.extra_fields.is_empty() {
debug!(
let beacon_node_spec = ChainSpec::from_config::<E>(&config).ok_or_else(|| {
error!(
log,
"Beacon spec includes unknown fields";
"The minimal/mainnet spec type of the beacon node does not match the validator \
client. See the --network command.";
"endpoint" => %self.beacon_node,
"fields" => ?config_and_preset.extra_fields,
);
}
CandidateError::Incompatible
})?;
if beacon_node_spec.genesis_fork_version != spec.genesis_fork_version {
error!(