Skip to content

Commit b8b6683

Browse files
authored
feat: add metrics for sendRawTransactionSync (#4576)
## What ❔ - Add stage metrics for `eth_sendRawTransactionSync` ## Why ❔ - `eth_sendRawTransactionSync` is returning slower than sendTransaction + waitForTransactionReceipt so adding metrics to see what the cause is ## Is this a breaking change? - [ ] Yes - [x] No ## Operational changes <!-- Any config changes? Any new flags? Any changes to any scripts? --> <!-- Please add anything that non-Matter Labs entities running their own ZK Chain may need to know --> ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`.
1 parent 54dc61c commit b8b6683

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

core/node/api_server/src/web3/metrics.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,29 @@ pub(super) struct TxReceiptMetrics {
517517
#[vise::register]
518518
pub(super) static TX_RECEIPT_METRICS: vise::Global<TxReceiptMetrics> = vise::Global::new();
519519

520+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EncodeLabelValue, EncodeLabelSet)]
521+
#[metrics(label = "stage", rename_all = "snake_case")]
522+
pub(super) enum SendRawTxSyncStage {
523+
Submit,
524+
PollReceipt,
525+
Timeout,
526+
}
527+
528+
#[derive(Debug, Metrics)]
529+
#[metrics(prefix = "api_send_raw_tx_sync")]
530+
pub(super) struct SendRawTxSyncMetrics {
531+
/// Latency of each stage of `eth_sendRawTransactionSync`.
532+
#[metrics(buckets = Buckets::LATENCIES)]
533+
pub latency: Family<SendRawTxSyncStage, Histogram<Duration>>,
534+
/// Number of poll iterations until completion or timeout.
535+
#[metrics(buckets = Buckets::exponential(1.0..=256.0, 2.0))]
536+
pub polls: Family<SendRawTxSyncStage, Histogram<u64>>,
537+
}
538+
539+
#[vise::register]
540+
pub(super) static SEND_RAW_TX_SYNC_METRICS: vise::Global<SendRawTxSyncMetrics> =
541+
vise::Global::new();
542+
520543
#[cfg(test)]
521544
mod tests {
522545
use assert_matches::assert_matches;

core/node/api_server/src/web3/namespaces/eth.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ use crate::{
2323
tx_sender::BinarySearchKind,
2424
utils::open_readonly_transaction,
2525
web3::{
26-
backend_jsonrpsee::MethodTracer, namespaces::validate_gas_cap,
27-
receipts::fill_transaction_receipts, state::RpcState, TypedFilter,
26+
backend_jsonrpsee::MethodTracer,
27+
metrics::{SendRawTxSyncStage, SEND_RAW_TX_SYNC_METRICS},
28+
namespaces::validate_gas_cap,
29+
receipts::fill_transaction_receipts,
30+
state::RpcState,
31+
TypedFilter,
2832
},
2933
};
3034

@@ -713,7 +717,17 @@ impl EthNamespace {
713717
};
714718

715719
// Submit transaction and get hash
716-
let hash = self.send_raw_transaction_impl(tx_bytes).await?;
720+
let submit_latency = SEND_RAW_TX_SYNC_METRICS.latency[&SendRawTxSyncStage::Submit].start();
721+
let hash = match self.send_raw_transaction_impl(tx_bytes).await {
722+
Ok(hash) => {
723+
submit_latency.observe();
724+
hash
725+
}
726+
Err(err) => {
727+
submit_latency.observe();
728+
return Err(err);
729+
}
730+
};
717731

718732
// Poll for receipt at regular intervals
719733
let poll_interval = std::time::Duration::from_millis(
@@ -724,15 +738,25 @@ impl EthNamespace {
724738

725739
let deadline = tokio::time::sleep(std::time::Duration::from_millis(timeout_ms));
726740
tokio::pin!(deadline);
741+
let poll_latency =
742+
SEND_RAW_TX_SYNC_METRICS.latency[&SendRawTxSyncStage::PollReceipt].start();
743+
let timeout_latency =
744+
SEND_RAW_TX_SYNC_METRICS.latency[&SendRawTxSyncStage::Timeout].start();
745+
let mut polls = 0u64;
727746

728747
// Check immediately, then poll at intervals
729748
loop {
730749
tokio::select! {
731750
_ = &mut deadline => {
751+
timeout_latency.observe();
752+
SEND_RAW_TX_SYNC_METRICS.polls[&SendRawTxSyncStage::Timeout].observe(polls);
732753
return Err(Web3Error::TransactionTimeout(hash));
733754
}
734755
_ = interval.tick() => {
756+
polls += 1;
735757
if let Some(receipt) = self.get_transaction_receipt_impl(hash).await? {
758+
poll_latency.observe();
759+
SEND_RAW_TX_SYNC_METRICS.polls[&SendRawTxSyncStage::PollReceipt].observe(polls);
736760
return Ok(receipt);
737761
}
738762
// Continue waiting

0 commit comments

Comments
 (0)