Integrate tracing (#6339)

Tracing Integration
- [reference](5bbf1859e9/projects/project-ideas.md (L297))


  - [x] replace slog & log with tracing throughout the codebase
- [x] implement custom crit log
- [x] make relevant changes in the formatter
- [x] replace sloggers
- [x] re-write SSE logging components

cc: @macladson @eserilev
This commit is contained in:
ThreeHrSleep
2025-03-13 04:01:05 +05:30
committed by GitHub
parent f23f984f85
commit d60c24ef1c
241 changed files with 9485 additions and 9328 deletions

View File

@@ -36,7 +36,6 @@ sensitive_url = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
slog = { workspace = true }
slot_clock = { workspace = true }
ssz_types = { workspace = true }
state_processing = { workspace = true }
@@ -46,6 +45,7 @@ task_executor = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true }
tokio-stream = { workspace = true }
tracing = { workspace = true }
tree_hash = { workspace = true }
tree_hash_derive = { workspace = true }
triehash = "0.8.4"

View File

@@ -6,7 +6,6 @@ use crate::engine_api::{
};
use crate::{ClientVersionV1, HttpJsonRpc};
use lru::LruCache;
use slog::{debug, error, info, warn, Logger};
use std::future::Future;
use std::num::NonZeroUsize;
use std::sync::Arc;
@@ -14,6 +13,7 @@ use std::time::Duration;
use task_executor::TaskExecutor;
use tokio::sync::{watch, Mutex, RwLock};
use tokio_stream::wrappers::WatchStream;
use tracing::{debug, error, info, warn};
use types::non_zero_usize::new_non_zero_usize;
use types::ExecutionBlockHash;
@@ -128,19 +128,17 @@ pub struct Engine {
state: RwLock<State>,
latest_forkchoice_state: RwLock<Option<ForkchoiceState>>,
executor: TaskExecutor,
log: Logger,
}
impl Engine {
/// Creates a new, offline engine.
pub fn new(api: HttpJsonRpc, executor: TaskExecutor, log: &Logger) -> Self {
pub fn new(api: HttpJsonRpc, executor: TaskExecutor) -> Self {
Self {
api,
payload_id_cache: Mutex::new(LruCache::new(PAYLOAD_ID_LRU_CACHE_SIZE)),
state: Default::default(),
latest_forkchoice_state: Default::default(),
executor,
log: log.clone(),
}
}
@@ -167,7 +165,6 @@ impl Engine {
&self,
forkchoice_state: ForkchoiceState,
payload_attributes: Option<PayloadAttributes>,
log: &Logger,
) -> Result<ForkchoiceUpdatedResponse, EngineApiError> {
let response = self
.api
@@ -180,11 +177,7 @@ impl Engine {
{
self.payload_id_cache.lock().await.put(key, payload_id);
} else {
debug!(
log,
"Engine returned unexpected payload_id";
"payload_id" => ?payload_id
);
debug!(?payload_id, "Engine returned unexpected payload_id");
}
}
@@ -205,33 +198,24 @@ impl Engine {
if let Some(forkchoice_state) = latest_forkchoice_state {
if forkchoice_state.head_block_hash == ExecutionBlockHash::zero() {
debug!(
self.log,
"No need to call forkchoiceUpdated";
"msg" => "head does not have execution enabled",
msg = "head does not have execution enabled",
"No need to call forkchoiceUpdated"
);
return;
}
info!(
self.log,
"Issuing forkchoiceUpdated";
"forkchoice_state" => ?forkchoice_state,
);
info!(?forkchoice_state, "Issuing forkchoiceUpdated");
// 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(forkchoice_state, None).await {
debug!(
self.log,
"Failed to issue latest head to engine";
"error" => ?e,
error = ?e,
"Failed to issue latest head to engine"
);
}
} else {
debug!(
self.log,
"No head, not sending to engine";
);
debug!("No head, not sending to engine");
}
}
@@ -252,18 +236,12 @@ impl Engine {
Ok(()) => {
let mut state = self.state.write().await;
if **state != EngineStateInternal::Synced {
info!(
self.log,
"Execution engine online";
);
info!("Execution engine online");
// Send the node our latest forkchoice_state.
self.send_latest_forkchoice_state().await;
} else {
debug!(
self.log,
"Execution engine online";
);
debug!("Execution engine online");
}
state.update(EngineStateInternal::Synced);
(**state, ResponseCacheAction::Update)
@@ -275,9 +253,8 @@ impl Engine {
}
Err(EngineApiError::Auth(err)) => {
error!(
self.log,
"Failed jwt authorization";
"error" => ?err,
error = ?err,
"Failed jwt authorization"
);
let mut state = self.state.write().await;
@@ -286,9 +263,8 @@ impl Engine {
}
Err(e) => {
error!(
self.log,
"Error during execution engine upcheck";
"error" => ?e,
error = ?e,
"Error during execution engine upcheck"
);
let mut state = self.state.write().await;
@@ -308,9 +284,9 @@ impl Engine {
.get_engine_capabilities(Some(CACHED_RESPONSE_AGE_LIMIT))
.await
{
warn!(self.log,
"Error during exchange capabilities";
"error" => ?e,
warn!(
error = ?e,
"Error during exchange capabilities"
)
} else {
// no point in running this if there was an error fetching the capabilities
@@ -326,11 +302,7 @@ impl Engine {
}
}
debug!(
self.log,
"Execution engine upcheck complete";
"state" => ?state,
);
debug!(?state, "Execution engine upcheck complete");
}
/// Returns the execution engine capabilities resulting from a call to
@@ -395,11 +367,7 @@ impl Engine {
Ok(result)
}
Err(error) => {
warn!(
self.log,
"Execution engine call failed";
"error" => ?error,
);
warn!(?error, "Execution engine call failed");
// The node just returned an error, run an upcheck so we can update the endpoint
// state.

View File

@@ -21,12 +21,12 @@ use eth2::types::{builder_bid::SignedBuilderBid, BlobsBundle, ForkVersionedRespo
use ethers_core::types::Transaction as EthersTransaction;
use fixed_bytes::UintExtended;
use fork_choice::ForkchoiceUpdateParameters;
use logging::crit;
use lru::LruCache;
use payload_status::process_payload_status;
pub use payload_status::PayloadStatus;
use sensitive_url::SensitiveUrl;
use serde::{Deserialize, Serialize};
use slog::{crit, debug, error, info, warn, Logger};
use slot_clock::SlotClock;
use std::collections::{hash_map::Entry, HashMap};
use std::fmt;
@@ -43,6 +43,7 @@ use tokio::{
time::sleep,
};
use tokio_stream::wrappers::WatchStream;
use tracing::{debug, error, info, warn};
use tree_hash::TreeHash;
use types::beacon_block_body::KzgCommitments;
use types::builder_bid::BuilderBid;
@@ -422,7 +423,6 @@ struct Inner<E: EthSpec> {
proposers: RwLock<HashMap<ProposerKey, Proposer>>,
executor: TaskExecutor,
payload_cache: PayloadCache<E>,
log: Logger,
/// Track whether the last `newPayload` call errored.
///
/// This is used *only* in the informational sync status endpoint, so that a VC using this
@@ -466,7 +466,7 @@ pub struct ExecutionLayer<E: EthSpec> {
impl<E: EthSpec> ExecutionLayer<E> {
/// Instantiate `Self` with an Execution engine specified in `Config`, using JSON-RPC via HTTP.
pub fn from_config(config: Config, executor: TaskExecutor, log: Logger) -> Result<Self, Error> {
pub fn from_config(config: Config, executor: TaskExecutor) -> Result<Self, Error> {
let Config {
execution_endpoint: url,
builder_url,
@@ -500,7 +500,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
.map_err(Error::InvalidJWTSecret)
} else {
// Create a new file and write a randomly generated secret to it if file does not exist
warn!(log, "No JWT found on disk. Generating"; "path" => %secret_file.display());
warn!(path = %secret_file.display(),"No JWT found on disk. Generating");
std::fs::File::options()
.write(true)
.create_new(true)
@@ -517,10 +517,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
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());
debug!(endpoint = %execution_url, jwt_path = ?secret_file.as_path(),"Loaded execution endpoint");
let api = HttpJsonRpc::new_with_auth(execution_url, auth, execution_timeout_multiplier)
.map_err(Error::ApiError)?;
Engine::new(api, executor.clone(), &log)
Engine::new(api, executor.clone())
};
let inner = Inner {
@@ -533,7 +533,6 @@ impl<E: EthSpec> ExecutionLayer<E> {
execution_blocks: Mutex::new(LruCache::new(EXECUTION_BLOCKS_LRU_CACHE_SIZE)),
executor,
payload_cache: PayloadCache::default(),
log,
last_new_payload_errored: RwLock::new(false),
};
@@ -580,11 +579,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
)
.map_err(Error::Builder)?;
info!(
self.log(),
"Using external block builder";
"builder_url" => ?builder_url,
"local_user_agent" => builder_client.get_user_agent(),
"ssz_disabled" => disable_ssz
?builder_url,
local_user_agent = builder_client.get_user_agent(),
ssz_disabled = disable_ssz,
"Using external block builder"
);
self.inner.builder.swap(Some(Arc::new(builder_client)));
Ok(())
@@ -655,10 +653,6 @@ impl<E: EthSpec> ExecutionLayer<E> {
&self.inner.proposers
}
fn log(&self) -> &Logger {
&self.inner.log
}
pub async fn execution_engine_forkchoice_lock(&self) -> MutexGuard<'_, ()> {
self.inner.execution_engine_forkchoice_lock.lock().await
}
@@ -716,16 +710,15 @@ impl<E: EthSpec> ExecutionLayer<E> {
.await
.map_err(|e| {
error!(
el.log(),
"Failed to clean proposer preparation cache";
"error" => format!("{:?}", e)
error = ?e,
"Failed to clean proposer preparation cache"
)
})
.unwrap_or(()),
None => error!(el.log(), "Failed to get current epoch from slot clock"),
None => error!("Failed to get current epoch from slot clock"),
}
} else {
error!(el.log(), "Failed to read slot clock");
error!("Failed to read slot clock");
// If we can't read the slot clock, just wait another slot and retry.
sleep(slot_clock.slot_duration()).await;
}
@@ -865,12 +858,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
} else {
// If there is no user-provided fee recipient, use a junk value and complain loudly.
crit!(
self.log(),
"Fee recipient unknown";
"msg" => "the suggested_fee_recipient was unknown during block production. \
msg = "the suggested_fee_recipient was unknown during block production. \
a junk address was used, rewards were lost! \
check the --suggested-fee-recipient flag and VC configuration.",
"proposer_index" => ?proposer_index
?proposer_index,
"Fee recipient unknown"
);
Address::from_slice(&DEFAULT_SUGGESTED_FEE_RECIPIENT)
@@ -987,11 +979,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
let parent_hash = payload_parameters.parent_hash;
info!(
self.log(),
"Requesting blinded header from connected builder";
"slot" => ?slot,
"pubkey" => ?pubkey,
"parent_hash" => ?parent_hash,
?slot,
?pubkey,
?parent_hash,
"Requesting blinded header from connected builder"
);
// Wait for the builder *and* local EL to produce a payload (or return an error).
@@ -1012,20 +1003,19 @@ impl<E: EthSpec> ExecutionLayer<E> {
);
info!(
self.log(),
"Requested blinded execution payload";
"relay_fee_recipient" => match &relay_result {
relay_fee_recipient = match &relay_result {
Ok(Some(r)) => format!("{:?}", r.data.message.header().fee_recipient()),
Ok(None) => "empty response".to_string(),
Err(_) => "request failed".to_string(),
},
"relay_response_ms" => relay_duration.as_millis(),
"local_fee_recipient" => match &local_result {
relay_response_ms = relay_duration.as_millis(),
local_fee_recipient = match &local_result {
Ok(get_payload_response) => format!("{:?}", get_payload_response.fee_recipient()),
Err(_) => "request failed".to_string()
Err(_) => "request failed".to_string(),
},
"local_response_ms" => local_duration.as_millis(),
"parent_hash" => ?parent_hash,
local_response_ms = local_duration.as_millis(),
?parent_hash,
"Requested blinded execution payload"
);
(relay_result, local_result)
@@ -1052,24 +1042,21 @@ impl<E: EthSpec> ExecutionLayer<E> {
// chain is unhealthy, gotta use local payload
match builder_params.chain_health {
ChainHealth::Unhealthy(condition) => info!(
self.log(),
"Chain is unhealthy, using local payload";
"info" => "this helps protect the network. the --builder-fallback flags \
can adjust the expected health conditions.",
"failed_condition" => ?condition
info = "this helps protect the network. the --builder-fallback flags \
can adjust the expected health conditions.",
failed_condition = ?condition,
"Chain is unhealthy, using local payload"
),
// Intentional no-op, so we never attempt builder API proposals pre-merge.
ChainHealth::PreMerge => (),
ChainHealth::Optimistic => info!(
self.log(),
"Chain is optimistic; can't build payload";
"info" => "the local execution engine is syncing and the builder network \
cannot safely be used - unable to propose block"
),
ChainHealth::Healthy => crit!(
self.log(),
"got healthy but also not healthy.. this shouldn't happen!"
info = "the local execution engine is syncing and the builder network \
cannot safely be used - unable to propose block",
"Chain is optimistic; can't build payload"
),
ChainHealth::Healthy => {
crit!("got healthy but also not healthy.. this shouldn't happen!")
}
}
return self
.get_full_payload_caching(payload_parameters)
@@ -1086,12 +1073,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
match (relay_result, local_result) {
(Err(e), Ok(local)) => {
warn!(
self.log(),
"Builder error when requesting payload";
"info" => "falling back to local execution client",
"relay_error" => ?e,
"local_block_hash" => ?local.block_hash(),
"parent_hash" => ?parent_hash,
info = "falling back to local execution client",
relay_error = ?e,
local_block_hash = ?local.block_hash(),
?parent_hash,
"Builder error when requesting payload"
);
Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full(
local.try_into()?,
@@ -1099,11 +1085,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
}
(Ok(None), Ok(local)) => {
info!(
self.log(),
"Builder did not return a payload";
"info" => "falling back to local execution client",
"local_block_hash" => ?local.block_hash(),
"parent_hash" => ?parent_hash,
info = "falling back to local execution client",
local_block_hash=?local.block_hash(),
?parent_hash,
"Builder did not return a payload"
);
Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full(
local.try_into()?,
@@ -1111,24 +1096,22 @@ impl<E: EthSpec> ExecutionLayer<E> {
}
(Err(relay_error), Err(local_error)) => {
crit!(
self.log(),
"Unable to produce execution payload";
"info" => "the local EL and builder both failed - unable to propose block",
"relay_error" => ?relay_error,
"local_error" => ?local_error,
"parent_hash" => ?parent_hash,
info = "the local EL and builder both failed - unable to propose block",
?relay_error,
?local_error,
?parent_hash,
"Unable to produce execution payload"
);
Err(Error::CannotProduceHeader)
}
(Ok(None), Err(local_error)) => {
crit!(
self.log(),
"Unable to produce execution payload";
"info" => "the local EL failed and the builder returned nothing - \
the block proposal will be missed",
"local_error" => ?local_error,
"parent_hash" => ?parent_hash,
info = "the local EL failed and the builder returned nothing - \
the block proposal will be missed",
?local_error,
?parent_hash,
"Unable to produce execution payload"
);
Err(Error::CannotProduceHeader)
@@ -1137,11 +1120,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
let header = &relay.data.message.header();
info!(
self.log(),
"Received local and builder payloads";
"relay_block_hash" => ?header.block_hash(),
"local_block_hash" => ?local.block_hash(),
"parent_hash" => ?parent_hash,
relay_block_hash = ?header.block_hash(),
local_block_hash=?local.block_hash(),
?parent_hash,
"Received local and builder payloads"
);
// check relay payload validity
@@ -1154,12 +1136,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
&[reason.as_ref().as_ref()],
);
warn!(
self.log(),
"Builder returned invalid payload";
"info" => "using local payload",
"reason" => %reason,
"relay_block_hash" => ?header.block_hash(),
"parent_hash" => ?parent_hash,
info = "using local payload",
%reason,
relay_block_hash = ?header.block_hash(),
?parent_hash,
"Builder returned invalid payload"
);
return Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full(
local.try_into()?,
@@ -1178,12 +1159,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
if local_value >= boosted_relay_value {
info!(
self.log(),
"Local block is more profitable than relay block";
"local_block_value" => %local_value,
"relay_value" => %relay_value,
"boosted_relay_value" => %boosted_relay_value,
"builder_boost_factor" => ?builder_boost_factor,
%local_value,
%relay_value,
%boosted_relay_value,
?builder_boost_factor,
"Local block is more profitable than relay block"
);
return Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full(
local.try_into()?,
@@ -1192,10 +1172,9 @@ impl<E: EthSpec> ExecutionLayer<E> {
if local.should_override_builder().unwrap_or(false) {
info!(
self.log(),
"Using local payload because execution engine suggested we ignore builder payload";
"local_block_value" => %local_value,
"relay_value" => %relay_value
%local_value,
%relay_value,
"Using local payload because execution engine suggested we ignore builder payload"
);
return Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full(
local.try_into()?,
@@ -1203,12 +1182,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
}
info!(
self.log(),
"Relay block is more profitable than local block";
"local_block_value" => %local_value,
"relay_value" => %relay_value,
"boosted_relay_value" => %boosted_relay_value,
"builder_boost_factor" => ?builder_boost_factor
%local_value,
%relay_value,
%boosted_relay_value,
?builder_boost_factor,
"Relay block is more profitable than local block"
);
Ok(ProvenancedPayload::try_from(relay.data.message)?)
@@ -1217,11 +1195,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
let header = &relay.data.message.header();
info!(
self.log(),
"Received builder payload with local error";
"relay_block_hash" => ?header.block_hash(),
"local_error" => ?local_error,
"parent_hash" => ?parent_hash,
relay_block_hash = ?header.block_hash(),
?local_error,
?parent_hash,
"Received builder payload with local error"
);
match verify_builder_bid(&relay, payload_parameters, None, spec) {
@@ -1232,12 +1209,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
&[reason.as_ref().as_ref()],
);
crit!(
self.log(),
"Builder returned invalid payload";
"info" => "no local payload either - unable to propose block",
"reason" => %reason,
"relay_block_hash" => ?header.block_hash(),
"parent_hash" => ?parent_hash,
info = "no local payload either - unable to propose block",
%reason,
relay_block_hash = ?header.block_hash(),
?parent_hash,
"Builder returned invalid payload"
);
Err(Error::CannotProduceHeader)
}
@@ -1304,7 +1280,6 @@ impl<E: EthSpec> ExecutionLayer<E> {
.notify_forkchoice_updated(
fork_choice_state,
Some(payload_attributes.clone()),
self.log(),
)
.await?;
@@ -1312,12 +1287,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
Some(payload_id) => payload_id,
None => {
error!(
self.log(),
"Exec engine unable to produce payload";
"msg" => "No payload ID, the engine is likely syncing. \
This has the potential to cause a missed block proposal.",
"status" => ?response.payload_status
);
msg = "No payload ID, the engine is likely syncing. \
This has the potential to cause a missed block proposal.",
status = ?response.payload_status,
"Exec engine unable to produce payload"
);
return Err(ApiError::PayloadIdUnavailable);
}
}
@@ -1325,36 +1299,44 @@ impl<E: EthSpec> ExecutionLayer<E> {
let payload_response = async {
debug!(
self.log(),
"Issuing engine_getPayload";
"suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(),
"prev_randao" => ?payload_attributes.prev_randao(),
"timestamp" => payload_attributes.timestamp(),
"parent_hash" => ?parent_hash,
suggested_fee_recipient = ?payload_attributes.suggested_fee_recipient(),
prev_randao = ?payload_attributes.prev_randao(),
timestamp = payload_attributes.timestamp(),
?parent_hash,
"Issuing engine_getPayload"
);
let _timer = metrics::start_timer_vec(
&metrics::EXECUTION_LAYER_REQUEST_TIMES,
&[metrics::GET_PAYLOAD],
);
engine.api.get_payload::<E>(current_fork, payload_id).await
}.await?;
}
.await?;
if payload_response.execution_payload_ref().fee_recipient() != payload_attributes.suggested_fee_recipient() {
if payload_response.execution_payload_ref().fee_recipient()
!= payload_attributes.suggested_fee_recipient()
{
error!(
self.log(),
"Inconsistent fee recipient";
"msg" => "The fee recipient returned from the Execution Engine differs \
msg = "The fee recipient returned from the Execution Engine differs \
from the suggested_fee_recipient set on the beacon node. This could \
indicate that fees are being diverted to another address. Please \
ensure that the value of suggested_fee_recipient is set correctly and \
that the Execution Engine is trusted.",
"fee_recipient" => ?payload_response.execution_payload_ref().fee_recipient(),
"suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(),
fee_recipient = ?payload_response.execution_payload_ref().fee_recipient(),
suggested_fee_recipient = ?payload_attributes.suggested_fee_recipient(),
"Inconsistent fee recipient"
);
}
if cache_fn(self, (payload_response.execution_payload_ref(), payload_response.blobs_bundle().ok())).is_some() {
if cache_fn(
self,
(
payload_response.execution_payload_ref(),
payload_response.blobs_bundle().ok(),
),
)
.is_some()
{
warn!(
self.log(),
"Duplicate payload cached, this might indicate redundant proposal \
attempts."
);
@@ -1394,18 +1376,17 @@ impl<E: EthSpec> ExecutionLayer<E> {
&["new_payload", status_str],
);
debug!(
self.log(),
"Processed engine_newPayload";
"status" => status_str,
"parent_hash" => ?parent_hash,
"block_hash" => ?block_hash,
"block_number" => block_number,
"response_time_ms" => timer.elapsed().as_millis()
status = status_str,
?parent_hash,
?block_hash,
block_number,
response_time_ms = timer.elapsed().as_millis(),
"Processed engine_newPayload"
);
}
*self.inner.last_new_payload_errored.write().await = result.is_err();
process_payload_status(block_hash, result, self.log())
process_payload_status(block_hash, result)
.map_err(Box::new)
.map_err(Error::EngineError)
}
@@ -1462,12 +1443,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
let proposer = self.proposers().read().await.get(&proposers_key).cloned()?;
debug!(
self.log(),
"Beacon proposer found";
"payload_attributes" => ?proposer.payload_attributes,
"head_block_root" => ?head_block_root,
"slot" => current_slot,
"validator_index" => proposer.validator_index,
payload_attributes = ?proposer.payload_attributes,
?head_block_root,
slot = %current_slot,
validator_index = proposer.validator_index,
"Beacon proposer found"
);
Some(proposer.payload_attributes)
@@ -1488,13 +1468,12 @@ impl<E: EthSpec> ExecutionLayer<E> {
);
debug!(
self.log(),
"Issuing engine_forkchoiceUpdated";
"finalized_block_hash" => ?finalized_block_hash,
"justified_block_hash" => ?justified_block_hash,
"head_block_hash" => ?head_block_hash,
"head_block_root" => ?head_block_root,
"current_slot" => current_slot,
?finalized_block_hash,
?justified_block_hash,
?head_block_hash,
?head_block_root,
?current_slot,
"Issuing engine_forkchoiceUpdated"
);
let next_slot = current_slot + 1;
@@ -1510,12 +1489,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
lookahead,
);
} else {
debug!(
self.log(),
"Late payload attributes";
"timestamp" => ?timestamp,
"now" => ?now,
)
debug!(?timestamp, ?now, "Late payload attributes")
}
}
}
@@ -1534,7 +1508,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
.engine()
.request(|engine| async move {
engine
.notify_forkchoice_updated(forkchoice_state, payload_attributes, self.log())
.notify_forkchoice_updated(forkchoice_state, payload_attributes)
.await
})
.await;
@@ -1549,7 +1523,6 @@ impl<E: EthSpec> ExecutionLayer<E> {
process_payload_status(
head_block_hash,
result.map(|response| response.payload_status),
self.log(),
)
.map_err(Box::new)
.map_err(Error::EngineError)
@@ -1646,11 +1619,10 @@ impl<E: EthSpec> ExecutionLayer<E> {
if let Some(hash) = &hash_opt {
info!(
self.log(),
"Found terminal block hash";
"terminal_block_hash_override" => ?spec.terminal_block_hash,
"terminal_total_difficulty" => ?spec.terminal_total_difficulty,
"block_hash" => ?hash,
terminal_block_hash_override = ?spec.terminal_block_hash,
terminal_total_difficulty = ?spec.terminal_total_difficulty,
block_hash = ?hash,
"Found terminal block hash"
);
}
@@ -1907,21 +1879,16 @@ impl<E: EthSpec> ExecutionLayer<E> {
block_root: Hash256,
block: &SignedBlindedBeaconBlock<E>,
) -> Result<FullPayloadContents<E>, Error> {
debug!(
self.log(),
"Sending block to builder";
"root" => ?block_root,
);
debug!(?block_root, "Sending block to builder");
if let Some(builder) = self.builder() {
let (payload_result, duration) =
timed_future(metrics::POST_BLINDED_PAYLOAD_BUILDER, async {
let ssz_enabled = builder.is_ssz_available();
debug!(
self.log(),
"Calling submit_blinded_block on builder";
"block_root" => ?block_root,
"ssz" => ssz_enabled
?block_root,
ssz = ssz_enabled,
"Calling submit_blinded_block on builder"
);
if ssz_enabled {
builder
@@ -1946,13 +1913,12 @@ impl<E: EthSpec> ExecutionLayer<E> {
);
let payload = unblinded_response.payload_ref();
info!(
self.log(),
"Builder successfully revealed payload";
"relay_response_ms" => duration.as_millis(),
"block_root" => ?block_root,
"fee_recipient" => ?payload.fee_recipient(),
"block_hash" => ?payload.block_hash(),
"parent_hash" => ?payload.parent_hash()
relay_response_ms = duration.as_millis(),
?block_root,
fee_recipient = ?payload.fee_recipient(),
block_hash = ?payload.block_hash(),
parent_hash = ?payload.parent_hash(),
"Builder successfully revealed payload"
)
}
Err(e) => {
@@ -1961,17 +1927,16 @@ impl<E: EthSpec> ExecutionLayer<E> {
&[metrics::FAILURE],
);
warn!(
self.log(),
"Builder failed to reveal payload";
"info" => "this is common behaviour for some builders and may not indicate an issue",
"error" => ?e,
"relay_response_ms" => duration.as_millis(),
"block_root" => ?block_root,
"parent_hash" => ?block
info = "this is common behaviour for some builders and may not indicate an issue",
error = ?e,
relay_response_ms = duration.as_millis(),
?block_root,
parent_hash = ?block
.message()
.execution_payload()
.map(|payload| format!("{}", payload.parent_hash()))
.unwrap_or_else(|_| "unknown".to_string())
.unwrap_or_else(|_| "unknown".to_string()),
"Builder failed to reveal payload"
)
}
}

View File

@@ -1,6 +1,6 @@
use crate::engine_api::{Error as ApiError, PayloadStatusV1, PayloadStatusV1Status};
use crate::engines::EngineError;
use slog::{warn, Logger};
use tracing::warn;
use types::ExecutionBlockHash;
/// Provides a simpler, easier to parse version of `PayloadStatusV1` for upstream users.
@@ -26,15 +26,10 @@ pub enum PayloadStatus {
pub fn process_payload_status(
head_block_hash: ExecutionBlockHash,
status: Result<PayloadStatusV1, EngineError>,
log: &Logger,
) -> Result<PayloadStatus, EngineError> {
match status {
Err(error) => {
warn!(
log,
"Error whilst processing payload status";
"error" => ?error,
);
warn!(?error, "Error whilst processing payload status");
Err(error)
}
Ok(response) => match &response.status {
@@ -66,10 +61,9 @@ pub fn process_payload_status(
// warning here.
if response.latest_valid_hash.is_some() {
warn!(
log,
"Malformed response from execution engine";
"msg" => "expected a null latest_valid_hash",
"status" => ?response.status
msg = "expected a null latest_valid_hash",
status = ?response.status,
"Malformed response from execution engine"
)
}
@@ -82,10 +76,9 @@ pub fn process_payload_status(
// warning here.
if response.latest_valid_hash.is_some() {
warn!(
log,
"Malformed response from execution engine";
"msg" => "expected a null latest_valid_hash",
"status" => ?response.status
msg = "expected a null latest_valid_hash",
status = ?response.status,
"Malformed response from execution engine"
)
}
@@ -96,10 +89,9 @@ pub fn process_payload_status(
// warning here.
if response.latest_valid_hash.is_some() {
warn!(
log,
"Malformed response from execution engine";
"msg" => "expected a null latest_valid_hash",
"status" => ?response.status
msg = "expected a null latest_valid_hash",
status = ?response.status,
"Malformed response from execution engine"
)
}

View File

@@ -13,7 +13,6 @@ use eth2::{
use fork_choice::ForkchoiceUpdateParameters;
use parking_lot::RwLock;
use sensitive_url::SensitiveUrl;
use slog::{debug, error, info, warn, Logger};
use ssz::Encode;
use std::collections::HashMap;
use std::fmt::Debug;
@@ -24,6 +23,7 @@ use std::time::Duration;
use task_executor::TaskExecutor;
use tempfile::NamedTempFile;
use tokio_stream::StreamExt;
use tracing::{debug, error, info, warn};
use tree_hash::TreeHash;
use types::builder_bid::{
BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidElectra,
@@ -309,7 +309,6 @@ pub struct MockBuilder<E: EthSpec> {
max_bid: bool,
/// A cache that stores the proposers index for a given epoch
proposers_cache: Arc<RwLock<HashMap<Epoch, Vec<ProposerData>>>>,
log: Logger,
}
impl<E: EthSpec> MockBuilder<E> {
@@ -331,8 +330,7 @@ impl<E: EthSpec> MockBuilder<E> {
..Default::default()
};
let el =
ExecutionLayer::from_config(config, executor.clone(), executor.log().clone()).unwrap();
let el = ExecutionLayer::from_config(config, executor.clone()).unwrap();
let builder = MockBuilder::new(
el,
@@ -342,7 +340,6 @@ impl<E: EthSpec> MockBuilder<E> {
false,
spec,
None,
executor.log().clone(),
);
let host: Ipv4Addr = Ipv4Addr::LOCALHOST;
let port = 0;
@@ -359,16 +356,12 @@ impl<E: EthSpec> MockBuilder<E> {
max_bid: bool,
spec: Arc<ChainSpec>,
sk: Option<&[u8]>,
log: Logger,
) -> Self {
let builder_sk = if let Some(sk_bytes) = sk {
match SecretKey::deserialize(sk_bytes) {
Ok(sk) => sk,
Err(_) => {
error!(
log,
"Invalid sk_bytes provided, generating random secret key"
);
error!("Invalid sk_bytes provided, generating random secret key");
SecretKey::random()
}
}
@@ -390,7 +383,6 @@ impl<E: EthSpec> MockBuilder<E> {
apply_operations,
max_bid,
genesis_time: None,
log,
}
}
@@ -425,18 +417,13 @@ impl<E: EthSpec> MockBuilder<E> {
&self,
registrations: Vec<SignedValidatorRegistrationData>,
) -> Result<(), String> {
info!(
self.log,
"Registering validators";
"count" => registrations.len(),
);
info!(count = registrations.len(), "Registering validators");
for registration in registrations {
if !registration.verify_signature(&self.spec) {
error!(
self.log,
"Failed to register validator";
"error" => "invalid signature",
"validator" => %registration.message.pubkey
error = "invalid signature",
validator = %registration.message.pubkey,
"Failed to register validator"
);
return Err("invalid signature".to_string());
}
@@ -472,9 +459,8 @@ impl<E: EthSpec> MockBuilder<E> {
}
};
info!(
self.log,
"Submitting blinded beacon block to builder";
"block_hash" => %root
block_hash = %root,
"Submitting blinded beacon block to builder"
);
let payload = self
.el
@@ -486,10 +472,9 @@ impl<E: EthSpec> MockBuilder<E> {
.try_into_full_block(Some(payload.clone()))
.ok_or("Internal error, just provided a payload")?;
debug!(
self.log,
"Got full payload, sending to local beacon node for propagation";
"txs_count" => payload.transactions().len(),
"blob_count" => blobs.as_ref().map(|b| b.commitments.len())
txs_count = payload.transactions().len(),
blob_count = blobs.as_ref().map(|b| b.commitments.len()),
"Got full payload, sending to local beacon node for propagation"
);
let publish_block_request = PublishBlockRequest::new(
Arc::new(full_block),
@@ -508,7 +493,7 @@ impl<E: EthSpec> MockBuilder<E> {
parent_hash: ExecutionBlockHash,
pubkey: PublicKeyBytes,
) -> Result<SignedBuilderBid<E>, String> {
info!(self.log, "In get_header");
info!("In get_header");
// Check if the pubkey has registered with the builder if required
if self.validate_pubkey && !self.val_registration_cache.read().contains_key(&pubkey) {
return Err("validator not registered with builder".to_string());
@@ -521,15 +506,12 @@ impl<E: EthSpec> MockBuilder<E> {
let payload_parameters = match payload_parameters {
Some(params) => params,
None => {
warn!(
self.log,
"Payload params not cached for parent_hash {}", parent_hash
);
warn!("Payload params not cached for parent_hash {}", parent_hash);
self.get_payload_params(slot, None, pubkey, None).await?
}
};
info!(self.log, "Got payload params");
info!("Got payload params");
let fork = self.fork_name_at_slot(slot);
let payload_response_type = self
@@ -545,7 +527,7 @@ impl<E: EthSpec> MockBuilder<E> {
.await
.map_err(|e| format!("couldn't get payload {:?}", e))?;
info!(self.log, "Got payload message, fork {}", fork);
info!("Got payload message, fork {}", fork);
let mut message = match payload_response_type {
crate::GetPayloadResponseType::Full(payload_response) => {
@@ -616,10 +598,10 @@ impl<E: EthSpec> MockBuilder<E> {
};
if self.apply_operations {
info!(self.log, "Applying operations");
info!("Applying operations");
self.apply_operations(&mut message);
}
info!(self.log, "Signing builder message");
info!("Signing builder message");
let mut signature = message.sign_builder_message(&self.builder_sk, &self.spec);
@@ -627,7 +609,7 @@ impl<E: EthSpec> MockBuilder<E> {
signature = Signature::empty();
};
let signed_bid = SignedBuilderBid { message, signature };
info!(self.log, "Builder bid {:?}", &signed_bid.message.value());
info!("Builder bid {:?}", &signed_bid.message.value());
Ok(signed_bid)
}
@@ -648,10 +630,7 @@ impl<E: EthSpec> MockBuilder<E> {
/// Prepare the execution layer for payload creation every slot for the correct
/// proposer index
pub async fn prepare_execution_layer(&self) -> Result<(), String> {
info!(
self.log,
"Starting a task to prepare the execution layer";
);
info!("Starting a task to prepare the execution layer");
let mut head_event_stream = self
.beacon_client
.get_events::<E>(&[EventTopic::Head])
@@ -662,9 +641,8 @@ impl<E: EthSpec> MockBuilder<E> {
match event {
EventKind::Head(head) => {
debug!(
self.log,
"Got a new head event";
"block_hash" => %head.block
block_hash = %head.block,
"Got a new head event"
);
let next_slot = head.slot + 1;
// Find the next proposer index from the cached data or through a beacon api call
@@ -712,9 +690,8 @@ impl<E: EthSpec> MockBuilder<E> {
}
e => {
warn!(
self.log,
"Got an unexpected event";
"event" => %e.topic_name()
event = %e.topic_name(),
"Got an unexpected event"
);
}
}
@@ -812,7 +789,6 @@ impl<E: EthSpec> MockBuilder<E> {
),
None => {
warn!(
self.log,
"Validator not registered {}, using default fee recipient and gas limits",
pubkey
);

View File

@@ -76,8 +76,7 @@ impl<E: EthSpec> MockExecutionLayer<E> {
suggested_fee_recipient: Some(Address::repeat_byte(42)),
..Default::default()
};
let el =
ExecutionLayer::from_config(config, executor.clone(), executor.log().clone()).unwrap();
let el = ExecutionLayer::from_config(config, executor.clone()).unwrap();
Self {
server,

View File

@@ -9,11 +9,11 @@ use bytes::Bytes;
use execution_block_generator::PoWBlock;
use handle_rpc::handle_rpc;
use kzg::Kzg;
use logging::test_logger;
use logging::create_test_tracing_subscriber;
use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
use serde::{Deserialize, Serialize};
use serde_json::json;
use slog::{info, Logger};
use std::collections::HashMap;
use std::convert::Infallible;
use std::future::Future;
@@ -21,6 +21,7 @@ use std::marker::PhantomData;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::sync::{Arc, LazyLock};
use tokio::{runtime, sync::oneshot};
use tracing::info;
use types::{ChainSpec, EthSpec, ExecutionBlockHash, Uint256};
use warp::{http::StatusCode, Filter, Rejection};
@@ -133,6 +134,7 @@ impl<E: EthSpec> MockServer<E> {
spec: Arc<ChainSpec>,
kzg: Option<Arc<Kzg>>,
) -> Self {
create_test_tracing_subscriber();
let MockExecutionConfig {
jwt_key,
terminal_difficulty,
@@ -161,7 +163,6 @@ impl<E: EthSpec> MockServer<E> {
let ctx: Arc<Context<E>> = Arc::new(Context {
config: server_config,
jwt_key,
log: test_logger(),
last_echo_request: last_echo_request.clone(),
execution_block_generator: RwLock::new(execution_block_generator),
previous_request: <_>::default(),
@@ -533,7 +534,7 @@ impl warp::reject::Reject for AuthError {}
pub struct Context<E: EthSpec> {
pub config: Config,
pub jwt_key: JwtKey,
pub log: Logger,
pub last_echo_request: Arc<RwLock<Option<Bytes>>>,
pub execution_block_generator: RwLock<ExecutionBlockGenerator<E>>,
pub preloaded_responses: Arc<Mutex<Vec<serde_json::Value>>>,
@@ -671,7 +672,6 @@ pub fn serve<E: EthSpec>(
shutdown: impl Future<Output = ()> + Send + Sync + 'static,
) -> Result<(SocketAddr, impl Future<Output = ()>), Error> {
let config = &ctx.config;
let log = ctx.log.clone();
let inner_ctx = ctx.clone();
let ctx_filter = warp::any().map(move || inner_ctx.clone());
@@ -751,9 +751,8 @@ pub fn serve<E: EthSpec>(
)?;
info!(
log,
"Metrics HTTP server started";
"listen_address" => listening_socket.to_string(),
listen_address = listening_socket.to_string(),
"Metrics HTTP server started"
);
Ok((listening_socket, server))