-
Notifications
You must be signed in to change notification settings - Fork 30
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() : fetch strk price from oracle #368
base: main
Are you sure you want to change the base?
Changes from 19 commits
da5323c
bdccab8
4634e8a
8a8fa6b
d83b8f9
2df3e5a
5b70d42
1f0373b
7a09d76
f4c067f
800ce9a
899694e
cecb081
066680e
694c995
589d040
779603e
aabf90a
5d23214
2428bac
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 |
---|---|---|
|
@@ -2,6 +2,7 @@ use crate::client::EthereumClient; | |
use alloy::eips::BlockNumberOrTag; | ||
use alloy::providers::Provider; | ||
use anyhow::Context; | ||
use bigdecimal::BigDecimal; | ||
use mc_mempool::{GasPriceProvider, L1DataProvider}; | ||
use std::time::{Duration, UNIX_EPOCH}; | ||
|
||
|
@@ -67,6 +68,21 @@ async fn update_gas_price(eth_client: &EthereumClient, l1_gas_provider: GasPrice | |
l1_gas_provider.update_eth_l1_gas_price(*eth_gas_price); | ||
l1_gas_provider.update_eth_l1_data_gas_price(avg_blob_base_fee); | ||
|
||
// fetch eth/strk price and update | ||
if let Some(oracle_provider) = &l1_gas_provider.oracle_provider { | ||
let (eth_strk_price, decimals) = | ||
oracle_provider.fetch_eth_strk_price().await.context("failed to retrieve ETH/STRK price")?; | ||
let strk_gas_price = (BigDecimal::new((*eth_gas_price).into(), decimals.into()) | ||
/ BigDecimal::new(eth_strk_price.into(), decimals.into())) | ||
.as_bigint_and_exponent(); | ||
let strk_data_gas_price = (BigDecimal::new(avg_blob_base_fee.into(), decimals.into()) | ||
/ BigDecimal::new(eth_strk_price.into(), decimals.into())) | ||
.as_bigint_and_exponent(); | ||
|
||
l1_gas_provider.update_strk_l1_gas_price(strk_gas_price.0.to_str_radix(10).parse::<u128>()?); | ||
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 would expect this not to overflow but would be great to ensure clean code |
||
l1_gas_provider.update_strk_l1_data_gas_price(strk_data_gas_price.0.to_str_radix(10).parse::<u128>()?); | ||
} | ||
|
||
l1_gas_provider.update_last_update_timestamp(); | ||
|
||
// Update block number separately to avoid holding the lock for too long | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool}; | |
use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; | ||
use mc_telemetry::{SysInfo, TelemetryService}; | ||
use mp_convert::ToFelt; | ||
use mp_oracle::Oracle; | ||
use mp_utils::service::{Service, ServiceGroup}; | ||
use service::{BlockProductionService, GatewayService, L1SyncService, RpcService, SyncService}; | ||
use starknet_providers::SequencerGatewayProvider; | ||
|
@@ -90,7 +91,7 @@ async fn main() -> anyhow::Result<()> { | |
.context("Initializing importer service")?, | ||
); | ||
|
||
let l1_gas_setter = GasPriceProvider::new(); | ||
let mut l1_gas_setter = GasPriceProvider::new(); | ||
|
||
if let Some(fix_gas) = run_cmd.l1_sync_params.gas_price { | ||
l1_gas_setter.update_eth_l1_gas_price(fix_gas as u128); | ||
|
@@ -108,6 +109,18 @@ async fn main() -> anyhow::Result<()> { | |
l1_gas_setter.update_strk_l1_data_gas_price(strk_fix_blob_gas as u128); | ||
l1_gas_setter.set_strk_data_gas_price_sync_enabled(false); | ||
} | ||
if let Some(ref oracle_url) = run_cmd.l1_sync_params.oracle_url { | ||
if let Some(ref oracle_api_key) = run_cmd.l1_sync_params.oracle_api_key { | ||
let oracle = Oracle::new("Pragma", oracle_url.to_string(), oracle_api_key.clone())?; | ||
l1_gas_setter.set_oracle_provider(oracle); | ||
} | ||
} | ||
|
||
if l1_gas_setter.is_oracle_needed() && l1_gas_setter.oracle_provider.is_none() { | ||
log::error!("STRK gas is not fixed and oracle is not provided"); | ||
panic!(); | ||
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 would personally handle the case where we dont want the strk price by defaulting it |
||
} | ||
|
||
let l1_data_provider: Arc<dyn L1DataProvider> = Arc::new(l1_gas_setter.clone()); | ||
|
||
// declare mempool here so that it can be used to process l1->l2 messages in the l1 service | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
description = "Madara primitive for Oracles" | ||
name = "mp-oracle" | ||
authors.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
repository.workspace = true | ||
version.workspace = true | ||
homepage.workspace = true | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[package.metadata.docs.rs] | ||
targets = ["x86_64-unknown-linux-gnu"] | ||
|
||
[dependencies] | ||
|
||
# Other | ||
anyhow = { workspace = true } | ||
num-bigint = { workspace = true } | ||
reqwest = { workspace = true } | ||
serde = { workspace = true } | ||
serde_json = { workspace = true } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use anyhow::bail; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
mod pragma; | ||
|
||
use pragma::*; | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
#[serde(tag = "oracle_name", content = "config")] | ||
pub enum Oracle { | ||
Pragma(PragmaOracle), | ||
} | ||
|
||
impl Oracle { | ||
pub fn new(oracle_name: &str, url: String, key: String) -> anyhow::Result<Self> { | ||
match oracle_name { | ||
"Pragma" => Ok(Oracle::Pragma(PragmaOracle::new(url, key))), | ||
_ => bail!("Unknown Oracle name"), | ||
} | ||
} | ||
|
||
pub fn set_base_url(&mut self, url: String) { | ||
match self { | ||
Oracle::Pragma(pragma_oracle) => pragma_oracle.api_url = url, | ||
} | ||
} | ||
|
||
pub async fn fetch_eth_strk_price(&self) -> anyhow::Result<(u128, u32)> { | ||
match self { | ||
Oracle::Pragma(pragma_oracle) => pragma_oracle.fetch_eth_strk_price().await, | ||
} | ||
} | ||
|
||
pub fn set_api_key(&mut self, key: String) { | ||
match self { | ||
Oracle::Pragma(pragma_oracle) => pragma_oracle.api_key = key, | ||
} | ||
} | ||
|
||
pub fn get_fetch_url(&self, base: String, quote: String) -> String { | ||
match self { | ||
Oracle::Pragma(pragma_oracle) => pragma_oracle.get_fetch_url(base, quote), | ||
} | ||
} | ||
|
||
pub fn get_api_key(&self) -> &String { | ||
match self { | ||
Oracle::Pragma(oracle) => &oracle.api_key, | ||
} | ||
} | ||
|
||
pub fn is_in_bounds(&self, price: u128) -> bool { | ||
match self { | ||
Oracle::Pragma(oracle) => oracle.price_bounds.low <= price && price <= oracle.price_bounds.high, | ||
} | ||
} | ||
} | ||
|
||
impl Default for Oracle { | ||
fn default() -> Self { | ||
Self::Pragma(PragmaOracle::default()) | ||
} | ||
} |
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.
if
eth_strk_price
price is 0 here there is a possible 0 division?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.
yeah you are right, added a check