Skip to content

Commit 602411d

Browse files
ShahakShamaclaude
andauthored
apollo_l1_gas_price: hold strk_to_usd oracle client + strk_to_usd_rate (#14158)
Goal: PR 2 of 6 in the stack moving the STRK/USD oracle from the ad-hoc wiring in SequencerConsensusContext into L1GasPriceProvider. This commit adds the field and inherent method on the provider but nothing calls it yet — the seam is established without behavior change. Change summary: - `L1GasPriceProvider` gains a second `Arc<dyn ExchangeRateOracleClientTrait>` field (`strk_to_usd_oracle_client`), positionally after the existing `eth_to_strk_oracle_client`. - `new` takes a second oracle client parameter. - `new_with_oracle` reads `config.strk_to_usd_oracle_config` (added in the previous commit on this stack) and constructs the client. - New inherent method `strk_to_usd_rate(timestamp)` mirrors the existing `eth_to_fri_rate`. - Unit tests in `l1_gas_price_provider_test.rs` updated to pass a second mock to the constructor. Decision points: - Positional constructor argument over a builder. The struct has two oracle clients now; if a third lands later, builder pattern is the right move. For two, positional is fine. - Same `ExchangeRateOracleClientError` propagation via the existing `L1GasPriceProviderError::ExchangeRateOracleClientError` variant. No new error variant needed — the two oracles are semantically identical, only differ by URL. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 26ffb18 commit 602411d

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

crates/apollo_l1_gas_price/src/l1_gas_price_provider.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::metrics::{
2323
L1_DATA_GAS_PRICE_LATEST_MEAN_VALUE,
2424
L1_GAS_PRICE_LATEST_MEAN_VALUE,
2525
L1_GAS_PRICE_PROVIDER_INSUFFICIENT_HISTORY,
26+
STRK_TO_USD_ORACLE_METRICS,
2627
};
2728

2829
#[cfg(test)]
@@ -60,22 +61,33 @@ pub struct L1GasPriceProvider {
6061
// If received data before initialization (is None), it means the scraper has restarted.
6162
price_samples_by_block: Option<RingBuffer<GasPriceData>>,
6263
eth_to_strk_oracle_client: Arc<dyn ExchangeRateOracleClientTrait>,
64+
strk_to_usd_oracle_client: Arc<dyn ExchangeRateOracleClientTrait>,
6365
}
6466

6567
impl L1GasPriceProvider {
6668
pub fn new(
6769
config: L1GasPriceProviderConfig,
6870
eth_to_strk_oracle_client: Arc<dyn ExchangeRateOracleClientTrait>,
71+
strk_to_usd_oracle_client: Arc<dyn ExchangeRateOracleClientTrait>,
6972
) -> Self {
70-
Self { config, price_samples_by_block: None, eth_to_strk_oracle_client }
73+
Self {
74+
config,
75+
price_samples_by_block: None,
76+
eth_to_strk_oracle_client,
77+
strk_to_usd_oracle_client,
78+
}
7179
}
7280

7381
pub fn new_with_oracle(config: L1GasPriceProviderConfig) -> Self {
7482
let eth_to_strk_oracle_client = ExchangeRateOracleClient::new(
7583
config.eth_to_strk_oracle_config.clone(),
7684
ETH_TO_STRK_ORACLE_METRICS,
7785
);
78-
Self::new(config, Arc::new(eth_to_strk_oracle_client))
86+
let strk_to_usd_oracle_client = ExchangeRateOracleClient::new(
87+
config.strk_to_usd_oracle_config.clone(),
88+
STRK_TO_USD_ORACLE_METRICS,
89+
);
90+
Self::new(config, Arc::new(eth_to_strk_oracle_client), Arc::new(strk_to_usd_oracle_client))
7991
}
8092

8193
pub fn initialize(&mut self) -> L1GasPriceProviderResult<()> {
@@ -193,6 +205,13 @@ impl L1GasPriceProvider {
193205
.await
194206
.map_err(L1GasPriceProviderError::ExchangeRateOracleClientError)
195207
}
208+
209+
pub async fn strk_to_usd_rate(&self, timestamp: u64) -> L1GasPriceProviderResult<u128> {
210+
self.strk_to_usd_oracle_client
211+
.fetch_rate(timestamp)
212+
.await
213+
.map_err(L1GasPriceProviderError::ExchangeRateOracleClientError)
214+
}
196215
}
197216

198217
#[async_trait]

crates/apollo_l1_gas_price/src/l1_gas_price_provider_test.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ use crate::l1_gas_price_provider::{L1GasPriceProvider, L1GasPriceProviderError};
1111
// Returns the provider, a vector of block prices to compare with, and the timestamp of block[3].
1212
fn make_provider() -> (L1GasPriceProvider, Vec<PriceInfo>, u64) {
1313
let eth_to_strk_oracle_client = Arc::new(MockExchangeRateOracleClientTrait::new());
14+
let strk_to_usd_oracle_client = Arc::new(MockExchangeRateOracleClientTrait::new());
1415
let mut provider = L1GasPriceProvider::new(
1516
L1GasPriceProviderConfig { number_of_blocks_for_mean: 3, ..Default::default() },
1617
eth_to_strk_oracle_client,
18+
strk_to_usd_oracle_client,
1719
);
1820
provider.initialize().unwrap();
1921
let mut prices = Vec::new();
@@ -117,9 +119,11 @@ fn gas_price_provider_timestamp_changes_mean() {
117119
#[test]
118120
fn gas_price_provider_can_start_at_nonzero_height() {
119121
let eth_to_strk_oracle_client = Arc::new(MockExchangeRateOracleClientTrait::new());
122+
let strk_to_usd_oracle_client = Arc::new(MockExchangeRateOracleClientTrait::new());
120123
let mut provider = L1GasPriceProvider::new(
121124
L1GasPriceProviderConfig { number_of_blocks_for_mean: 3, ..Default::default() },
122125
eth_to_strk_oracle_client,
126+
strk_to_usd_oracle_client,
123127
);
124128
provider.initialize().unwrap();
125129
let price_info = PriceInfo { base_fee_per_gas: GasPrice(0), blob_fee: GasPrice(0) };
@@ -130,9 +134,11 @@ fn gas_price_provider_can_start_at_nonzero_height() {
130134
#[test]
131135
fn gas_price_provider_uninitialized_error() {
132136
let eth_to_strk_oracle_client = Arc::new(MockExchangeRateOracleClientTrait::new());
137+
let strk_to_usd_oracle_client = Arc::new(MockExchangeRateOracleClientTrait::new());
133138
let mut provider = L1GasPriceProvider::new(
134139
L1GasPriceProviderConfig { number_of_blocks_for_mean: 3, ..Default::default() },
135140
eth_to_strk_oracle_client,
141+
strk_to_usd_oracle_client,
136142
);
137143
let price_info = PriceInfo { base_fee_per_gas: GasPrice(0), blob_fee: GasPrice(0) };
138144
let timestamp = BlockTimestamp(0);

0 commit comments

Comments
 (0)