get rid of EL endpoint switching at forks
This commit is contained in:
parent
d96d793bfb
commit
e9affafb6b
@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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(),
|
||||
|
@ -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.
|
||||
|
@ -18,8 +18,8 @@ use tree_hash_derive::TreeHash;
|
||||
Decode,
|
||||
TreeHash,
|
||||
Default,
|
||||
TestRandom,
|
||||
Derivative,
|
||||
TestRandom,
|
||||
Derivative,
|
||||
arbitrary::Arbitrary,
|
||||
)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
|
Loading…
Reference in New Issue
Block a user