get rid of EL endpoint switching at forks

This commit is contained in:
realbigsean 2023-01-13 10:51:45 -05:00
parent d96d793bfb
commit e9affafb6b
No known key found for this signature in database
GPG Key ID: B372B64D866BF8CC
5 changed files with 45 additions and 58 deletions

View File

@ -953,10 +953,13 @@ impl HttpJsonRpc {
&self,
execution_payload: ExecutionPayload<T>,
) -> Result<PayloadStatusV1, Error> {
match execution_payload {
ExecutionPayload::Eip4844(_) => self.new_payload_v3(execution_payload).await,
ExecutionPayload::Capella(_) => self.new_payload_v2(execution_payload).await,
ExecutionPayload::Merge(_) => self.new_payload_v1(execution_payload).await,
let supported_apis = self.get_cached_supported_apis().await?;
if supported_apis.new_payload_v2 {
self.new_payload_v2(execution_payload).await
} else if supported_apis.new_payload_v1 {
self.new_payload_v1(execution_payload).await
} else {
Err(Error::RequiredMethodUnsupported("engine_newPayload"))
}
}
@ -967,11 +970,13 @@ impl HttpJsonRpc {
fork_name: ForkName,
payload_id: PayloadId,
) -> Result<ExecutionPayload<T>, Error> {
match fork_name {
ForkName::Eip4844 => self.get_payload_v3(fork_name, payload_id).await,
ForkName::Capella => self.get_payload_v2(fork_name, payload_id).await,
ForkName::Merge => self.get_payload_v1(fork_name, payload_id).await,
_ => Err(Error::RequiredMethodUnsupported("engine_getPayload")),
let supported_apis = self.get_cached_supported_apis().await?;
if supported_apis.get_payload_v2 {
self.get_payload_v2(fork_name, payload_id).await
} else if supported_apis.new_payload_v1 {
self.get_payload_v1(fork_name, payload_id).await
} else {
Err(Error::RequiredMethodUnsupported("engine_getPayload"))
}
}
@ -979,25 +984,23 @@ impl HttpJsonRpc {
// forkchoice_updated that the execution engine supports
pub async fn forkchoice_updated(
&self,
fork_name: ForkName,
forkchoice_state: ForkchoiceState,
payload_attributes: Option<PayloadAttributes>,
) -> Result<ForkchoiceUpdatedResponse, Error> {
match fork_name {
ForkName::Capella | ForkName::Eip4844 => {
self.forkchoice_updated_v2(forkchoice_state, payload_attributes)
.await
}
ForkName::Merge => {
self.forkchoice_updated_v1(
forkchoice_state,
payload_attributes
.map(|pa| pa.downgrade_to_v1())
.transpose()?,
)
let supported_apis = self.get_cached_supported_apis().await?;
if supported_apis.forkchoice_updated_v2 {
self.forkchoice_updated_v2(forkchoice_state, payload_attributes)
.await
}
_ => Err(Error::RequiredMethodUnsupported("engine_forkchoiceUpdated")),
} else if supported_apis.forkchoice_updated_v1 {
self.forkchoice_updated_v1(
forkchoice_state,
payload_attributes
.map(|pa| pa.downgrade_to_v1())
.transpose()?,
)
.await
} else {
Err(Error::RequiredMethodUnsupported("engine_forkchoiceUpdated"))
}
}
}

View File

@ -11,7 +11,7 @@ use std::sync::Arc;
use task_executor::TaskExecutor;
use tokio::sync::{watch, Mutex, RwLock};
use tokio_stream::wrappers::WatchStream;
use types::{ExecutionBlockHash, ForkName};
use types::ExecutionBlockHash;
/// The number of payload IDs that will be stored for each `Engine`.
///
@ -114,7 +114,7 @@ pub struct Engine {
pub api: HttpJsonRpc,
payload_id_cache: Mutex<LruCache<PayloadIdCacheKey, PayloadId>>,
state: RwLock<State>,
latest_forkchoice_state: RwLock<Option<(ForkName, ForkchoiceState)>>,
latest_forkchoice_state: RwLock<Option<ForkchoiceState>>,
executor: TaskExecutor,
log: Logger,
}
@ -153,15 +153,13 @@ impl Engine {
pub async fn notify_forkchoice_updated(
&self,
fork_name: ForkName,
forkchoice_state: ForkchoiceState,
payload_attributes: Option<PayloadAttributes>,
log: &Logger,
) -> Result<ForkchoiceUpdatedResponse, EngineApiError> {
info!(log, "Notifying FCU"; "fork_name" => ?fork_name);
let response = self
.api
.forkchoice_updated(fork_name, forkchoice_state, payload_attributes.clone())
.forkchoice_updated(forkchoice_state, payload_attributes.clone())
.await?;
if let Some(payload_id) = response.payload_id {
@ -181,18 +179,18 @@ impl Engine {
Ok(response)
}
async fn get_latest_forkchoice_state(&self) -> Option<(ForkName, ForkchoiceState)> {
async fn get_latest_forkchoice_state(&self) -> Option<ForkchoiceState> {
*self.latest_forkchoice_state.read().await
}
pub async fn set_latest_forkchoice_state(&self, fork_name: ForkName, state: ForkchoiceState) {
*self.latest_forkchoice_state.write().await = Some((fork_name, state));
pub async fn set_latest_forkchoice_state(&self, state: ForkchoiceState) {
*self.latest_forkchoice_state.write().await = Some(state);
}
async fn send_latest_forkchoice_state(&self) {
let latest_forkchoice_state = self.get_latest_forkchoice_state().await;
if let Some((fork_name, forkchoice_state)) = latest_forkchoice_state {
if let Some(forkchoice_state) = latest_forkchoice_state {
if forkchoice_state.head_block_hash == ExecutionBlockHash::zero() {
debug!(
self.log,
@ -206,16 +204,11 @@ impl Engine {
self.log,
"Issuing forkchoiceUpdated";
"forkchoice_state" => ?forkchoice_state,
"fork_name" => ?fork_name,
);
// For simplicity, payload attributes are never included in this call. It may be
// reasonable to include them in the future.
if let Err(e) = self
.api
.forkchoice_updated(fork_name, forkchoice_state, None)
.await
{
if let Err(e) = self.api.forkchoice_updated(forkchoice_state, None).await {
debug!(
self.log,
"Failed to issue latest head to engine";

View File

@ -228,7 +228,6 @@ struct Inner<E: EthSpec> {
executor: TaskExecutor,
payload_cache: PayloadCache<E>,
builder_profit_threshold: Uint256,
spec: ChainSpec,
log: Logger,
}
@ -252,8 +251,6 @@ pub struct Config {
/// The minimum value of an external payload for it to be considered in a proposal.
pub builder_profit_threshold: u128,
pub execution_timeout_multiplier: Option<u32>,
#[serde(skip)]
pub spec: ChainSpec,
}
/// Provides access to one execution engine and provides a neat interface for consumption by the
@ -281,7 +278,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
default_datadir,
builder_profit_threshold,
execution_timeout_multiplier,
spec,
} = config;
if urls.len() > 1 {
@ -326,9 +322,13 @@ impl<T: EthSpec> ExecutionLayer<T> {
let engine: Engine = {
let auth = Auth::new(jwt_key, jwt_id, jwt_version);
debug!(log, "Loaded execution endpoint"; "endpoint" => %execution_url, "jwt_path" => ?secret_file.as_path());
let api =
HttpJsonRpc::new_with_auth(execution_url, auth, execution_timeout_multiplier, &spec)
.map_err(Error::ApiError)?;
let api = HttpJsonRpc::new_with_auth(
execution_url,
auth,
execution_timeout_multiplier,
&spec,
)
.map_err(Error::ApiError)?;
Engine::new(api, executor.clone(), &log)
};
@ -354,7 +354,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
executor,
payload_cache: PayloadCache::default(),
builder_profit_threshold: Uint256::from(builder_profit_threshold),
spec,
log,
};
@ -1028,7 +1027,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
let response = engine
.notify_forkchoice_updated(
current_fork,
fork_choice_state,
Some(payload_attributes.clone()),
self.log(),
@ -1289,13 +1287,8 @@ impl<T: EthSpec> ExecutionLayer<T> {
finalized_block_hash,
};
let fork_name = self
.inner
.spec
.fork_name_at_epoch(next_slot.epoch(T::slots_per_epoch()));
self.engine()
.set_latest_forkchoice_state(fork_name, forkchoice_state)
.set_latest_forkchoice_state(forkchoice_state)
.await;
let payload_attributes_ref = &payload_attributes;
@ -1304,7 +1297,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
.request(|engine| async move {
engine
.notify_forkchoice_updated(
fork_name,
forkchoice_state,
payload_attributes_ref.clone(),
self.log(),

View File

@ -348,7 +348,6 @@ pub fn get_config<E: EthSpec>(
let execution_timeout_multiplier =
clap_utils::parse_required(cli_args, "execution-timeout-multiplier")?;
el_config.execution_timeout_multiplier = Some(execution_timeout_multiplier);
el_config.spec = spec.clone();
// If `--execution-endpoint` is provided, we should ignore any `--eth1-endpoints` values and
// use `--execution-endpoint` instead. Also, log a deprecation warning.

View File

@ -18,8 +18,8 @@ use tree_hash_derive::TreeHash;
Decode,
TreeHash,
Default,
TestRandom,
Derivative,
TestRandom,
Derivative,
arbitrary::Arbitrary,
)]
#[serde(bound = "T: EthSpec")]