Deprecate exchangeTransitionConfiguration functionality (#4517)

## Issue Addressed

Solves #4442 
## Proposed Changes

EL clients log errors if we don't query this endpoint, but they are making releases that remove this error logging. After those are out we can stop calling it, after which point EL teams will remove the endpoint entirely. 
Refer https://hackmd.io/@n0ble/deprecate-exchgTC
This commit is contained in:
Gua00va 2023-07-31 23:51:39 +00:00
parent cb275e746d
commit 73764d0dd2
9 changed files with 3 additions and 149 deletions

View File

@ -86,9 +86,6 @@ pub enum MergeReadiness {
#[serde(serialize_with = "serialize_uint256")] #[serde(serialize_with = "serialize_uint256")]
current_difficulty: Option<Uint256>, current_difficulty: Option<Uint256>,
}, },
/// The transition configuration with the EL failed, there might be a problem with
/// connectivity, authentication or a difference in configuration.
ExchangeTransitionConfigurationFailed { error: String },
/// The EL can be reached and has the correct configuration, however it's not yet synced. /// The EL can be reached and has the correct configuration, however it's not yet synced.
NotSynced, NotSynced,
/// The user has not configured this node to use an execution endpoint. /// The user has not configured this node to use an execution endpoint.
@ -109,12 +106,6 @@ impl fmt::Display for MergeReadiness {
params, current_difficulty params, current_difficulty
) )
} }
MergeReadiness::ExchangeTransitionConfigurationFailed { error } => write!(
f,
"Could not confirm the transition configuration with the \
execution endpoint: {:?}",
error
),
MergeReadiness::NotSynced => write!( MergeReadiness::NotSynced => write!(
f, f,
"The execution endpoint is connected and configured, \ "The execution endpoint is connected and configured, \
@ -155,14 +146,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// Attempts to connect to the EL and confirm that it is ready for the merge. /// Attempts to connect to the EL and confirm that it is ready for the merge.
pub async fn check_merge_readiness(&self) -> MergeReadiness { pub async fn check_merge_readiness(&self) -> MergeReadiness {
if let Some(el) = self.execution_layer.as_ref() { if let Some(el) = self.execution_layer.as_ref() {
if let Err(e) = el.exchange_transition_configuration(&self.spec).await {
// The EL was either unreachable, responded with an error or has a different
// configuration.
return MergeReadiness::ExchangeTransitionConfigurationFailed {
error: format!("{:?}", e),
};
}
if !el.is_synced_for_notifier().await { if !el.is_synced_for_notifier().await {
// The EL is not synced. // The EL is not synced.
return MergeReadiness::NotSynced; return MergeReadiness::NotSynced;

View File

@ -850,9 +850,6 @@ where
execution_layer.spawn_clean_proposer_caches_routine::<TSlotClock>( execution_layer.spawn_clean_proposer_caches_routine::<TSlotClock>(
beacon_chain.slot_clock.clone(), beacon_chain.slot_clock.clone(),
); );
// Spawns a routine that polls the `exchange_transition_configuration` endpoint.
execution_layer.spawn_transition_configuration_poll(beacon_chain.spec.clone());
} }
// Spawn a service to publish BLS to execution changes at the Capella fork. // Spawn a service to publish BLS to execution changes at the Capella fork.

View File

@ -404,14 +404,6 @@ async fn merge_readiness_logging<T: BeaconChainTypes>(
"config" => ?other "config" => ?other
), ),
}, },
readiness @ MergeReadiness::ExchangeTransitionConfigurationFailed { error: _ } => {
error!(
log,
"Not ready for merge";
"info" => %readiness,
"hint" => "try updating Lighthouse and/or the execution layer",
)
}
readiness @ MergeReadiness::NotSynced => warn!( readiness @ MergeReadiness::NotSynced => warn!(
log, log,
"Not ready for merge"; "Not ready for merge";

View File

@ -1,9 +1,8 @@
use crate::engines::ForkchoiceState; use crate::engines::ForkchoiceState;
use crate::http::{ use crate::http::{
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1, ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2,
ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2,
ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2,
}; };
use eth2::types::{SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2}; use eth2::types::{SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2};
pub use ethers_core::types::Transaction; pub use ethers_core::types::Transaction;
@ -450,7 +449,6 @@ pub struct EngineCapabilities {
pub get_payload_bodies_by_range_v1: bool, pub get_payload_bodies_by_range_v1: bool,
pub get_payload_v1: bool, pub get_payload_v1: bool,
pub get_payload_v2: bool, pub get_payload_v2: bool,
pub exchange_transition_configuration_v1: bool,
} }
impl EngineCapabilities { impl EngineCapabilities {
@ -480,9 +478,6 @@ impl EngineCapabilities {
if self.get_payload_v2 { if self.get_payload_v2 {
response.push(ENGINE_GET_PAYLOAD_V2); response.push(ENGINE_GET_PAYLOAD_V2);
} }
if self.exchange_transition_configuration_v1 {
response.push(ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1);
}
response response
} }

View File

@ -46,10 +46,6 @@ pub const ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1: &str = "engine_getPayloadBodiesB
pub const ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1: &str = "engine_getPayloadBodiesByRangeV1"; pub const ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1: &str = "engine_getPayloadBodiesByRangeV1";
pub const ENGINE_GET_PAYLOAD_BODIES_TIMEOUT: Duration = Duration::from_secs(10); pub const ENGINE_GET_PAYLOAD_BODIES_TIMEOUT: Duration = Duration::from_secs(10);
pub const ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1: &str =
"engine_exchangeTransitionConfigurationV1";
pub const ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1_TIMEOUT: Duration = Duration::from_secs(1);
pub const ENGINE_EXCHANGE_CAPABILITIES: &str = "engine_exchangeCapabilities"; pub const ENGINE_EXCHANGE_CAPABILITIES: &str = "engine_exchangeCapabilities";
pub const ENGINE_EXCHANGE_CAPABILITIES_TIMEOUT: Duration = Duration::from_secs(1); pub const ENGINE_EXCHANGE_CAPABILITIES_TIMEOUT: Duration = Duration::from_secs(1);
@ -68,7 +64,6 @@ pub static LIGHTHOUSE_CAPABILITIES: &[&str] = &[
ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V2,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1,
]; ];
/// This is necessary because a user might run a capella-enabled version of /// This is necessary because a user might run a capella-enabled version of
@ -83,7 +78,6 @@ pub static PRE_CAPELLA_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilit
get_payload_bodies_by_range_v1: false, get_payload_bodies_by_range_v1: false,
get_payload_v1: true, get_payload_v1: true,
get_payload_v2: false, get_payload_v2: false,
exchange_transition_configuration_v1: true,
}; };
/// Contains methods to convert arbitrary bytes to an ETH2 deposit contract object. /// Contains methods to convert arbitrary bytes to an ETH2 deposit contract object.
@ -934,24 +928,6 @@ impl HttpJsonRpc {
.collect()) .collect())
} }
pub async fn exchange_transition_configuration_v1(
&self,
transition_configuration: TransitionConfigurationV1,
) -> Result<TransitionConfigurationV1, Error> {
let params = json!([transition_configuration]);
let response = self
.rpc_request(
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1,
params,
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1_TIMEOUT
* self.execution_timeout_multiplier,
)
.await?;
Ok(response)
}
pub async fn exchange_capabilities(&self) -> Result<EngineCapabilities, Error> { pub async fn exchange_capabilities(&self) -> Result<EngineCapabilities, Error> {
let params = json!([LIGHTHOUSE_CAPABILITIES]); let params = json!([LIGHTHOUSE_CAPABILITIES]);
@ -982,8 +958,6 @@ impl HttpJsonRpc {
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1), .contains(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1),
get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1), get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1),
get_payload_v2: capabilities.contains(ENGINE_GET_PAYLOAD_V2), get_payload_v2: capabilities.contains(ENGINE_GET_PAYLOAD_V2),
exchange_transition_configuration_v1: capabilities
.contains(ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1),
}), }),
} }
} }

View File

@ -74,8 +74,6 @@ const EXECUTION_BLOCKS_LRU_CACHE_SIZE: usize = 128;
const DEFAULT_SUGGESTED_FEE_RECIPIENT: [u8; 20] = const DEFAULT_SUGGESTED_FEE_RECIPIENT: [u8; 20] =
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
const CONFIG_POLL_INTERVAL: Duration = Duration::from_secs(60);
/// A payload alongside some information about where it came from. /// A payload alongside some information about where it came from.
pub enum ProvenancedPayload<P> { pub enum ProvenancedPayload<P> {
/// A good ol' fashioned farm-to-table payload from your local EE. /// A good ol' fashioned farm-to-table payload from your local EE.
@ -502,24 +500,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
self.spawn(preparation_cleaner, "exec_preparation_cleanup"); self.spawn(preparation_cleaner, "exec_preparation_cleanup");
} }
/// Spawns a routine that polls the `exchange_transition_configuration` endpoint.
pub fn spawn_transition_configuration_poll(&self, spec: ChainSpec) {
let routine = |el: ExecutionLayer<T>| async move {
loop {
if let Err(e) = el.exchange_transition_configuration(&spec).await {
error!(
el.log(),
"Failed to check transition config";
"error" => ?e
);
}
sleep(CONFIG_POLL_INTERVAL).await;
}
};
self.spawn(routine, "exec_config_poll");
}
/// Returns `true` if the execution engine is synced and reachable. /// Returns `true` if the execution engine is synced and reachable.
pub async fn is_synced(&self) -> bool { pub async fn is_synced(&self) -> bool {
self.engine().is_synced().await self.engine().is_synced().await
@ -1318,53 +1298,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
.map_err(Error::EngineError) .map_err(Error::EngineError)
} }
pub async fn exchange_transition_configuration(&self, spec: &ChainSpec) -> Result<(), Error> {
let local = TransitionConfigurationV1 {
terminal_total_difficulty: spec.terminal_total_difficulty,
terminal_block_hash: spec.terminal_block_hash,
terminal_block_number: 0,
};
let result = self
.engine()
.request(|engine| engine.api.exchange_transition_configuration_v1(local))
.await;
match result {
Ok(remote) => {
if local.terminal_total_difficulty != remote.terminal_total_difficulty
|| local.terminal_block_hash != remote.terminal_block_hash
{
error!(
self.log(),
"Execution client config mismatch";
"msg" => "ensure lighthouse and the execution client are up-to-date and \
configured consistently",
"remote" => ?remote,
"local" => ?local,
);
Err(Error::EngineError(Box::new(EngineError::Api {
error: ApiError::TransitionConfigurationMismatch,
})))
} else {
debug!(
self.log(),
"Execution client config is OK";
);
Ok(())
}
}
Err(e) => {
error!(
self.log(),
"Unable to get transition config";
"error" => ?e,
);
Err(Error::EngineError(Box::new(e)))
}
}
}
/// Returns the execution engine capabilities resulting from a call to /// Returns the execution engine capabilities resulting from a call to
/// engine_exchangeCapabilities. If the capabilities cache is not populated, /// engine_exchangeCapabilities. If the capabilities cache is not populated,
/// or if it is populated with a cached result of age >= `age_limit`, this /// or if it is populated with a cached result of age >= `age_limit`, this

View File

@ -357,15 +357,6 @@ pub async fn handle_rpc<T: EthSpec>(
Ok(serde_json::to_value(response).unwrap()) Ok(serde_json::to_value(response).unwrap())
} }
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1 => {
let block_generator = ctx.execution_block_generator.read();
let transition_config: TransitionConfigurationV1 = TransitionConfigurationV1 {
terminal_total_difficulty: block_generator.terminal_total_difficulty,
terminal_block_hash: block_generator.terminal_block_hash,
terminal_block_number: block_generator.terminal_block_number,
};
Ok(serde_json::to_value(transition_config).unwrap())
}
ENGINE_EXCHANGE_CAPABILITIES => { ENGINE_EXCHANGE_CAPABILITIES => {
let engine_capabilities = ctx.engine_capabilities.read(); let engine_capabilities = ctx.engine_capabilities.read();
Ok(serde_json::to_value(engine_capabilities.to_response()).unwrap()) Ok(serde_json::to_value(engine_capabilities.to_response()).unwrap())

View File

@ -43,7 +43,6 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities {
get_payload_bodies_by_range_v1: true, get_payload_bodies_by_range_v1: true,
get_payload_v1: true, get_payload_v1: true,
get_payload_v2: true, get_payload_v2: true,
exchange_transition_configuration_v1: true,
}; };
mod execution_block_generator; mod execution_block_generator;

View File

@ -204,16 +204,6 @@ impl<E: GenericExecutionEngine> TestRig<E> {
let account1 = ethers_core::types::Address::from_slice(&hex::decode(ACCOUNT1).unwrap()); let account1 = ethers_core::types::Address::from_slice(&hex::decode(ACCOUNT1).unwrap());
let account2 = ethers_core::types::Address::from_slice(&hex::decode(ACCOUNT2).unwrap()); let account2 = ethers_core::types::Address::from_slice(&hex::decode(ACCOUNT2).unwrap());
/*
* Check the transition config endpoint.
*/
for ee in [&self.ee_a, &self.ee_b] {
ee.execution_layer
.exchange_transition_configuration(&self.spec)
.await
.unwrap();
}
/* /*
* Read the terminal block hash from both pairs, check it's equal. * Read the terminal block hash from both pairs, check it's equal.
*/ */