Skip to content

Commit

Permalink
feat: starknet-rs migration (#28)
Browse files Browse the repository at this point in the history
* feat: starknet-rs migration

* fix: removed unused code
  • Loading branch information
EvolveArt authored Jun 18, 2024
1 parent 2f30af8 commit 214593e
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 272 deletions.
277 changes: 81 additions & 196 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ phf = { version = "0.11", features = ["macros"] }
prometheus = "0.13.3"
reqwest = { version = "0.11.22", features = ["json"] }
serde = { version = "1.0.130", features = ["derive"] }
starknet = "0.9.0"
starknet = "0.11.0"
strum = { version = "0.25.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
url = "2.5.0"
Expand Down
41 changes: 21 additions & 20 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
use arc_swap::{ArcSwap, Guard};
use starknet::{
core::{
types::{BlockId, BlockTag, FieldElement, FunctionCall},
types::{BlockId, BlockTag, Felt, FunctionCall},
utils::{cairo_short_string_to_felt, parse_cairo_short_string},
},
macros::selector,
Expand All @@ -18,7 +18,7 @@ use strum::{Display, EnumString, IntoStaticStr};
use tokio::sync::OnceCell;
use url::Url;

use crate::constants::CONFIG_UPDATE_INTERVAL;
use crate::{constants::CONFIG_UPDATE_INTERVAL, utils::try_felt_to_u32};

#[derive(Debug, Clone, EnumString, IntoStaticStr)]
pub enum NetworkName {
Expand All @@ -37,14 +37,16 @@ pub enum DataType {
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Network {
pub name: NetworkName,
pub provider: Arc<JsonRpcClient<HttpTransport>>,
pub oracle_address: FieldElement,
pub publisher_registry_address: FieldElement,
pub oracle_address: Felt,
pub publisher_registry_address: Felt,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct DataInfo {
pub pairs: Vec<String>,
pub sources: HashMap<String, Vec<String>>,
Expand All @@ -56,7 +58,7 @@ pub struct DataInfo {
#[allow(unused)]
pub struct Config {
data_info: HashMap<DataType, DataInfo>,
publishers: HashMap<String, FieldElement>,
publishers: HashMap<String, Felt>,
network: Network,
indexer_url: String,
}
Expand Down Expand Up @@ -119,8 +121,7 @@ impl Config {

Config::new(ConfigInput {
network: NetworkName::from_str(&network).expect("Invalid network name"),
oracle_address: FieldElement::from_hex_be(&oracle_address)
.expect("Invalid oracle address"),
oracle_address: Felt::from_hex_unchecked(&oracle_address),
spot_pairs: parse_pairs(&spot_pairs),
future_pairs: parse_pairs(&future_pairs),
})
Expand Down Expand Up @@ -155,15 +156,15 @@ impl Config {
}
}

pub fn all_publishers(&self) -> &HashMap<String, FieldElement> {
pub fn all_publishers(&self) -> &HashMap<String, Felt> {
&self.publishers
}
}

#[derive(Debug, Clone)]
pub struct ConfigInput {
pub network: NetworkName,
pub oracle_address: FieldElement,
pub oracle_address: Felt,
pub spot_pairs: Vec<String>,
pub future_pairs: Vec<String>,
}
Expand Down Expand Up @@ -222,8 +223,8 @@ pub async fn config_force_init(config_input: ConfigInput) {

async fn init_publishers(
rpc_client: &JsonRpcClient<HttpTransport>,
oracle_address: FieldElement,
) -> (HashMap<String, FieldElement>, FieldElement) {
oracle_address: Felt,
) -> (HashMap<String, Felt>, Felt) {
// Fetch publisher registry address
let publisher_registry_address = *rpc_client
.call(
Expand Down Expand Up @@ -269,7 +270,7 @@ async fn init_publishers(
.filter(|publisher| !excluded_publishers.contains(publisher))
.collect::<Vec<String>>();

let mut publishers_map: HashMap<String, FieldElement> = HashMap::new();
let mut publishers_map: HashMap<String, Felt> = HashMap::new();
for publisher in publishers {
let field_publisher =
cairo_short_string_to_felt(&publisher).expect("Failed to parse publisher");
Expand All @@ -294,7 +295,7 @@ async fn init_publishers(

async fn init_spot_config(
rpc_client: &JsonRpcClient<HttpTransport>,
oracle_address: FieldElement,
oracle_address: Felt,
pairs: Vec<String>,
) -> DataInfo {
let mut sources: HashMap<String, Vec<String>> = HashMap::new();
Expand All @@ -315,7 +316,7 @@ async fn init_spot_config(
FunctionCall {
contract_address: oracle_address,
entry_point_selector: selector!("get_decimals"),
calldata: vec![FieldElement::ZERO, field_pair],
calldata: vec![Felt::ZERO, field_pair],
},
BlockId::Tag(BlockTag::Latest),
)
Expand All @@ -324,15 +325,15 @@ async fn init_spot_config(
.first()
.unwrap();

decimals.insert(pair.to_string(), spot_decimals.try_into().unwrap());
decimals.insert(pair.to_string(), try_felt_to_u32(&spot_decimals).unwrap());

// Fetch sources
let spot_pair_sources = rpc_client
.call(
FunctionCall {
contract_address: oracle_address,
entry_point_selector: selector!("get_all_sources"),
calldata: vec![FieldElement::ZERO, field_pair],
calldata: vec![Felt::ZERO, field_pair],
},
BlockId::Tag(BlockTag::Latest),
)
Expand Down Expand Up @@ -366,7 +367,7 @@ async fn init_spot_config(

async fn init_future_config(
rpc_client: &JsonRpcClient<HttpTransport>,
oracle_address: FieldElement,
oracle_address: Felt,
pairs: Vec<String>,
) -> DataInfo {
let mut sources: HashMap<String, Vec<String>> = HashMap::new();
Expand All @@ -387,7 +388,7 @@ async fn init_future_config(
FunctionCall {
contract_address: oracle_address,
entry_point_selector: selector!("get_decimals"),
calldata: vec![FieldElement::ONE, field_pair, FieldElement::ZERO],
calldata: vec![Felt::ONE, field_pair, Felt::ZERO],
},
BlockId::Tag(BlockTag::Latest),
)
Expand All @@ -396,15 +397,15 @@ async fn init_future_config(
.first()
.unwrap();

decimals.insert(pair.to_string(), future_decimals.try_into().unwrap());
decimals.insert(pair.to_string(), try_felt_to_u32(&future_decimals).unwrap());

// Fetch sources
let future_pair_sources = rpc_client
.call(
FunctionCall {
contract_address: oracle_address,
entry_point_selector: selector!("get_all_sources"),
calldata: vec![FieldElement::ONE, field_pair, FieldElement::ZERO],
calldata: vec![Felt::ONE, field_pair, Felt::ZERO],
},
BlockId::Tag(BlockTag::Latest),
)
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub(crate) mod constants;
pub mod models;
pub mod schema;
pub mod types;
pub(crate) mod utils;
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ mod schema;
mod constants;
// Types
mod types;
// Utils
mod utils;

#[cfg(test)]
mod tests;
Expand Down
21 changes: 7 additions & 14 deletions src/monitoring/on_off_deviation.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bigdecimal::ToPrimitive;
use starknet::{
core::{
types::{BlockId, BlockTag, FieldElement, FunctionCall},
types::{BlockId, BlockTag, Felt, FunctionCall},
utils::cairo_short_string_to_felt,
},
macros::selector,
Expand All @@ -13,6 +13,7 @@ use crate::{
config::{get_config, DataType},
constants::COINGECKO_IDS,
error::MonitoringError,
utils::try_felt_to_u32,
};

/// On-chain price deviation from the reference price.
Expand All @@ -39,8 +40,8 @@ pub async fn on_off_price_deviation(
let field_pair = cairo_short_string_to_felt(&pair_id).expect("failed to convert pair id");

let calldata = match data_type {
DataType::Spot => vec![FieldElement::ZERO, field_pair],
DataType::Future => vec![FieldElement::ONE, field_pair, FieldElement::ZERO],
DataType::Spot => vec![Felt::ZERO, field_pair],
DataType::Future => vec![Felt::ONE, field_pair, Felt::ZERO],
};

let data = client
Expand All @@ -55,19 +56,10 @@ pub async fn on_off_price_deviation(
.await
.map_err(|e| MonitoringError::OnChain(e.to_string()))?;

let decimals =
config
.decimals(data_type.clone())
.get(&pair_id)
.ok_or(MonitoringError::OnChain(format!(
"Failed to get decimals for pair {:?}",
pair_id
)))?;

let on_chain_price = data
.first()
.ok_or(MonitoringError::OnChain("No data".to_string()))?
.to_big_decimal(*decimals)
.to_bigint()
.to_f64()
.ok_or(MonitoringError::Conversion(
"Failed to convert to f64".to_string(),
Expand Down Expand Up @@ -117,7 +109,8 @@ pub async fn on_off_price_deviation(
.get_price();

let deviation = (reference_price - on_chain_price) / on_chain_price;
let num_sources_aggregated = (*data.get(3).unwrap()).try_into().map_err(|e| {
let num_sources = data.get(3).unwrap();
let num_sources_aggregated = try_felt_to_u32(num_sources).map_err(|e| {
MonitoringError::Conversion(format!("Failed to convert num sources {:?}", e))
})?;
(deviation, num_sources_aggregated)
Expand Down
11 changes: 5 additions & 6 deletions src/monitoring/publisher_balance.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
use bigdecimal::ToPrimitive;
use starknet::{
core::types::{BlockId, BlockTag, FieldElement, FunctionCall},
core::types::{BlockId, BlockTag, Felt, FunctionCall},
macros::selector,
providers::Provider,
};

use crate::constants::{FEE_TOKEN_ADDRESS, FEE_TOKEN_DECIMALS};
use crate::constants::FEE_TOKEN_ADDRESS;
use crate::{config::get_config, error::MonitoringError};

/// Returns the balance of a given publisher address
/// Note: Currently only reads ETH balance
pub async fn publisher_balance(publisher_address: FieldElement) -> Result<f64, MonitoringError> {
pub async fn publisher_balance(publisher_address: Felt) -> Result<f64, MonitoringError> {
let config = get_config(None).await;

let client = &config.network().provider;
let token_balance = client
.call(
FunctionCall {
contract_address: FieldElement::from_hex_be(FEE_TOKEN_ADDRESS)
.expect("failed to convert token address"),
contract_address: Felt::from_hex_unchecked(FEE_TOKEN_ADDRESS),
entry_point_selector: selector!("balanceOf"),
calldata: vec![publisher_address],
},
Expand All @@ -30,7 +29,7 @@ pub async fn publisher_balance(publisher_address: FieldElement) -> Result<f64, M
let on_chain_balance = token_balance
.first()
.ok_or(MonitoringError::OnChain("No data".to_string()))?
.to_big_decimal(FEE_TOKEN_DECIMALS)
.to_bigint()
.to_f64()
.ok_or(MonitoringError::Conversion(
"Failed to convert to f64".to_string(),
Expand Down
18 changes: 5 additions & 13 deletions src/monitoring/source_deviation.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use bigdecimal::ToPrimitive;
use starknet::{
core::{
types::{BlockId, BlockTag, FieldElement, FunctionCall},
types::{BlockId, BlockTag, Felt, FunctionCall},
utils::cairo_short_string_to_felt,
},
macros::selector,
providers::Provider,
};

use crate::{config::get_config, error::MonitoringError, types::Entry};
use crate::{config::get_config, error::MonitoringError, types::Entry, utils::try_felt_to_u32};

/// Calculates the deviation from the on-chain price
/// Returns the deviation and the number of sources aggregated
Expand All @@ -27,32 +27,24 @@ pub async fn source_deviation<T: Entry>(
FunctionCall {
contract_address: config.network().oracle_address,
entry_point_selector: selector!("get_data_median"),
calldata: vec![FieldElement::ZERO, field_pair],
calldata: vec![Felt::ZERO, field_pair],
},
BlockId::Tag(BlockTag::Latest),
)
.await
.map_err(|e| MonitoringError::OnChain(e.to_string()))?;

let decimals = config
.decimals(query.data_type())
.get(query.pair_id())
.ok_or(MonitoringError::OnChain(format!(
"Failed to get decimals for pair {:?}",
query.pair_id()
)))?;

let on_chain_price = data
.first()
.ok_or(MonitoringError::OnChain("No data".to_string()))?
.to_big_decimal(*decimals)
.to_bigint()
.to_f64()
.ok_or(MonitoringError::Conversion(
"Failed to convert to f64".to_string(),
))?;

let deviation = (normalized_price - on_chain_price) / on_chain_price;
let num_sources_aggregated = (*data.get(3).unwrap()).try_into().map_err(|e| {
let num_sources_aggregated = try_felt_to_u32(data.get(3).unwrap()).map_err(|e| {
MonitoringError::Conversion(format!("Failed to convert num sources {:?}", e))
})?;

Expand Down
6 changes: 3 additions & 3 deletions src/processing/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub async fn process_sequencer_data() -> Result<(), MonitoringError> {
parsed_price.to_string().parse::<f64>().unwrap() / 10_f64.powi(result.decimals as i32);

let provider = match network_env {
"Testnet" => SequencerGatewayProvider::starknet_alpha_goerli(),
"Testnet" => SequencerGatewayProvider::starknet_alpha_sepolia(),
"Mainnet" => SequencerGatewayProvider::starknet_alpha_mainnet(),
_ => panic!("Invalid network env"),
};
Expand All @@ -79,8 +79,8 @@ pub async fn process_sequencer_data() -> Result<(), MonitoringError> {
.await
.map_err(MonitoringError::Provider)?;

let eth = block.eth_l1_gas_price.to_big_decimal(18);
let strk = block.strk_l1_gas_price.to_big_decimal(18);
let eth = block.l1_gas_price.price_in_wei.to_bigint();
let strk = block.l1_gas_price.price_in_fri.to_bigint();

let expected_price = (strk / eth).to_f64().ok_or(MonitoringError::Conversion(
"Failed to convert expected price to f64".to_string(),
Expand Down
5 changes: 3 additions & 2 deletions src/processing/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
};
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use serde::{Deserialize, Serialize};
use starknet::core::types::FieldElement;
use starknet::core::types::Felt;
use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider};
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct IndexerServerStatus {
Expand Down Expand Up @@ -106,6 +106,7 @@ async fn blocks_left(
// "decimals": 18
// }
#[derive(serde::Deserialize, Debug)]
#[allow(dead_code)]
pub struct PragmaDataDTO {
pub num_sources_aggregated: u32,
pub pair_id: String,
Expand Down Expand Up @@ -169,7 +170,7 @@ pub async fn query_pragma_api(

pub async fn check_publisher_balance(
publisher: String,
publisher_address: FieldElement,
publisher_address: Felt,
) -> Result<(), MonitoringError> {
let config = get_config(None).await;
let balance = publisher_balance(publisher_address).await?;
Expand Down
Loading

0 comments on commit 214593e

Please sign in to comment.