Simplify error handling after engines fallback removal (#3283)

## Issue Addressed
Part of #3118, continuation of #3257

## Proposed Changes
- the [ `first_success_without_retry` ](9c429d0764/beacon_node/execution_layer/src/engines.rs (L348-L351)) function returns a single error.
- the [`first_success`](9c429d0764/beacon_node/execution_layer/src/engines.rs (L324)) function returns a single error.
- [ `EngineErrors` ](9c429d0764/beacon_node/execution_layer/src/lib.rs (L69)) carries a single error.
- [`EngineError`](9c429d0764/beacon_node/execution_layer/src/engines.rs (L173-L177)) now does not need to carry an Id
- [`process_multiple_payload_statuses`](9c429d0764/beacon_node/execution_layer/src/payload_status.rs (L46-L50)) now doesn't need to receive an iterator of statuses and weight in different errors

## Additional Info
This is built on top of #3294
This commit is contained in:
Divma
2022-07-04 02:56:13 +00:00
parent 61ed5f0ec6
commit 1219da9a45
3 changed files with 154 additions and 248 deletions

View File

@@ -12,7 +12,7 @@ pub use engine_api::{http, http::deposit_methods, http::HttpJsonRpc};
pub use engines::ForkChoiceState;
use engines::{Engine, EngineError, Engines, Logging};
use lru::LruCache;
use payload_status::process_multiple_payload_statuses;
use payload_status::process_payload_status;
pub use payload_status::PayloadStatus;
use sensitive_url::SensitiveUrl;
use serde::{Deserialize, Serialize};
@@ -68,11 +68,10 @@ pub enum Error {
NoPayloadBuilder,
ApiError(ApiError),
Builder(builder_client::Error),
EngineErrors(Vec<EngineError>),
EngineError(Box<EngineError>),
NotSynced,
ShuttingDown,
FeeRecipientUnspecified,
ConsensusFailure,
MissingLatestValidHash,
InvalidJWTSecret(String),
}
@@ -200,12 +199,11 @@ impl<T: EthSpec> ExecutionLayer<T> {
}?;
let engine: Engine<EngineApi> = {
let id = execution_url.to_string();
let auth = Auth::new(jwt_key, jwt_id, jwt_version);
debug!(log, "Loaded execution endpoint"; "endpoint" => %id, "jwt_path" => ?secret_file.as_path());
debug!(log, "Loaded execution endpoint"; "endpoint" => %execution_url, "jwt_path" => ?secret_file.as_path());
let api = HttpJsonRpc::<EngineApi>::new_with_auth(execution_url, auth)
.map_err(Error::ApiError)?;
Engine::<EngineApi>::new(id, api)
Engine::<EngineApi>::new(api)
};
let builder = builder_url
@@ -709,7 +707,8 @@ impl<T: EthSpec> ExecutionLayer<T> {
})
})
.await
.map_err(Error::EngineErrors)
.map_err(Box::new)
.map_err(Error::EngineError)
}
/// Maps to the `engine_newPayload` JSON-RPC call.
@@ -742,16 +741,14 @@ impl<T: EthSpec> ExecutionLayer<T> {
"block_number" => execution_payload.block_number,
);
let broadcast_results = self
let broadcast_result = self
.engines()
.broadcast(|engine| engine.api.new_payload_v1(execution_payload.clone()))
.await;
process_multiple_payload_statuses(
execution_payload.block_hash,
Some(broadcast_results).into_iter(),
self.log(),
)
process_payload_status(execution_payload.block_hash, broadcast_result, self.log())
.map_err(Box::new)
.map_err(Error::EngineError)
}
/// Register that the given `validator_index` is going to produce a block at `slot`.
@@ -879,7 +876,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
.set_latest_forkchoice_state(forkchoice_state)
.await;
let broadcast_results = self
let broadcast_result = self
.engines()
.broadcast(|engine| async move {
engine
@@ -888,13 +885,13 @@ impl<T: EthSpec> ExecutionLayer<T> {
})
.await;
process_multiple_payload_statuses(
process_payload_status(
head_block_hash,
Some(broadcast_results)
.into_iter()
.map(|result| result.map(|response| response.payload_status)),
broadcast_result.map(|response| response.payload_status),
self.log(),
)
.map_err(Box::new)
.map_err(Error::EngineError)
}
pub async fn exchange_transition_configuration(&self, spec: &ChainSpec) -> Result<(), Error> {
@@ -909,9 +906,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
.broadcast(|engine| engine.api.exchange_transition_configuration_v1(local))
.await;
let mut errors = vec![];
// Having no fallbacks, the id of the used node is 0
let i = 0usize;
match broadcast_result {
Ok(remote) => {
if local.terminal_total_difficulty != remote.terminal_total_difficulty
@@ -922,20 +916,18 @@ impl<T: EthSpec> ExecutionLayer<T> {
"Execution client config mismatch";
"msg" => "ensure lighthouse and the execution client are up-to-date and \
configured consistently",
"execution_endpoint" => i,
"remote" => ?remote,
"local" => ?local,
);
errors.push(EngineError::Api {
id: i.to_string(),
Err(Error::EngineError(Box::new(EngineError::Api {
error: ApiError::TransitionConfigurationMismatch,
});
})))
} else {
debug!(
self.log(),
"Execution client config is OK";
"execution_endpoint" => i
);
Ok(())
}
}
Err(e) => {
@@ -943,17 +935,10 @@ impl<T: EthSpec> ExecutionLayer<T> {
self.log(),
"Unable to get transition config";
"error" => ?e,
"execution_endpoint" => i,
);
errors.push(e);
Err(Error::EngineError(Box::new(e)))
}
}
if errors.is_empty() {
Ok(())
} else {
Err(Error::EngineErrors(errors))
}
}
/// Used during block production to determine if the merge has been triggered.
@@ -992,7 +977,8 @@ impl<T: EthSpec> ExecutionLayer<T> {
.await
})
.await
.map_err(Error::EngineErrors)?;
.map_err(Box::new)
.map_err(Error::EngineError)?;
if let Some(hash) = &hash_opt {
info!(
@@ -1102,7 +1088,8 @@ impl<T: EthSpec> ExecutionLayer<T> {
Ok(None)
})
.await
.map_err(|e| Error::EngineErrors(vec![e]))
.map_err(Box::new)
.map_err(Error::EngineError)
}
/// This function should remain internal.
@@ -1160,7 +1147,8 @@ impl<T: EthSpec> ExecutionLayer<T> {
.await
})
.await
.map_err(Error::EngineErrors)
.map_err(Box::new)
.map_err(Error::EngineError)
}
async fn get_payload_by_block_hash_from_engine(