Pārlūkot izejas kodu

feat(fortuna): add metric to track accrued pyth fees (#2448)

* feat(fortuna): add metric to track accrued pyth fees

Co-Authored-By: Jayant Krishnamurthy <jayant@dourolabs.xyz>

* refactor(fortuna): use ChainIdLabel as key for accrued_pyth_fees metric

Co-Authored-By: Jayant Krishnamurthy <jayant@dourolabs.xyz>

* chore(fortuna): bump patch version to 7.4.4

Co-Authored-By: Jayant Krishnamurthy <jayant@dourolabs.xyz>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Jayant Krishnamurthy <jayant@dourolabs.xyz>
devin-ai-integration[bot] 8 mēneši atpakaļ
vecāks
revīzija
5d2ef61e7b

+ 1 - 1
apps/fortuna/Cargo.lock

@@ -1554,7 +1554,7 @@ dependencies = [
 
 [[package]]
 name = "fortuna"
-version = "7.4.3"
+version = "7.4.4"
 dependencies = [
  "anyhow",
  "axum",

+ 1 - 1
apps/fortuna/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "fortuna"
-version = "7.4.3"
+version = "7.4.4"
 edition = "2021"
 
 [lib]

+ 9 - 0
apps/fortuna/src/keeper.rs

@@ -11,6 +11,7 @@ use {
         keeper::commitment::update_commitments_loop,
         keeper::fee::adjust_fee_wrapper,
         keeper::fee::withdraw_fees_wrapper,
+        keeper::track::track_accrued_pyth_fees,
         keeper::track::track_balance,
         keeper::track::track_provider,
     },
@@ -208,6 +209,14 @@ pub async fn run_keeper_threads(
                     )
                     .in_current_span(),
                 );
+                spawn(
+                    track_accrued_pyth_fees(
+                        chain_id.clone(),
+                        contract.clone(),
+                        keeper_metrics.clone(),
+                    )
+                    .in_current_span(),
+                );
 
                 time::sleep(TRACK_INTERVAL).await;
             }

+ 23 - 0
apps/fortuna/src/keeper/keeper_metrics.rs

@@ -16,6 +16,11 @@ pub struct AccountLabel {
     pub address: String,
 }
 
+#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
+pub struct ChainIdLabel {
+    pub chain_id: String,
+}
+
 pub struct KeeperMetrics {
     pub current_sequence_number: Family<AccountLabel, Gauge>,
     pub end_sequence_number: Family<AccountLabel, Gauge>,
@@ -36,6 +41,7 @@ pub struct KeeperMetrics {
     pub final_gas_multiplier: Family<AccountLabel, Histogram>,
     pub final_fee_multiplier: Family<AccountLabel, Histogram>,
     pub gas_price_estimate: Family<AccountLabel, Gauge<f64, AtomicU64>>,
+    pub accrued_pyth_fees: Family<ChainIdLabel, Gauge<f64, AtomicU64>>,
 }
 
 impl Default for KeeperMetrics {
@@ -76,6 +82,7 @@ impl Default for KeeperMetrics {
                 Histogram::new(vec![100.0, 110.0, 120.0, 140.0, 160.0, 180.0, 200.0].into_iter())
             }),
             gas_price_estimate: Family::default(),
+            accrued_pyth_fees: Family::default(),
         }
     }
 }
@@ -202,9 +209,25 @@ impl KeeperMetrics {
             keeper_metrics.gas_price_estimate.clone(),
         );
 
+        writable_registry.register(
+            "accrued_pyth_fees",
+            "Accrued Pyth fees on the contract",
+            keeper_metrics.accrued_pyth_fees.clone(),
+        );
+
         // *Important*: When adding a new metric:
         // 1. Register it above using `writable_registry.register(...)`
         // 2. Add a get_or_create call in the loop below to initialize it for each chain/provider pair
+
+        // Initialize accrued_pyth_fees for each chain_id
+        for (chain_id, _) in chain_labels.iter() {
+            let _ = keeper_metrics
+                .accrued_pyth_fees
+                .get_or_create(&ChainIdLabel {
+                    chain_id: chain_id.clone(),
+                });
+        }
+
         for (chain_id, provider_address) in chain_labels {
             let account_label = AccountLabel {
                 chain_id,

+ 29 - 1
apps/fortuna/src/keeper/track.rs

@@ -1,5 +1,5 @@
 use {
-    super::keeper_metrics::{AccountLabel, KeeperMetrics},
+    super::keeper_metrics::{AccountLabel, ChainIdLabel, KeeperMetrics},
     crate::{
         api::ChainId, chain::ethereum::InstrumentedPythContract,
         eth_utils::traced_client::TracedClient,
@@ -100,3 +100,31 @@ pub async fn track_provider(
         })
         .set(end_sequence_number as i64);
 }
+
+/// tracks the accrued pyth fees on the given chain
+/// if there is an error the function will just return
+#[tracing::instrument(skip_all)]
+pub async fn track_accrued_pyth_fees(
+    chain_id: ChainId,
+    contract: InstrumentedPythContract,
+    metrics: Arc<KeeperMetrics>,
+) {
+    let accrued_pyth_fees = match contract.get_accrued_pyth_fees().call().await {
+        Ok(fees) => fees,
+        Err(e) => {
+            tracing::error!("Error while getting accrued pyth fees. error: {:?}", e);
+            return;
+        }
+    };
+
+    // The f64 conversion is made to be able to serve metrics with the constraints of Prometheus.
+    // The fee is in wei, so we divide by 1e18 to convert it to eth.
+    let accrued_pyth_fees = accrued_pyth_fees as f64 / 1e18;
+
+    metrics
+        .accrued_pyth_fees
+        .get_or_create(&ChainIdLabel {
+            chain_id: chain_id.clone(),
+        })
+        .set(accrued_pyth_fees);
+}