From 55b5f9c28fa7db1dbd040848cf516325462b2f93 Mon Sep 17 00:00:00 2001 From: Alex Miao Date: Wed, 4 Oct 2023 22:24:02 -0700 Subject: [PATCH] feat(builder): add bundle gas stats to metrics --- crates/builder/Cargo.toml | 1 + crates/builder/src/bundle_sender.rs | 14 ++++++++++ crates/builder/src/transaction_tracker.rs | 34 ++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/crates/builder/Cargo.toml b/crates/builder/Cargo.toml index 872db3942..833a6be58 100644 --- a/crates/builder/Cargo.toml +++ b/crates/builder/Cargo.toml @@ -48,6 +48,7 @@ mockall = {workspace = true, optional = true } mockall.workspace = true rundler-pool = { path = "../pool", features = ["test-utils"] } rundler-provider = { path = "../provider", features = ["test-utils"] } +rundler-sim = { path = "../sim", features = ["test-utils"] } [build-dependencies] tonic-build.workspace = true diff --git a/crates/builder/src/bundle_sender.rs b/crates/builder/src/bundle_sender.rs index f1864fdc3..3c364ae88 100644 --- a/crates/builder/src/bundle_sender.rs +++ b/crates/builder/src/bundle_sender.rs @@ -268,9 +268,12 @@ where tx_hash, block_number, attempt_number, + gas_limit, + gas_used, .. } => { BuilderMetrics::increment_bundle_txns_success(self.builder_index); + BuilderMetrics::set_bundle_gas_stats(gas_limit, gas_used); if attempt_number == 0 { info!("Bundle with hash {tx_hash:?} landed in block {block_number}"); } else { @@ -381,6 +384,8 @@ where nonce, block_number, attempt_number, + gas_limit, + gas_used, } => { self.emit(BuilderEvent::transaction_mined( self.builder_index, @@ -389,6 +394,7 @@ where block_number, )); BuilderMetrics::increment_bundle_txns_success(self.builder_index); + BuilderMetrics::set_bundle_gas_stats(gas_limit, gas_used); return Ok(SendBundleResult::Success { block_number, attempt_number, @@ -551,6 +557,14 @@ impl BuilderMetrics { metrics::increment_counter!("builder_bundle_fee_increases", "builder_index" => builder_index.to_string()); } + fn set_bundle_gas_stats(gas_limit: U256, gas_used: U256) { + let gas_limit = gas_limit.as_u128() as f64; + let gas_used = gas_used.as_u128() as f64; + metrics::gauge!("builder_bundle_gas_limit", gas_limit); + metrics::gauge!("builder_bundle_gas_used", gas_used); + metrics::gauge!("builder_bundle_gas_utilization", gas_limit / gas_used); + } + fn set_current_fees(fees: &GasFees) { metrics::gauge!( "builder_current_max_fee", diff --git a/crates/builder/src/transaction_tracker.rs b/crates/builder/src/transaction_tracker.rs index 2a7ad0d75..9e5e837ac 100644 --- a/crates/builder/src/transaction_tracker.rs +++ b/crates/builder/src/transaction_tracker.rs @@ -74,6 +74,8 @@ pub(crate) enum TrackerUpdate { nonce: U256, block_number: u64, attempt_number: u64, + gas_limit: U256, + gas_used: U256, }, StillPendingAfterWait, LatestTxDropped { @@ -288,11 +290,14 @@ where .await .context("tracker should check transaction status when the nonce changes")?; if let TxStatus::Mined { block_number } = status { + let (gas_limit, gas_used) = self.get_mined_tx_gas_info(tx.tx_hash).await?; out = TrackerUpdate::Mined { tx_hash: tx.tx_hash, nonce: self.nonce, block_number, attempt_number: tx.attempt_number, + gas_limit, + gas_used, }; break; } @@ -321,11 +326,14 @@ where TxStatus::Mined { block_number } => { let nonce = self.nonce; self.set_nonce_and_clear_state(nonce + 1); + let (gas_limit, gas_used) = self.get_mined_tx_gas_info(last_tx.tx_hash).await?; Some(TrackerUpdate::Mined { tx_hash: last_tx.tx_hash, nonce, block_number, attempt_number: last_tx.attempt_number, + gas_limit, + gas_used, }) } TxStatus::Dropped => { @@ -379,6 +387,14 @@ where TransactionTrackerMetrics::set_current_fees(None); } } + + async fn get_mined_tx_gas_info(&self, tx_hash: H256) -> anyhow::Result<(U256, U256)> { + let (tx, tx_receipt) = tokio::try_join!( + self.provider.get_transaction(tx_hash), + self.provider.get_transaction_receipt(tx_hash), + )?; + Ok((tx.unwrap().gas, tx_receipt.unwrap().gas_used.unwrap())) + } } struct TransactionTrackerMetrics {} @@ -417,7 +433,7 @@ impl TransactionTrackerMetrics { mod tests { use std::sync::Arc; - use ethers::types::{Address, Eip1559TransactionRequest}; + use ethers::types::{Address, Eip1559TransactionRequest, Transaction, TransactionReceipt}; use mockall::Sequence; use rundler_provider::MockProvider; @@ -733,6 +749,22 @@ mod tests { .returning(move || Ok(1)) .times(1); + provider.expect_get_transaction().returning(|_: H256| { + Ok(Some(Transaction { + gas: U256::from(0), + ..Default::default() + })) + }); + + provider + .expect_get_transaction_receipt() + .returning(|_: H256| { + Ok(Some(TransactionReceipt { + gas_used: Some(U256::from(0)), + ..Default::default() + })) + }); + let tracker = create_tracker(sender, provider).await; let tx = Eip1559TransactionRequest::new().nonce(0);