-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Add metrics to gas price service #2635
Changes from 6 commits
9c3c9fe
2301bcd
a5ea886
620a0de
5fa145b
4c29fd6
8b8b4f2
89826f5
b15a224
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 |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use crate::global_registry; | ||
use prometheus_client::metrics::gauge::Gauge; | ||
use std::sync::OnceLock; | ||
|
||
#[derive(Debug)] | ||
pub struct GasPriceMetrics { | ||
pub real_gas_price: Gauge, | ||
pub exec_gas_price: Gauge, | ||
pub da_gas_price: Gauge, | ||
pub total_reward: Gauge, | ||
pub total_known_costs: Gauge, | ||
pub predicted_profit: Gauge, | ||
pub unrecorded_bytes: Gauge, | ||
pub latest_cost_per_byte: Gauge, | ||
pub recorded_height: Gauge, | ||
} | ||
|
||
impl Default for GasPriceMetrics { | ||
fn default() -> Self { | ||
let real_gas_price = Gauge::default(); | ||
let exec_gas_price = Gauge::default(); | ||
let da_gas_price = Gauge::default(); | ||
let total_reward = Gauge::default(); | ||
let total_known_costs = Gauge::default(); | ||
let predicted_profit = Gauge::default(); | ||
let unrecorded_bytes = Gauge::default(); | ||
let latest_cost_per_byte = Gauge::default(); | ||
let recorded_height = Gauge::default(); | ||
|
||
let metrics = GasPriceMetrics { | ||
real_gas_price, | ||
exec_gas_price, | ||
da_gas_price, | ||
total_reward, | ||
total_known_costs, | ||
predicted_profit, | ||
unrecorded_bytes, | ||
latest_cost_per_byte, | ||
recorded_height, | ||
}; | ||
|
||
let mut registry = global_registry().registry.lock(); | ||
registry.register( | ||
"gas_price_service_real_gas_price", | ||
"The real gas price used on the most recent block", | ||
metrics.real_gas_price.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_exec_gas_price", | ||
"The requested execution gas price for the next block", | ||
metrics.exec_gas_price.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_da_gas_price", | ||
"The requested data availability gas price for the next block", | ||
metrics.da_gas_price.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_total_reward", | ||
"The total reward received from DA gas price fees", | ||
metrics.total_reward.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_total_known_costs", | ||
"The total known costs for committing L2 blocks to DA", | ||
metrics.total_known_costs.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_predicted_profit", | ||
"The predicted profit based on the rewards, known costs, and predicted costs from price per byte", | ||
metrics.predicted_profit.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_unrecorded_bytes", | ||
"The total bytes of all L2 blocks waiting to be recorded on DA", | ||
metrics.unrecorded_bytes.clone(), | ||
); | ||
registry.register( | ||
"gas_price_service_latest_cost_per_byte", | ||
"The latest cost per byte to record L2 blocks on DA", | ||
metrics.latest_cost_per_byte.clone(), | ||
); | ||
|
||
registry.register( | ||
"gas_price_service_recorded_height", | ||
"The height of the latest L2 block recorded on DA", | ||
metrics.recorded_height.clone(), | ||
); | ||
|
||
metrics | ||
} | ||
} | ||
|
||
static GAS_PRICE_METRICS: OnceLock<GasPriceMetrics> = OnceLock::new(); | ||
|
||
pub fn gas_price_metrics() -> &'static GasPriceMetrics { | ||
GAS_PRICE_METRICS.get_or_init(GasPriceMetrics::default) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ use crate::{ | |
}; | ||
use anyhow::anyhow; | ||
use async_trait::async_trait; | ||
use fuel_core_metrics::gas_price_metrics::gas_price_metrics; | ||
use fuel_core_services::{ | ||
RunnableService, | ||
RunnableTask, | ||
|
@@ -48,7 +49,10 @@ use fuel_core_services::{ | |
StateWatcher, | ||
TaskNextAction, | ||
}; | ||
use fuel_core_types::fuel_types::BlockHeight; | ||
use fuel_core_types::{ | ||
fuel_types::BlockHeight, | ||
services::txpool::Metadata, | ||
}; | ||
use fuel_gas_price_algorithm::{ | ||
v0::AlgorithmUpdaterV0, | ||
v1::{ | ||
|
@@ -251,17 +255,19 @@ where | |
block_gas_capacity: u64, | ||
block_bytes: u64, | ||
block_fees: u64, | ||
gas_price: u64, | ||
) -> anyhow::Result<()> { | ||
let capacity = Self::validate_block_gas_capacity(block_gas_capacity)?; | ||
let mut storage_tx = self.storage_tx_provider.begin_transaction()?; | ||
let mut new_recorded_height = match storage_tx | ||
let (old_recorded_height, mut new_recorded_height) = match storage_tx | ||
.get_recorded_height() | ||
.map_err(|err| anyhow!(err))? | ||
{ | ||
Some(_) => None, | ||
Some(old) => (Some(old), None), | ||
None => { | ||
// Sets it on first run | ||
self.initial_recorded_height.take() | ||
let initial = self.initial_recorded_height.take(); | ||
(initial, initial) | ||
} | ||
}; | ||
|
||
|
@@ -303,12 +309,61 @@ where | |
AtomicStorage::commit_transaction(storage_tx)?; | ||
let new_algo = self.algorithm_updater.algorithm(); | ||
tracing::debug!("Updating gas price: {}", &new_algo.calculate()); | ||
self.shared_algo.update(new_algo); | ||
self.shared_algo.update(new_algo).await; | ||
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. why await here? 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. I'm confused by the error: pub async fn update(&mut self, new_algo: A) {
let mut write_lock = self.0.write();
*write_lock = new_algo;
} 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. nvm need to pull |
||
let best_recorded_height = new_recorded_height.or(old_recorded_height); | ||
Self::record_metrics(&metadata, gas_price, best_recorded_height); | ||
// Clear the buffer after committing changes | ||
self.da_block_costs_buffer.clear(); | ||
Ok(()) | ||
} | ||
|
||
fn record_metrics( | ||
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. we should conditionally export metrics, see description of #2310 for reference |
||
metadata: &UpdaterMetadata, | ||
gas_price: u64, | ||
recorded_height: Option<BlockHeight>, | ||
) { | ||
if let UpdaterMetadata::V1(v1_metadata) = metadata { | ||
let metrics = gas_price_metrics(); | ||
let real_gas_price_i64 = gas_price.try_into().unwrap_or(i64::MAX); | ||
let exec_gas_price_i64 = v1_metadata | ||
.new_exec_gas_price() | ||
.try_into() | ||
.unwrap_or(i64::MAX); | ||
Comment on lines
+332
to
+335
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. Nit: I generally prefer explicit conversions for readability. I.e. I'm also uncertain if it makes sense to report |
||
let da_gas_price_i64 = v1_metadata | ||
.new_da_gas_price() | ||
.try_into() | ||
.unwrap_or(i64::MAX); | ||
let total_reward_i64 = | ||
v1_metadata.total_da_rewards.try_into().unwrap_or(i64::MAX); | ||
let total_known_costs_i64 = v1_metadata | ||
.latest_known_total_da_cost | ||
.try_into() | ||
.unwrap_or(i64::MAX); | ||
let predicted_profit_i64 = | ||
v1_metadata.last_profit.try_into().unwrap_or(i64::MAX); | ||
let unrecorded_bytes_i64 = v1_metadata | ||
.unrecorded_block_bytes | ||
.try_into() | ||
.unwrap_or(i64::MAX); | ||
let latest_cost_per_byte_i64 = v1_metadata | ||
.latest_da_cost_per_byte | ||
.try_into() | ||
.unwrap_or(i64::MAX); | ||
metrics.real_gas_price.set(real_gas_price_i64); | ||
metrics.exec_gas_price.set(exec_gas_price_i64); | ||
metrics.da_gas_price.set(da_gas_price_i64); | ||
metrics.total_reward.set(total_reward_i64); | ||
metrics.total_known_costs.set(total_known_costs_i64); | ||
metrics.predicted_profit.set(predicted_profit_i64); | ||
metrics.unrecorded_bytes.set(unrecorded_bytes_i64); | ||
metrics.latest_cost_per_byte.set(latest_cost_per_byte_i64); | ||
if let Some(height) = recorded_height { | ||
let inner: u32 = height.into(); | ||
metrics.recorded_height.set(inner.into()); | ||
} | ||
} | ||
} | ||
|
||
async fn apply_block_info_to_gas_algorithm( | ||
&mut self, | ||
l2_block: BlockInfo, | ||
|
@@ -328,6 +383,7 @@ where | |
block_gas_capacity, | ||
block_bytes, | ||
block_fees, | ||
gas_price, | ||
.. | ||
} => { | ||
self.handle_normal_block( | ||
|
@@ -336,6 +392,7 @@ where | |
block_gas_capacity, | ||
block_bytes, | ||
block_fees, | ||
gas_price, | ||
) | ||
.await?; | ||
} | ||
|
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.
do we need this change?
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.
Maybe
(None, initial)
would be clearer.