-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: collect withdrawal volumes metrics #200
Changes from 8 commits
7d1e23c
84b3062
71873c2
9e25578
8e763d8
bad1d3a
4a18c77
4e9a2ee
78657fd
8873270
c1d16ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,4 +13,5 @@ members = [ | |
"tx-sender", | ||
"vlog", | ||
"watcher", | ||
"withdrawals-meterer" | ||
] |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "withdrawals-meterer" | ||
version = "0.1.11" | ||
authors = ["The Matter Labs Team <[email protected]>"] | ||
homepage = "https://zksync.io/" | ||
license = "MIT OR Apache-2.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
ethers = "2.0.10" | ||
lazy_static = "1.4.0" | ||
metrics = "0.21.1" | ||
tokio = "1.32.0" | ||
|
||
client = { path = "../client" } | ||
sqlx = { version = "0.7", features = ["postgres", "runtime-tokio-rustls"] } | ||
storage = { path = "../storage" } | ||
vlog = { path = "../vlog" } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#![deny(unused_crate_dependencies)] | ||
#![warn(missing_docs)] | ||
#![warn(unused_extern_crates)] | ||
#![warn(unused_imports)] | ||
|
||
//! A utility crate that meters withdrawals amounts. | ||
|
||
use std::{collections::HashMap, str::FromStr, sync::Arc}; | ||
|
||
use client::ETH_TOKEN_ADDRESS; | ||
use ethers::types::Address; | ||
use lazy_static::lazy_static; | ||
use sqlx::PgPool; | ||
use storage::StoredWithdrawal; | ||
use tokio::sync::RwLock; | ||
|
||
lazy_static! { | ||
static ref TOKEN_DECIMALS: Arc<RwLock<HashMap<Address, u32>>> = { | ||
let mut map = HashMap::new(); | ||
map.insert(ETH_TOKEN_ADDRESS, 18_u32); | ||
|
||
Arc::new(RwLock::new(map)) | ||
}; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on the number of tokens, seems it's better to create a struct There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. separeted |
||
/// Given a set of withdrawal ids meter all of them to a metric | ||
/// with a given name. | ||
pub async fn meter_finalized_withdrawals_storage( | ||
pool: &PgPool, | ||
ids: Vec<i64>, | ||
metric_name: &'static str, | ||
) -> Result<(), storage::Error> { | ||
let withdrawals = storage::get_withdrawals(pool, &ids).await?; | ||
|
||
meter_finalized_withdrawals(pool, &withdrawals, metric_name).await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Given a set of [`StoredWithdrawal`], meter all of them to a | ||
/// metric with a given name. | ||
/// | ||
/// This function returns only storage error, all formatting, etc | ||
/// errors will be just logged. | ||
pub async fn meter_finalized_withdrawals( | ||
pool: &PgPool, | ||
withdrawals: &[StoredWithdrawal], | ||
metric_name: &'static str, | ||
) -> Result<(), storage::Error> { | ||
for w in withdrawals { | ||
let guard = TOKEN_DECIMALS.read().await; | ||
let decimals = guard.get(&w.event.token).copied(); | ||
drop(guard); | ||
|
||
let decimals = match decimals { | ||
None => { | ||
let Some(decimals) = storage::token_decimals(pool, w.event.token).await? else { | ||
vlog::error!("Received withdrawal from unknown token {:?}", w.event.token); | ||
continue; | ||
}; | ||
|
||
TOKEN_DECIMALS.write().await.insert(w.event.token, decimals); | ||
decimals | ||
} | ||
Some(decimals) => decimals, | ||
}; | ||
|
||
let formatted = match ethers::utils::format_units(w.event.amount, decimals) { | ||
Ok(f) => f, | ||
Err(e) => { | ||
vlog::error!("failed to format units: {e}"); | ||
continue; | ||
} | ||
}; | ||
|
||
let formatted_f64 = match f64::from_str(&formatted) { | ||
Ok(f) => f, | ||
Err(e) => { | ||
vlog::error!("failed to format units: {e}"); | ||
continue; | ||
} | ||
}; | ||
|
||
metrics::increment_gauge!( | ||
metric_name, | ||
formatted_f64, | ||
"token" => format!("{:?}", w.event.token) | ||
) | ||
} | ||
|
||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's supposed to be
select id from unnest( $1 :: bigint[]))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed