Skip to content

Commit 5b863f5

Browse files
bxpanaDeniallugo
authored andcommitted
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 819f714 commit 5b863f5

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

@@ -721,7 +725,17 @@ impl EthNamespace {
721725
};
722726

723727
// Submit transaction and get hash
724-
let hash = self.send_raw_transaction_impl(tx_bytes).await?;
728+
let submit_latency = SEND_RAW_TX_SYNC_METRICS.latency[&SendRawTxSyncStage::Submit].start();
729+
let hash = match self.send_raw_transaction_impl(tx_bytes).await {
730+
Ok(hash) => {
731+
submit_latency.observe();
732+
hash
733+
}
734+
Err(err) => {
735+
submit_latency.observe();
736+
return Err(err);
737+
}
738+
};
725739

726740
// Poll for receipt at regular intervals
727741
let poll_interval = std::time::Duration::from_millis(
@@ -732,15 +746,25 @@ impl EthNamespace {
732746

733747
let deadline = tokio::time::sleep(std::time::Duration::from_millis(timeout_ms));
734748
tokio::pin!(deadline);
749+
let poll_latency =
750+
SEND_RAW_TX_SYNC_METRICS.latency[&SendRawTxSyncStage::PollReceipt].start();
751+
let timeout_latency =
752+
SEND_RAW_TX_SYNC_METRICS.latency[&SendRawTxSyncStage::Timeout].start();
753+
let mut polls = 0u64;
735754

736755
// Check immediately, then poll at intervals
737756
loop {
738757
tokio::select! {
739758
_ = &mut deadline => {
759+
timeout_latency.observe();
760+
SEND_RAW_TX_SYNC_METRICS.polls[&SendRawTxSyncStage::Timeout].observe(polls);
740761
return Err(Web3Error::TransactionTimeout(hash));
741762
}
742763
_ = interval.tick() => {
764+
polls += 1;
743765
if let Some(receipt) = self.get_transaction_receipt_impl(hash).await? {
766+
poll_latency.observe();
767+
SEND_RAW_TX_SYNC_METRICS.polls[&SendRawTxSyncStage::PollReceipt].observe(polls);
744768
return Ok(receipt);
745769
}
746770
// Continue waiting

0 commit comments

Comments
 (0)