Skip to content

Commit 0751bf8

Browse files
committed
trace: add duration_ms, block_hash, and tx_hash to spans
Apply review feedback: add duration_ms timing to all instrumented spans, add block_hash to ensure_well_formed_payload (recorded after computation), and add tx_hash to the execute_tx error warn log.
1 parent 03619b3 commit 0751bf8

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

crates/node/src/builder.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ where
6666
parent_hash = %attributes.parent_hash,
6767
tx_count = attributes.transactions.len(),
6868
gas_limit = ?attributes.gas_limit,
69+
duration_ms = tracing::field::Empty,
6970
))]
7071
pub async fn build_payload(
7172
&self,
7273
attributes: EvolvePayloadAttributes,
7374
) -> Result<SealedBlock<ev_primitives::Block>, PayloadBuilderError> {
75+
let _start = std::time::Instant::now();
76+
7477
// Validate attributes
7578
attributes
7679
.validate()
@@ -162,7 +165,7 @@ where
162165
debug!(gas_used, "transaction executed successfully");
163166
}
164167
Err(err) => {
165-
tracing::warn!(error = ?err, "transaction execution failed");
168+
tracing::warn!(error = ?err, tx_hash = %tx.tx_hash(), "transaction execution failed");
166169
}
167170
}
168171
}
@@ -179,6 +182,8 @@ where
179182

180183
let sealed_block = block.sealed_block().clone();
181184

185+
tracing::Span::current().record("duration_ms", _start.elapsed().as_millis() as u64);
186+
182187
info!(
183188
block_number = sealed_block.number,
184189
block_hash = ?sealed_block.hash(),
@@ -297,6 +302,7 @@ mod tests {
297302
assert!(span.has_field("parent_hash"), "span missing parent_hash field");
298303
assert!(span.has_field("tx_count"), "span missing tx_count field");
299304
assert!(span.has_field("gas_limit"), "span missing gas_limit field");
305+
assert!(span.has_field("duration_ms"), "span missing duration_ms field");
300306
}
301307

302308
#[tokio::test]

crates/node/src/payload_service.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ where
134134
#[instrument(skip(self, args), fields(
135135
tx_count = args.config.attributes.transactions.len(),
136136
payload_id = %args.config.attributes.payload_id(),
137+
duration_ms = tracing::field::Empty,
137138
))]
138139
fn try_build(
139140
&self,
140141
args: BuildArguments<Self::Attributes, Self::BuiltPayload>,
141142
) -> Result<BuildOutcome<Self::BuiltPayload>, PayloadBuilderError> {
143+
let _start = std::time::Instant::now();
142144
let BuildArguments {
143145
cached_reads: _,
144146
config,
@@ -204,6 +206,8 @@ where
204206
None, // No blob sidecar for evolve.
205207
);
206208

209+
tracing::Span::current().record("duration_ms", _start.elapsed().as_millis() as u64);
210+
207211
Ok(BuildOutcome::Better {
208212
payload: built_payload,
209213
cached_reads: CachedReads::default(),
@@ -371,5 +375,6 @@ mod tests {
371375

372376
assert!(span.has_field("tx_count"), "span missing tx_count field");
373377
assert!(span.has_field("payload_id"), "span missing payload_id field");
378+
assert!(span.has_field("duration_ms"), "span missing duration_ms field");
374379
}
375380
}

crates/node/src/test_utils.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,22 @@ where
9898

9999
self.spans.lock().unwrap().push(record);
100100
}
101+
102+
fn on_record(
103+
&self,
104+
id: &tracing::span::Id,
105+
values: &tracing::span::Record<'_>,
106+
ctx: Context<'_, S>,
107+
) {
108+
let mut collector = FieldCollector::new();
109+
values.record(&mut collector);
110+
111+
if let Some(span_ref) = ctx.span(id) {
112+
let name = span_ref.name().to_string();
113+
let mut spans = self.spans.lock().unwrap();
114+
if let Some(record) = spans.iter_mut().find(|s| s.name == name) {
115+
record.fields.extend(collector.fields);
116+
}
117+
}
118+
}
101119
}

crates/node/src/txpool.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,18 +480,20 @@ where
480480
#[instrument(skip(self, transaction), fields(
481481
origin = ?origin,
482482
tx_hash = %transaction.hash(),
483+
duration_ms = tracing::field::Empty,
483484
))]
484485
async fn validate_transaction(
485486
&self,
486487
origin: TransactionOrigin,
487488
transaction: <Self as TransactionValidator>::Transaction,
488489
) -> TransactionValidationOutcome<Self::Transaction> {
490+
let _start = std::time::Instant::now();
489491
let mut state = None;
490492
let outcome = self
491493
.inner
492494
.validate_one_with_state(origin, transaction, &mut state);
493495

494-
match outcome {
496+
let result = match outcome {
495497
TransactionValidationOutcome::Valid {
496498
balance,
497499
state_nonce,
@@ -513,7 +515,10 @@ where
513515
}
514516
},
515517
other => other,
516-
}
518+
};
519+
520+
tracing::Span::current().record("duration_ms", _start.elapsed().as_millis() as u64);
521+
result
517522
}
518523
}
519524

@@ -786,6 +791,7 @@ mod tests {
786791

787792
assert!(span.has_field("origin"), "span missing origin field");
788793
assert!(span.has_field("tx_hash"), "span missing tx_hash field");
794+
assert!(span.has_field("duration_ms"), "span missing duration_ms field");
789795
}
790796

791797
/// Tests pool-level deploy allowlist rejection for `EvNode` CREATE when caller not allowlisted.

crates/node/src/validator.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,20 @@ impl PayloadValidator<EvolveEngineTypes> for EvolveEngineValidator {
6060
#[instrument(skip(self, payload), fields(
6161
block_number = payload.payload.block_number(),
6262
tx_count = payload.payload.transactions().len(),
63+
block_hash = tracing::field::Empty,
64+
duration_ms = tracing::field::Empty,
6365
))]
6466
fn ensure_well_formed_payload(
6567
&self,
6668
payload: ExecutionData,
6769
) -> Result<RecoveredBlock<Self::Block>, NewPayloadError> {
70+
let _start = std::time::Instant::now();
6871
// Use inner validator but with custom evolve handling.
6972
match self.inner.ensure_well_formed_payload(payload.clone()) {
7073
Ok(sealed_block) => {
74+
let span = tracing::Span::current();
75+
span.record("block_hash", tracing::field::display(sealed_block.hash()));
76+
span.record("duration_ms", _start.elapsed().as_millis() as u64);
7177
info!("payload validation succeeded");
7278
let ev_block = convert_sealed_block(sealed_block);
7379
ev_block
@@ -94,6 +100,9 @@ impl PayloadValidator<EvolveEngineTypes> for EvolveEngineValidator {
94100
info!(error = ?err, "bypassing validation error for ev-reth");
95101
// For evolve, we trust the payload builder - parse the block with EvNode support.
96102
let ev_block = parse_evolve_payload(payload)?;
103+
let span = tracing::Span::current();
104+
span.record("block_hash", tracing::field::display(ev_block.hash()));
105+
span.record("duration_ms", _start.elapsed().as_millis() as u64);
97106
ev_block
98107
.try_recover()
99108
.map_err(|e| NewPayloadError::Other(e.into()))
@@ -344,6 +353,8 @@ mod tests {
344353

345354
assert!(span.has_field("block_number"), "span missing block_number field");
346355
assert!(span.has_field("tx_count"), "span missing tx_count field");
356+
assert!(span.has_field("block_hash"), "span missing block_hash field");
357+
assert!(span.has_field("duration_ms"), "span missing duration_ms field");
347358
}
348359

349360
/// Verifies that `is_unknown_tx_type_error` correctly identifies decode errors

0 commit comments

Comments
 (0)