From b1f304267824f20f1674476b925c0ee8b97a53c8 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 13:12:09 +0100 Subject: [PATCH 01/13] feat: clean code --- .env.example | 2 +- migrations/.keep | 0 .../down.sql | 6 -- .../up.sql | 36 ---------- .../2023-10-11-230102_create_posts/down.sql | 2 - .../2023-10-11-230102_create_posts/up.sql | 37 ---------- src/config.rs | 1 + src/error.rs | 18 ++--- src/main.rs | 49 ++++++++++--- src/models.rs | 20 ++++++ src/monitoring/mod.rs | 4 +- ...ePairId.rs => time_last_update_pair_id.rs} | 0 ...teSource.rs => time_last_update_source.rs} | 1 + src/process_data.rs | 70 +++++++++++-------- src/server.rs | 2 + 15 files changed, 116 insertions(+), 132 deletions(-) delete mode 100644 migrations/.keep delete mode 100644 migrations/00000000000000_diesel_initial_setup/down.sql delete mode 100644 migrations/00000000000000_diesel_initial_setup/up.sql delete mode 100644 migrations/2023-10-11-230102_create_posts/down.sql delete mode 100644 migrations/2023-10-11-230102_create_posts/up.sql create mode 100644 src/config.rs rename src/monitoring/{timeLastUpdatePairId.rs => time_last_update_pair_id.rs} (100%) rename src/monitoring/{timeLastUpdateSource.rs => time_last_update_source.rs} (99%) diff --git a/.env.example b/.env.example index 54f001d..3609cf1 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,2 @@ # The database URL the application will use to connect to the database. -DATABASE_URL='postgres://postgres:A+T|oiWbuK02OwLG:8rAdF7LT~b-@testnet-aurora.proxy-cusx5kdiz1ia.eu-west-3.rds.amazonaws.com/indexed_data?sslmode=disable' \ No newline at end of file +DATABASE_URL='postgres://postgres:postgres@localhost:5432/postgres' \ No newline at end of file diff --git a/migrations/.keep b/migrations/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql deleted file mode 100644 index a9f5260..0000000 --- a/migrations/00000000000000_diesel_initial_setup/down.sql +++ /dev/null @@ -1,6 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - -DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); -DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql deleted file mode 100644 index d68895b..0000000 --- a/migrations/00000000000000_diesel_initial_setup/up.sql +++ /dev/null @@ -1,36 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - - - - --- Sets up a trigger for the given table to automatically set a column called --- `updated_at` whenever the row is modified (unless `updated_at` was included --- in the modified columns) --- --- # Example --- --- ```sql --- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); --- --- SELECT diesel_manage_updated_at('users'); --- ``` -CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ -BEGIN - EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s - FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ -BEGIN - IF ( - NEW IS DISTINCT FROM OLD AND - NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at - ) THEN - NEW.updated_at := current_timestamp; - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; diff --git a/migrations/2023-10-11-230102_create_posts/down.sql b/migrations/2023-10-11-230102_create_posts/down.sql deleted file mode 100644 index 73ada84..0000000 --- a/migrations/2023-10-11-230102_create_posts/down.sql +++ /dev/null @@ -1,2 +0,0 @@ --- This file should undo anything in `up.sql` -DROP TABLE IF EXISTS public.future_entry; diff --git a/migrations/2023-10-11-230102_create_posts/up.sql b/migrations/2023-10-11-230102_create_posts/up.sql deleted file mode 100644 index b96a73b..0000000 --- a/migrations/2023-10-11-230102_create_posts/up.sql +++ /dev/null @@ -1,37 +0,0 @@ --- Your SQL goes here -CREATE TABLE IF NOT EXISTS public.future_entry -( - network character varying(255) COLLATE pg_catalog."default", - pair_id character varying(255) COLLATE pg_catalog."default", - data_id character varying(255) COLLATE pg_catalog."default", - block_hash character varying(255) COLLATE pg_catalog."default", - block_number bigint, - block_timestamp timestamp without time zone, - transaction_hash character varying(255) COLLATE pg_catalog."default", - price numeric, - "timestamp" timestamp without time zone, - publisher character varying(255) COLLATE pg_catalog."default", - source character varying(255) COLLATE pg_catalog."default", - volume numeric, - expiration_timestamp timestamp without time zone, - _cursor bigint -) - -TABLESPACE pg_default; - -ALTER TABLE IF EXISTS public.future_entry - OWNER to postgres; - -REVOKE ALL ON TABLE public.future_entry FROM indexed_data_read_only; - -GRANT SELECT ON TABLE public.future_entry TO indexed_data_read_only; - -GRANT ALL ON TABLE public.future_entry TO postgres; --- Index: future_entry_pair_id_publisher_source_timestamp_index - --- DROP INDEX IF EXISTS public.future_entry_pair_id_publisher_source_timestamp_index; - -CREATE INDEX IF NOT EXISTS future_entry_pair_id_publisher_source_timestamp_index - ON public.future_entry USING btree - (pair_id COLLATE pg_catalog."default" ASC NULLS LAST, publisher COLLATE pg_catalog."default" ASC NULLS LAST, source COLLATE pg_catalog."default" ASC NULLS LAST, "timestamp" ASC NULLS LAST) - TABLESPACE pg_default; \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/config.rs @@ -0,0 +1 @@ + diff --git a/src/error.rs b/src/error.rs index e015f49..e4f8cca 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,10 +2,10 @@ use std::{error::Error as StdError, fmt}; #[derive(Debug)] pub enum MonitoringError { - PriceError(String), - TimeError(String), - DatabaseError(diesel::result::Error), - ConnectionError(String), + Price(String), + Time(String), + Database(diesel::result::Error), + Connection(String), } impl StdError for MonitoringError {} @@ -13,10 +13,10 @@ impl StdError for MonitoringError {} impl fmt::Display for MonitoringError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - MonitoringError::PriceError(e) => write!(f, "Price Error: {}", e), - MonitoringError::TimeError(e) => write!(f, "Time Error: {}", e), - MonitoringError::DatabaseError(e) => write!(f, "Database Error: {}", e), - MonitoringError::ConnectionError(e) => write!(f, "Connection Error: {}", e), + MonitoringError::Price(e) => write!(f, "Price Error: {}", e), + MonitoringError::Time(e) => write!(f, "Time Error: {}", e), + MonitoringError::Database(e) => write!(f, "Database Error: {}", e), + MonitoringError::Connection(e) => write!(f, "Connection Error: {}", e), } } } @@ -24,6 +24,6 @@ impl fmt::Display for MonitoringError { // Convert diesel error to our custom error impl From for MonitoringError { fn from(err: diesel::result::Error) -> MonitoringError { - MonitoringError::DatabaseError(err) + MonitoringError::Database(err) } } diff --git a/src/main.rs b/src/main.rs index f6b0fad..446e20e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,28 +1,53 @@ -// main.rs extern crate diesel; extern crate dotenv; use diesel_async::pooled_connection::deadpool::*; use diesel_async::pooled_connection::AsyncDieselConnectionManager; -use diesel_async::AsyncPgConnection; use dotenv::dotenv; use std::env; + +// Error handling mod error; +// Database models mod models; +// Monitoring functions mod monitoring; +// Processing functions mod process_data; -mod schema; +// Server mod server; +// Database schema +mod schema; #[tokio::main] async fn main() { + // Load environment variables from .env file dotenv().ok(); - let pairs = vec![("BTC/USD", "CEX", 8), ("ETH/USD", "CEX",8), ("BTC/USD", "COINBASE",8), ("ETH/USD", "COINBASE",8), ("BTC/USD", "BITSTAMP",8), ("ETH/USD", "BITSTAMP",8),("BTC/USD", "OKX",8), ("ETH/USD", "OKX",8),("BTC/USD", "GECKOTERMINAL",8), ("ETH/USD", "GECKOTERMINAL",8), ("BTC/USD", "KAIKO",8), ("ETH/USD", "KAIKO",8),]; + + // Define the pairs to monitor + let pairs = vec![ + ("BTC/USD", "CEX", 8), + ("ETH/USD", "CEX", 8), + ("BTC/USD", "COINBASE", 8), + ("ETH/USD", "COINBASE", 8), + ("BTC/USD", "BITSTAMP", 8), + ("ETH/USD", "BITSTAMP", 8), + ("BTC/USD", "OKX", 8), + ("ETH/USD", "OKX", 8), + ("BTC/USD", "GECKOTERMINAL", 8), + ("ETH/USD", "GECKOTERMINAL", 8), + ("BTC/USD", "KAIKO", 8), + ("ETH/USD", "KAIKO", 8), + ]; + tokio::spawn(server::run_metrics_server()); + let database_url: String = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); let config = AsyncDieselConnectionManager::::new(database_url); let pool = Pool::builder(config).build().unwrap(); + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(5)); + loop { interval.tick().await; // Wait for the next tick @@ -30,12 +55,18 @@ async fn main() { .clone() .into_iter() .flat_map(|(pair, srce, decimals)| { - let pool_ref_for_pair = pool.clone(); - let pool_ref_for_pair_and_source = pool.clone(); - vec![ - tokio::spawn(Box::pin(process_data::process_data_by_pair(pool_ref_for_pair, pair, decimals))), - tokio::spawn(Box::pin(process_data::process_data_by_pair_and_source(pool_ref_for_pair_and_source, pair, srce, decimals))), + tokio::spawn(Box::pin(process_data::process_data_by_pair( + pool.clone(), + pair, + decimals, + ))), + tokio::spawn(Box::pin(process_data::process_data_by_pair_and_source( + pool.clone(), + pair, + srce, + decimals, + ))), ] }) .collect(); diff --git a/src/models.rs b/src/models.rs index 5deb0f5..b05da22 100644 --- a/src/models.rs +++ b/src/models.rs @@ -23,3 +23,23 @@ pub struct SpotEntry { pub volume: BigDecimal, pub _cursor: i64, } + +#[derive(Debug, Queryable, Selectable, QueryableByName)] +#[diesel(table_name = crate::schema::future_entry)] +#[diesel(check_for_backend(diesel::pg::Pg))] +pub struct FutureEntry { + pub data_id: String, + pub network: String, + pub pair_id: String, + pub block_hash: String, + pub block_number: i64, + pub block_timestamp: Option, + pub transaction_hash: String, + pub price: BigDecimal, + pub timestamp: Option, + pub publisher: String, + pub source: String, + pub volume: BigDecimal, + pub expiration_timestamp: Option, + pub _cursor: i64, +} diff --git a/src/monitoring/mod.rs b/src/monitoring/mod.rs index d670c4c..3de5ef7 100644 --- a/src/monitoring/mod.rs +++ b/src/monitoring/mod.rs @@ -1,2 +1,2 @@ -pub mod timeLastUpdateSource; -pub mod timeLastUpdatePairId; \ No newline at end of file +pub mod time_last_update_pair_id; +pub mod time_last_update_source; diff --git a/src/monitoring/timeLastUpdatePairId.rs b/src/monitoring/time_last_update_pair_id.rs similarity index 100% rename from src/monitoring/timeLastUpdatePairId.rs rename to src/monitoring/time_last_update_pair_id.rs diff --git a/src/monitoring/timeLastUpdateSource.rs b/src/monitoring/time_last_update_source.rs similarity index 99% rename from src/monitoring/timeLastUpdateSource.rs rename to src/monitoring/time_last_update_source.rs index e928753..2ce0410 100644 --- a/src/monitoring/timeLastUpdateSource.rs +++ b/src/monitoring/time_last_update_source.rs @@ -1,6 +1,7 @@ use crate::models::SpotEntry; use chrono::{DateTime, TimeZone, Utc}; use std::time::SystemTime; + pub async fn time_since_last_update(query: &SpotEntry) -> u64 { let datetime: DateTime = TimeZone::from_utc_datetime(&Utc, &query.timestamp.unwrap()); let timestamp = datetime.timestamp(); diff --git a/src/process_data.rs b/src/process_data.rs index 70dd4e0..1d50aaf 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -1,21 +1,23 @@ extern crate diesel; extern crate dotenv; + +use crate::diesel::QueryDsl; +use crate::error::MonitoringError; use crate::models::SpotEntry; +use crate::monitoring::time_last_update_pair_id::time_last_update_pair_id; +use crate::monitoring::time_last_update_source::time_since_last_update; +use crate::schema::spot_entry::dsl::*; + use bigdecimal::ToPrimitive; use diesel::ExpressionMethods; -use diesel_async::AsyncPgConnection; use diesel_async::pooled_connection::AsyncDieselConnectionManager; -use crate::schema::spot_entry::dsl::*; -use crate::monitoring::timeLastUpdateSource::time_since_last_update; -use crate::monitoring::timeLastUpdatePairId::time_last_update_pair_id; -use diesel::sql_types::Text; -use prometheus::{opts, register_gauge_vec, GaugeVec}; -use crate::diesel::QueryDsl; +use diesel_async::AsyncPgConnection; use diesel_async::RunQueryDsl; -use crate::error::MonitoringError; +use prometheus::{opts, register_gauge_vec, GaugeVec}; + lazy_static::lazy_static! { static ref TIME_SINCE_LAST_UPDATE_SOURCE: GaugeVec = register_gauge_vec!( - opts!("time_since_last_updatee_seconds", "Time since the last update in seconds."), + opts!("time_since_last_update_seconds", "Time since the last update in seconds."), &["pair", "source"] ).unwrap(); } @@ -38,52 +40,60 @@ pub async fn process_data_by_pair( pool: deadpool::managed::Pool>, pair: &str, decimals: u32, -) -> Result { - let mut conn = pool.get().await.map_err(|_| MonitoringError::ConnectionError("Failed to get connection".to_string()))?; +) -> Result { + let mut conn = pool + .get() + .await + .map_err(|_| MonitoringError::Connection("Failed to get connection".to_string()))?; + let result: Result = spot_entry .filter(pair_id.eq(pair)) .order(block_timestamp.desc()) .first(&mut conn) .await; + match result { - Ok(data) => { + Ok(data) => { let minute_since_last_publish = time_last_update_pair_id(&data).await; let time_labels = TIME_SINCE_LAST_UPDATE_PAIR_ID.with_label_values(&[pair]); time_labels.set(minute_since_last_publish as f64); Ok(minute_since_last_publish) - }, - Err(e) => Err(e.into()) + } + Err(e) => Err(e.into()), } } - pub async fn process_data_by_pair_and_source( pool: deadpool::managed::Pool>, pair: &str, - srce: &str, - decimals: u32 -) -> Result { - let mut conn = pool.get().await.map_err(|_| MonitoringError::ConnectionError("Failed to get connection".to_string()))?; - + src: &str, + decimals: u32, +) -> Result { + let mut conn = pool + .get() + .await + .map_err(|_| MonitoringError::Connection("Failed to get connection".to_string()))?; + let filtered_by_source_result: Result = spot_entry .filter(pair_id.eq(pair)) - .filter(source.eq(srce)) + .filter(source.eq(src)) .order(block_timestamp.desc()) .first(&mut conn) .await; - match filtered_by_source_result { Ok(data) => { let time = time_since_last_update(&data).await; - let time_labels = TIME_SINCE_LAST_UPDATE_SOURCE.with_label_values(&[pair, srce]); - let price_labels = PAIR_PRICE.with_label_values(&[&pair, &srce]); - let price_as_f64 = data.price.to_f64().ok_or(MonitoringError::PriceError("Failed to convert BigDecimal to f64".to_string()))?; - let dec : i32= 10; - price_labels.set(price_as_f64/(dec.pow(decimals)) as f64); + let time_labels = TIME_SINCE_LAST_UPDATE_SOURCE.with_label_values(&[pair, src]); + let price_labels = PAIR_PRICE.with_label_values(&[pair, src]); + let price_as_f64 = data.price.to_f64().ok_or(MonitoringError::Price( + "Failed to convert BigDecimal to f64".to_string(), + ))?; + let dec: i32 = 10; + price_labels.set(price_as_f64 / (dec.pow(decimals)) as f64); time_labels.set(time as f64); - Ok(time) - }, - Err(e) => Err(e.into()) + Ok(time) + } + Err(e) => Err(e.into()), } } diff --git a/src/server.rs b/src/server.rs index 516cd84..17d72d5 100644 --- a/src/server.rs +++ b/src/server.rs @@ -9,7 +9,9 @@ pub async fn run_metrics_server() { .route("/metrics", get(metrics_handler)); let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); + println!("Listening on http://{}", addr); + Server::bind(&addr) .serve(app.into_make_service()) .await From 1df677158331c0bb756485bf4ab3eb5503ffdea1 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 15:29:58 +0100 Subject: [PATCH 02/13] feat: load starknet config --- .env.example | 11 +- Cargo.lock | 90 ++++--- Cargo.toml | 12 +- README.md | 8 +- src/config.rs | 224 ++++++++++++++++++ src/error.rs | 2 - src/main.rs | 47 ++-- src/monitoring/mod.rs | 3 +- src/monitoring/time_last_update_pair_id.rs | 9 - ...te_source.rs => time_since_last_update.rs} | 4 +- src/process_data.rs | 51 ++-- src/server.rs | 1 + 12 files changed, 372 insertions(+), 90 deletions(-) delete mode 100644 src/monitoring/time_last_update_pair_id.rs rename src/monitoring/{time_last_update_source.rs => time_since_last_update.rs} (75%) diff --git a/.env.example b/.env.example index 3609cf1..d06ffb7 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,11 @@ # The database URL the application will use to connect to the database. -DATABASE_URL='postgres://postgres:postgres@localhost:5432/postgres' \ No newline at end of file +DATABASE_URL='postgres://postgres:postgres@localhost:5432/postgres' + +# RPC URLS +TESTNET_RPC_URL= +MAINNET_RPC_URL= + +# Config +NETWORK=testnet +ORACLE_ADDRESS=0x +PAIRS=BTC/USD,ETH/USD \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 7f986f1..3060085 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1295,9 +1295,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1634,9 +1634,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1975,7 +1975,9 @@ dependencies = [ "prometheus", "starknet", "starknet_api", + "strum", "tokio", + "url", "uuid 1.4.1", ] @@ -2194,9 +2196,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" @@ -2794,18 +2796,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -3009,14 +3011,14 @@ dependencies = [ [[package]] name = "starknet" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0623b045f3dc10aef030c9ddd4781cff9cbe1188b71063cc510b75d1f96be6" +checksum = "5eb139c5e6f6c6da627080e33cc00b3fc1c9733403034ca1ee9c42a95c337c7f" dependencies = [ "starknet-accounts", "starknet-contract", "starknet-core", - "starknet-crypto 0.6.0", + "starknet-crypto 0.6.1", "starknet-ff", "starknet-macros", "starknet-providers", @@ -3025,9 +3027,9 @@ dependencies = [ [[package]] name = "starknet-accounts" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e97edc480348dca300e5a8234e6c4e6f2f1ac028f2b16fcce294ebe93d07f4" +checksum = "3743932c80ad2a5868c2dd4ef729de4e12060c88e73e4bb678a5f8e51b105e53" dependencies = [ "async-trait", "auto_impl", @@ -3039,9 +3041,9 @@ dependencies = [ [[package]] name = "starknet-contract" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b86e3f6b3ca9a5c45271ab10871c99f7dc82fee3199d9f8c7baa2a1829947d" +checksum = "4e55aac528c5376e1626d5a8d4daaf280bfd08f909dadc729e5b009203d6ec21" dependencies = [ "serde", "serde_json", @@ -3054,9 +3056,9 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.6.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14139b1c39bdc2f1e663c12090ff5108fe50ebe62c09e15e32988dfaf445a7e4" +checksum = "ff50e281d4fdb97988a3d5c7b7cae22b9d67bb2ef9be2cfafc17a1e35542cb53" dependencies = [ "base64 0.21.4", "flate2", @@ -3066,7 +3068,7 @@ dependencies = [ "serde_json_pythonic", "serde_with", "sha3", - "starknet-crypto 0.6.0", + "starknet-crypto 0.6.1", "starknet-ff", ] @@ -3092,9 +3094,9 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dbb308033b5c60c5677645f7ba3b012b4e3e81f773480d27fb5f342d50621e6" +checksum = "33c03f5ac70f9b067f48db7d2d70bdf18ee0f731e8192b6cfa679136becfcdb0" dependencies = [ "crypto-bigint", "hex", @@ -3141,9 +3143,9 @@ dependencies = [ [[package]] name = "starknet-ff" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2cb1d9c0a50380cddab99cb202c6bfb3332728a2769bd0ca2ee80b0b390dd4" +checksum = "067419451efdea1ee968df8438369960c167e0e905c05b84afd074f50e1d6f3d" dependencies = [ "ark-ff", "bigdecimal 0.3.1", @@ -3156,9 +3158,9 @@ dependencies = [ [[package]] name = "starknet-macros" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef846b6bb48fc8c3e9a2aa9b5b037414f04a908d9db56493a3ae69a857eb2506" +checksum = "840be1a7eb5735863eee47d3a3f26df45b9be2c519e8da294e74b4d0524d77d1" dependencies = [ "starknet-core", "syn 2.0.38", @@ -3166,9 +3168,9 @@ dependencies = [ [[package]] name = "starknet-providers" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b136c26b72ff1756f0844e0aa80bab680ceb99d63921826facbb8e7340ff82" +checksum = "5b08084f36ff7f11743ec71f33f0b11d439cbe0524058def299eb47de1ef1c28" dependencies = [ "async-trait", "auto_impl", @@ -3186,9 +3188,9 @@ dependencies = [ [[package]] name = "starknet-signers" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9386015d2e6dc3df285bfb33a3afd8ad7596c70ed38ab57019de4d2dfc7826f" +checksum = "91919d8f318f0b5bcc4ff5849fbd3fb46adaaa72e0bf204742bab7c822425ff4" dependencies = [ "async-trait", "auto_impl", @@ -3196,7 +3198,7 @@ dependencies = [ "eth-keystore", "rand", "starknet-core", - "starknet-crypto 0.6.0", + "starknet-crypto 0.6.1", "thiserror", ] @@ -3254,6 +3256,28 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.38", +] + [[package]] name = "subtle" version = "2.5.0" @@ -3635,9 +3659,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", diff --git a/Cargo.toml b/Cargo.toml index 4572a4c..4aeaa6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,13 @@ axum-macros = "0.3" chrono = "0.4" bigdecimal = "0.4.1" num-bigint = "0.4" -diesel = { version = "2.1.0", features = ["postgres" , "numeric", "chrono","uuid", "serde_json"] } +diesel = { version = "2.1.0", features = [ + "postgres", + "numeric", + "chrono", + "uuid", + "serde_json", +] } diesel-async = { version = "0.4.1", features = [ "async-connection-wrapper", "deadpool", @@ -24,9 +30,11 @@ diesel_migrations = "2" uuid = { version = "1.4", features = ["fast-rng", "v4", "serde"] } tokio = { version = "1", features = ["full"] } starknet_api = "0.4.1" -starknet = "0.6.0" +starknet = "0.8.0" deadpool = { version = "0.9.3", features = ["managed"] } futures = "0.3.28" prometheus = "0.13.3" lazy_static = "1.4.0" hyper = "0.14.27" +url = "2.5.0" +strum = { version = "0.25.0", features = ["derive"] } diff --git a/README.md b/README.md index 89223e6..bfe32eb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ -# pragma-monitoring +# Pragma Monitoring + +## Prometheus Service + +This service runs a prometheus server that returns metrics on the `/metrics` route. + +It powers our internal grafana dashboards and alerts. diff --git a/src/config.rs b/src/config.rs index 8b13789..edfa707 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1 +1,225 @@ +use std::{collections::HashMap, sync::Arc}; +use starknet::{ + core::{ + types::{BlockId, BlockTag, FieldElement, FunctionCall}, + utils::cairo_short_string_to_felt, + }, + macros::selector, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, +}; +use strum::EnumString; +use url::Url; + +// https://blastapi.io/public-api/starknet +const DEFAULT_MAINNET_RPC_URL: &str = "https://starknet-mainnet.public.blastapi.io"; +const DEFAULT_TESTNET_RPC_URL: &str = "https://starknet-sepolia.public.blastapi.io"; + +#[derive(Debug, EnumString)] +pub enum NetworkName { + #[strum(ascii_case_insensitive)] + Mainnet, + #[strum(ascii_case_insensitive)] + Testnet, +} + +#[derive(Debug, Clone)] +pub struct Network { + pub name: String, + pub provider: Arc>, + pub oracle_address: FieldElement, + pub publisher_registry_address: FieldElement, +} + +#[derive(Debug, Clone)] +pub struct Config { + pub pairs: Vec, + pub sources: HashMap>, // Mapping from pair to sources + pub decimals: HashMap, // Mapping from pair to decimals + pub publishers: Vec, + pub network: Network, +} + +impl Config { + pub async fn new( + network: NetworkName, + oracle_address: FieldElement, + pairs: Vec, + ) -> Self { + match network { + NetworkName::Mainnet => { + // Create RPC Client + let rpc_url = + std::env::var("MAINNET_RPC_URL").unwrap_or(DEFAULT_MAINNET_RPC_URL.to_string()); + let rpc_client = + JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); + + let (decimals, sources, publishers, publisher_registry_address) = + init_oracle_config(&rpc_client, oracle_address, pairs.clone()).await; + + Self { + pairs, + sources, + publishers, + decimals, + network: Network { + name: "mainnet".to_string(), + provider: Arc::new(rpc_client), + oracle_address, + publisher_registry_address, + }, + } + } + NetworkName::Testnet => { + // Create RPC Client + let rpc_url = + std::env::var("TESTNET_RPC_URL").unwrap_or(DEFAULT_TESTNET_RPC_URL.to_string()); + let rpc_client = + JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); + + let (decimals, sources, publishers, publisher_registry_address) = + init_oracle_config(&rpc_client, oracle_address, pairs.clone()).await; + + Self { + pairs, + sources, + publishers, + decimals, + network: Network { + name: "testnet".to_string(), + provider: Arc::new(rpc_client), + oracle_address, + publisher_registry_address, + }, + } + } + } + } +} + +async fn init_oracle_config( + rpc_client: &JsonRpcClient, + oracle_address: FieldElement, + pairs: Vec, +) -> ( + HashMap, + HashMap>, + Vec, + FieldElement, +) { + // Fetch publisher registry address + let publisher_registry_address = *rpc_client + .call( + FunctionCall { + contract_address: oracle_address, + entry_point_selector: selector!("get_publisher_registry_address"), + calldata: vec![], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to call contract") + .first() + .unwrap(); + + // Fetch publishers + let publishers = rpc_client + .call( + FunctionCall { + contract_address: publisher_registry_address, + entry_point_selector: selector!("get_all_publishers"), + calldata: vec![], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to get publishers") + .into_iter() + .map(|publisher| publisher.to_string()) + .collect(); + + let mut sources: HashMap> = HashMap::new(); + let mut decimals: HashMap = HashMap::new(); + + for pair in &pairs { + let field_pair = cairo_short_string_to_felt(pair).unwrap(); + + // Fetch decimals + let spot_decimals = *rpc_client + .call( + FunctionCall { + contract_address: oracle_address, + entry_point_selector: selector!("get_decimals"), + calldata: vec![FieldElement::ZERO, field_pair], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to get decimals") + .first() + .unwrap(); + + // TODO: support future pairs + let _future_decimals = *rpc_client + .call( + FunctionCall { + contract_address: oracle_address, + entry_point_selector: selector!("get_decimals"), + calldata: vec![FieldElement::ONE, field_pair, FieldElement::ZERO], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to get decimals") + .first() + .unwrap(); + + decimals.insert(pair.to_string(), spot_decimals.try_into().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], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to get pair 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], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to get pair sources"); + + // Store all sources for the given pair + let mut pair_sources = Vec::new(); + for source in [spot_pair_sources, future_pair_sources].concat() { + if !pair_sources.contains(&source.to_string()) { + pair_sources.push(source.to_string()); + } + } + + sources.insert(pair.to_string(), pair_sources); + } + + (decimals, sources, publishers, publisher_registry_address) +} + +/// Parse pairs from a comma separated string. +/// e.g BTC/USD,ETH/USD +pub fn parse_pairs(pairs: &str) -> Vec { + pairs + .split(',') + .map(|pair| pair.to_string()) + .collect::>() +} diff --git a/src/error.rs b/src/error.rs index e4f8cca..9ca1dc0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,7 +3,6 @@ use std::{error::Error as StdError, fmt}; #[derive(Debug)] pub enum MonitoringError { Price(String), - Time(String), Database(diesel::result::Error), Connection(String), } @@ -14,7 +13,6 @@ impl fmt::Display for MonitoringError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MonitoringError::Price(e) => write!(f, "Price Error: {}", e), - MonitoringError::Time(e) => write!(f, "Time Error: {}", e), MonitoringError::Database(e) => write!(f, "Database Error: {}", e), MonitoringError::Connection(e) => write!(f, "Connection Error: {}", e), } diff --git a/src/main.rs b/src/main.rs index 446e20e..eb2e564 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,18 @@ extern crate diesel; extern crate dotenv; +use config::parse_pairs; +use config::Config; +use config::NetworkName; use diesel_async::pooled_connection::deadpool::*; use diesel_async::pooled_connection::AsyncDieselConnectionManager; use dotenv::dotenv; +use starknet::core::types::FieldElement; use std::env; +use std::str::FromStr; +// Configuration +mod config; // Error handling mod error; // Database models @@ -25,20 +32,16 @@ async fn main() { dotenv().ok(); // Define the pairs to monitor - let pairs = vec![ - ("BTC/USD", "CEX", 8), - ("ETH/USD", "CEX", 8), - ("BTC/USD", "COINBASE", 8), - ("ETH/USD", "COINBASE", 8), - ("BTC/USD", "BITSTAMP", 8), - ("ETH/USD", "BITSTAMP", 8), - ("BTC/USD", "OKX", 8), - ("ETH/USD", "OKX", 8), - ("BTC/USD", "GECKOTERMINAL", 8), - ("ETH/USD", "GECKOTERMINAL", 8), - ("BTC/USD", "KAIKO", 8), - ("ETH/USD", "KAIKO", 8), - ]; + let network = std::env::var("NETWORK").expect("NETWORK must be set"); + let oracle_address = std::env::var("ORACLE_ADDRESS").expect("ORACLE_ADDRESS must be set"); + let pairs = std::env::var("PAIRS").expect("PAIRS must be set"); + + let monitoring_config = Config::new( + NetworkName::from_str(&network).expect("Invalid network name"), + FieldElement::from_hex_be(&oracle_address).expect("Invalid oracle address"), + parse_pairs(&pairs), + ) + .await; tokio::spawn(server::run_metrics_server()); @@ -51,21 +54,21 @@ async fn main() { loop { interval.tick().await; // Wait for the next tick - let tasks: Vec<_> = pairs + let tasks: Vec<_> = monitoring_config .clone() + .sources .into_iter() - .flat_map(|(pair, srce, decimals)| { + .flat_map(|(pair, sources)| { vec![ tokio::spawn(Box::pin(process_data::process_data_by_pair( pool.clone(), - pair, - decimals, + pair.clone(), ))), - tokio::spawn(Box::pin(process_data::process_data_by_pair_and_source( + tokio::spawn(Box::pin(process_data::process_data_by_pair_and_sources( pool.clone(), - pair, - srce, - decimals, + pair.clone(), + sources, + *monitoring_config.decimals.get(&pair.clone()).unwrap(), ))), ] }) diff --git a/src/monitoring/mod.rs b/src/monitoring/mod.rs index 3de5ef7..a7cf25a 100644 --- a/src/monitoring/mod.rs +++ b/src/monitoring/mod.rs @@ -1,2 +1 @@ -pub mod time_last_update_pair_id; -pub mod time_last_update_source; +pub mod time_since_last_update; diff --git a/src/monitoring/time_last_update_pair_id.rs b/src/monitoring/time_last_update_pair_id.rs deleted file mode 100644 index f2ed8b6..0000000 --- a/src/monitoring/time_last_update_pair_id.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::models::SpotEntry; -use chrono::{DateTime, TimeZone, Utc}; -use std::time::SystemTime; -pub async fn time_last_update_pair_id(query: &SpotEntry) -> u64 { - let datetime: DateTime = TimeZone::from_utc_datetime(&Utc, &query.timestamp.unwrap()); - let timestamp = datetime.timestamp(); - let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH); - now.unwrap().as_secs() - timestamp as u64 -} diff --git a/src/monitoring/time_last_update_source.rs b/src/monitoring/time_since_last_update.rs similarity index 75% rename from src/monitoring/time_last_update_source.rs rename to src/monitoring/time_since_last_update.rs index 2ce0410..d56e26b 100644 --- a/src/monitoring/time_last_update_source.rs +++ b/src/monitoring/time_since_last_update.rs @@ -2,9 +2,11 @@ use crate::models::SpotEntry; use chrono::{DateTime, TimeZone, Utc}; use std::time::SystemTime; -pub async fn time_since_last_update(query: &SpotEntry) -> u64 { +/// Calculate the time since the last update in seconds. +pub fn time_since_last_update(query: &SpotEntry) -> u64 { let datetime: DateTime = TimeZone::from_utc_datetime(&Utc, &query.timestamp.unwrap()); let timestamp = datetime.timestamp(); let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH); + now.unwrap().as_secs() - timestamp as u64 } diff --git a/src/process_data.rs b/src/process_data.rs index 1d50aaf..bfd098e 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -4,8 +4,7 @@ extern crate dotenv; use crate::diesel::QueryDsl; use crate::error::MonitoringError; use crate::models::SpotEntry; -use crate::monitoring::time_last_update_pair_id::time_last_update_pair_id; -use crate::monitoring::time_last_update_source::time_since_last_update; +use crate::monitoring::time_since_last_update::time_since_last_update; use crate::schema::spot_entry::dsl::*; use bigdecimal::ToPrimitive; @@ -18,7 +17,7 @@ use prometheus::{opts, register_gauge_vec, GaugeVec}; lazy_static::lazy_static! { static ref TIME_SINCE_LAST_UPDATE_SOURCE: GaugeVec = register_gauge_vec!( opts!("time_since_last_update_seconds", "Time since the last update in seconds."), - &["pair", "source"] + &["source"] ).unwrap(); } @@ -38,8 +37,7 @@ lazy_static::lazy_static! { pub async fn process_data_by_pair( pool: deadpool::managed::Pool>, - pair: &str, - decimals: u32, + pair: String, ) -> Result { let mut conn = pool .get() @@ -47,22 +45,40 @@ pub async fn process_data_by_pair( .map_err(|_| MonitoringError::Connection("Failed to get connection".to_string()))?; let result: Result = spot_entry - .filter(pair_id.eq(pair)) + .filter(pair_id.eq(pair.clone())) .order(block_timestamp.desc()) .first(&mut conn) .await; match result { Ok(data) => { - let minute_since_last_publish = time_last_update_pair_id(&data).await; - let time_labels = TIME_SINCE_LAST_UPDATE_PAIR_ID.with_label_values(&[pair]); - time_labels.set(minute_since_last_publish as f64); - Ok(minute_since_last_publish) + let seconds_since_last_publish = time_since_last_update(&data); + let time_labels = TIME_SINCE_LAST_UPDATE_PAIR_ID.with_label_values(&[&pair]); + + time_labels.set(seconds_since_last_publish as f64); + + Ok(seconds_since_last_publish) } Err(e) => Err(e.into()), } } +pub async fn process_data_by_pair_and_sources( + pool: deadpool::managed::Pool>, + pair: String, + sources: Vec, + decimals: u32, +) -> Result { + let mut timestamps = Vec::new(); + + for src in sources { + let res = process_data_by_pair_and_source(pool.clone(), &pair, &src, decimals).await?; + timestamps.push(res); + } + + Ok(*timestamps.last().unwrap()) +} + pub async fn process_data_by_pair_and_source( pool: deadpool::managed::Pool>, pair: &str, @@ -73,9 +89,7 @@ pub async fn process_data_by_pair_and_source( .get() .await .map_err(|_| MonitoringError::Connection("Failed to get connection".to_string()))?; - let filtered_by_source_result: Result = spot_entry - .filter(pair_id.eq(pair)) .filter(source.eq(src)) .order(block_timestamp.desc()) .first(&mut conn) @@ -83,15 +97,18 @@ pub async fn process_data_by_pair_and_source( match filtered_by_source_result { Ok(data) => { - let time = time_since_last_update(&data).await; - let time_labels = TIME_SINCE_LAST_UPDATE_SOURCE.with_label_values(&[pair, src]); + let time = time_since_last_update(&data); + + let time_labels = TIME_SINCE_LAST_UPDATE_SOURCE.with_label_values(&[src]); let price_labels = PAIR_PRICE.with_label_values(&[pair, src]); + let price_as_f64 = data.price.to_f64().ok_or(MonitoringError::Price( - "Failed to convert BigDecimal to f64".to_string(), + "Failed to convert price to f64".to_string(), ))?; - let dec: i32 = 10; - price_labels.set(price_as_f64 / (dec.pow(decimals)) as f64); + + price_labels.set(price_as_f64 / (10_u64.pow(decimals)) as f64); time_labels.set(time as f64); + Ok(time) } Err(e) => Err(e.into()), diff --git a/src/server.rs b/src/server.rs index 17d72d5..7e34084 100644 --- a/src/server.rs +++ b/src/server.rs @@ -26,6 +26,7 @@ async fn metrics_handler() -> hyper::Response { let mut buffer = vec![]; let encoder = TextEncoder::new(); let metric_families = prometheus::gather(); + encoder.encode(&metric_families, &mut buffer).unwrap(); hyper::Response::builder() From 763d53b080320aeb6ff88c7656c0571427953d13 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 16:46:14 +0100 Subject: [PATCH 03/13] feat: price deviation from coingecko --- Cargo.lock | 212 +++++++++++++++++++++++++++++- Cargo.toml | 2 + src/constants.rs | 7 + src/error.rs | 2 + src/main.rs | 2 + src/monitoring/mod.rs | 1 + src/monitoring/price_deviation.rs | 31 +++++ src/process_data.rs | 45 +++++-- 8 files changed, 291 insertions(+), 11 deletions(-) create mode 100644 src/constants.rs create mode 100644 src/monitoring/price_deviation.rs diff --git a/Cargo.lock b/Cargo.lock index 3060085..82b4784 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -832,6 +832,19 @@ dependencies = [ "inout", ] +[[package]] +name = "coingecko" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b24c2d346c689c0b8a27d4c921a35d8cac68cc266130bc82ba879155ca828da0" +dependencies = [ + "chrono", + "reqwest", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "colored" version = "2.0.4" @@ -1253,6 +1266,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "finl_unicode" version = "1.2.0" @@ -1293,6 +1312,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1597,6 +1631,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1962,6 +2009,7 @@ dependencies = [ "axum-macros", "bigdecimal 0.4.1", "chrono", + "coingecko", "deadpool", "diesel", "diesel-async", @@ -1972,6 +2020,7 @@ dependencies = [ "hyper", "lazy_static", "num-bigint", + "phf", "prometheus", "starknet", "starknet_api", @@ -1999,6 +2048,24 @@ dependencies = [ "version_check", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndarray" version = "0.13.1" @@ -2099,6 +2166,50 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "openssl" +version = "0.10.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +dependencies = [ + "bitflags 2.4.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parity-scale-codec" version = "3.6.5" @@ -2215,8 +2326,32 @@ name = "phf" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared 0.11.2", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.38", ] [[package]] @@ -2275,6 +2410,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "postgres-protocol" version = "0.6.6" @@ -2471,6 +2612,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -2539,10 +2689,12 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -2553,6 +2705,7 @@ dependencies = [ "serde_urlencoded", "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls", "tower-service", "url", @@ -2633,9 +2786,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.18" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.0", "errno", @@ -2725,6 +2878,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + [[package]] name = "schemars" version = "0.8.15" @@ -2788,6 +2950,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.20" @@ -3339,6 +3524,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys", +] + [[package]] name = "term" version = "0.7.0" @@ -3452,6 +3650,16 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-postgres" version = "0.7.10" diff --git a/Cargo.toml b/Cargo.toml index 4aeaa6a..38d07e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,3 +38,5 @@ lazy_static = "1.4.0" hyper = "0.14.27" url = "2.5.0" strum = { version = "0.25.0", features = ["derive"] } +coingecko = "1.0.1" +phf = { version = "0.11", features = ["macros"] } diff --git a/src/constants.rs b/src/constants.rs new file mode 100644 index 0000000..8cbe980 --- /dev/null +++ b/src/constants.rs @@ -0,0 +1,7 @@ +use phf::phf_map; + +pub(crate) static COINGECKO_IDS: phf::Map<&'static str, &'static str> = phf_map! { + "BTC/USD" => "bitcoin", + "ETH/USD" => "ethereum", + "LUSD/USD" => "liquity-usd", +}; diff --git a/src/error.rs b/src/error.rs index 9ca1dc0..4653b8c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,6 +5,7 @@ pub enum MonitoringError { Price(String), Database(diesel::result::Error), Connection(String), + Api(String), } impl StdError for MonitoringError {} @@ -15,6 +16,7 @@ impl fmt::Display for MonitoringError { MonitoringError::Price(e) => write!(f, "Price Error: {}", e), MonitoringError::Database(e) => write!(f, "Database Error: {}", e), MonitoringError::Connection(e) => write!(f, "Connection Error: {}", e), + MonitoringError::Api(e) => write!(f, "API Error: {}", e), } } } diff --git a/src/main.rs b/src/main.rs index eb2e564..a670fa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,8 @@ mod process_data; mod server; // Database schema mod schema; +// Constants +mod constants; #[tokio::main] async fn main() { diff --git a/src/monitoring/mod.rs b/src/monitoring/mod.rs index a7cf25a..524b3db 100644 --- a/src/monitoring/mod.rs +++ b/src/monitoring/mod.rs @@ -1 +1,2 @@ +pub mod price_deviation; pub mod time_since_last_update; diff --git a/src/monitoring/price_deviation.rs b/src/monitoring/price_deviation.rs new file mode 100644 index 0000000..cfd1acd --- /dev/null +++ b/src/monitoring/price_deviation.rs @@ -0,0 +1,31 @@ +use crate::{constants::COINGECKO_IDS, error::MonitoringError, models::SpotEntry}; +use bigdecimal::ToPrimitive; +use coingecko::CoinGeckoClient; + +/// Calculates the deviation of the price from a trusted API (Coingecko) +pub async fn price_deviation(query: &SpotEntry) -> Result { + let coingecko_client = CoinGeckoClient::default(); + + let ids = &COINGECKO_IDS; + + let pair_id = query.pair_id.to_string(); + let coingecko_id = *ids.get(&pair_id).expect("Failed to get coingecko id"); + + let coingecko_price = coingecko_client + .price(&[coingecko_id], &["USD"], false, false, false, true) + .await + .map_err(|e| MonitoringError::Api(e.to_string()))?; + + let published_price = query + .price + .to_f64() + .expect("Failed to convert price to f64"); + + let reference_price = coingecko_price + .get(coingecko_id) + .expect("Failed to get coingecko price") + .usd + .expect("Failed to get usd price"); + + Ok((published_price - reference_price) / reference_price) +} diff --git a/src/process_data.rs b/src/process_data.rs index bfd098e..24c8106 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -4,6 +4,7 @@ extern crate dotenv; use crate::diesel::QueryDsl; use crate::error::MonitoringError; use crate::models::SpotEntry; +use crate::monitoring::price_deviation::price_deviation; use crate::monitoring::time_since_last_update::time_since_last_update; use crate::schema::spot_entry::dsl::*; @@ -12,27 +13,48 @@ use diesel::ExpressionMethods; use diesel_async::pooled_connection::AsyncDieselConnectionManager; use diesel_async::AsyncPgConnection; use diesel_async::RunQueryDsl; +use lazy_static::lazy_static; use prometheus::{opts, register_gauge_vec, GaugeVec}; -lazy_static::lazy_static! { +lazy_static! { static ref TIME_SINCE_LAST_UPDATE_SOURCE: GaugeVec = register_gauge_vec!( - opts!("time_since_last_update_seconds", "Time since the last update in seconds."), + opts!( + "time_since_last_update_seconds", + "Time since the last update in seconds." + ), &["source"] - ).unwrap(); + ) + .unwrap(); } -lazy_static::lazy_static! { +lazy_static! { static ref PAIR_PRICE: GaugeVec = register_gauge_vec!( opts!("pair_price", "Price of the pair from the source."), &["pair", "source"] - ).unwrap(); + ) + .unwrap(); } -lazy_static::lazy_static! { +lazy_static! { static ref TIME_SINCE_LAST_UPDATE_PAIR_ID: GaugeVec = register_gauge_vec!( - opts!("time_since_last_update_pair_id", "Time since the last update in seconds."), + opts!( + "time_since_last_update_pair_id", + "Time since the last update in seconds." + ), &["pair"] - ).unwrap(); + ) + .unwrap(); +} + +lazy_static! { + static ref PRICE_DEVIATION: GaugeVec = register_gauge_vec!( + opts!( + "price_deviation", + "Price deviation from the reference price." + ), + &["pair", "source"] + ) + .unwrap(); } pub async fn process_data_by_pair( @@ -101,13 +123,18 @@ pub async fn process_data_by_pair_and_source( let time_labels = TIME_SINCE_LAST_UPDATE_SOURCE.with_label_values(&[src]); let price_labels = PAIR_PRICE.with_label_values(&[pair, src]); + let deviation_labels = PRICE_DEVIATION.with_label_values(&[pair, src]); let price_as_f64 = data.price.to_f64().ok_or(MonitoringError::Price( "Failed to convert price to f64".to_string(), ))?; + let normalized_price = price_as_f64 / (10_u64.pow(decimals)) as f64; + + let deviation = price_deviation(&data).await?; - price_labels.set(price_as_f64 / (10_u64.pow(decimals)) as f64); + price_labels.set(normalized_price); time_labels.set(time as f64); + deviation_labels.set(deviation); Ok(time) } From de2df210291bc080347111c0bf4b560c57708410 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 17:08:28 +0100 Subject: [PATCH 04/13] fix: logger --- Cargo.lock | 39 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 20 +++++++++++--------- src/main.rs | 6 ++++-- src/server.rs | 3 ++- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82b4784..80dd64c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1195,6 +1195,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1593,6 +1606,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.27" @@ -2016,9 +2035,11 @@ dependencies = [ "diesel_derives 1.4.1", "diesel_migrations", "dotenv", + "env_logger", "futures", "hyper", "lazy_static", + "log", "num-bigint", "phf", "prometheus", @@ -3548,6 +3569,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.49" @@ -4032,6 +4062,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 38d07e8..de29856 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,17 +12,17 @@ chrono = "0.4" bigdecimal = "0.4.1" num-bigint = "0.4" diesel = { version = "2.1.0", features = [ - "postgres", - "numeric", - "chrono", - "uuid", - "serde_json", + "postgres", + "numeric", + "chrono", + "uuid", + "serde_json", ] } diesel-async = { version = "0.4.1", features = [ - "async-connection-wrapper", - "deadpool", - "postgres", - "tokio", + "async-connection-wrapper", + "deadpool", + "postgres", + "tokio", ] } dotenv = "0.15.0" diesel_derives = "1.4.0" @@ -40,3 +40,5 @@ url = "2.5.0" strum = { version = "0.25.0", features = ["derive"] } coingecko = "1.0.1" phf = { version = "0.11", features = ["macros"] } +log = "0.4.20" +env_logger = "0.10.1" diff --git a/src/main.rs b/src/main.rs index a670fa7..dddcbee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,8 @@ mod constants; #[tokio::main] async fn main() { + env_logger::init(); + // Load environment variables from .env file dotenv().ok(); @@ -85,8 +87,8 @@ async fn main() { // Process or output the results for result in &results { match result { - Ok(data) => println!("Task succeeded with data: {:?}", data), - Err(e) => eprintln!("Task failed with error: {:?}", e), + Ok(data) => log::info!("Task succeeded with data: {:?}", data), + Err(e) => log::error!("Task failed with error: {:?}", e), } } } diff --git a/src/server.rs b/src/server.rs index 7e34084..a8f8809 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,5 +1,6 @@ use axum::{routing::get, Router}; use hyper::Server; +use log::info; use prometheus::{Encoder, TextEncoder}; use std::net::SocketAddr; @@ -10,7 +11,7 @@ pub async fn run_metrics_server() { let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); - println!("Listening on http://{}", addr); + info!("Server Started, listening on http://{}", addr); Server::bind(&addr) .serve(app.into_make_service()) From 3c277a6895257d987d7b08355c3d1281dd8c1cf6 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 17:29:04 +0100 Subject: [PATCH 05/13] feat: deviation from on-chain median --- Cargo.lock | 859 ++++++++++++++++------------- README.md | 2 +- src/main.rs | 2 +- src/monitoring/mod.rs | 1 + src/monitoring/source_deviation.rs | 46 ++ src/process_data.rs | 24 +- 6 files changed, 556 insertions(+), 378 deletions(-) create mode 100644 src/monitoring/source_deviation.rs diff --git a/Cargo.lock b/Cargo.lock index 80dd64c..454a76e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,7 +72,7 @@ dependencies = [ "digest", "itertools 0.10.5", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "paste", "rustc_version", "zeroize", @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "proc-macro2", "quote", "syn 1.0.109", @@ -118,7 +118,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "num-traits 0.2.16", + "num-traits 0.2.17", "rand", ] @@ -145,13 +145,13 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -232,7 +232,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -258,9 +258,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bigdecimal" @@ -270,21 +270,21 @@ checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "serde", ] [[package]] name = "bigdecimal" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "454bca3db10617b88b566f205ed190aedb0e0e6dd4cad61d3988a72e8c5594cb" +checksum = "c06619be423ea5bb86c95f087d5707942791a08a85530df0db2209a3ecfb8bc9" dependencies = [ "autocfg", "libm", "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", ] [[package]] @@ -310,9 +310,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "bitvec" @@ -368,20 +368,20 @@ dependencies = [ "lazy_static", "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "serde", ] [[package]] name = "cairo-lang-casm" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc7f7cb89bc3f52c2c738f3e87c8f8773bd3456cae1d322d100d4b0da584f3c" +checksum = "2850dc1d46d5bfb64c5ed0bc7ccd4821e4d4c36a8f2678a897df7c2bfaefe6fc" dependencies = [ "cairo-lang-utils", "indoc", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "parity-scale-codec", "parity-scale-codec-derive", "schemars", @@ -391,9 +391,9 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4f2c54b065f7fd97bf8d5df76cbcbbd01d8a8c319d281796ee20ecc48e16ca8" +checksum = "2e6360b6735eeff503c6103520fef7410ca2c5a5ae90584822baa326607721ac" dependencies = [ "anyhow", "cairo-lang-defs", @@ -401,7 +401,6 @@ dependencies = [ "cairo-lang-filesystem", "cairo-lang-lowering", "cairo-lang-parser", - "cairo-lang-plugins", "cairo-lang-project", "cairo-lang-semantic", "cairo-lang-sierra", @@ -409,26 +408,24 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "itertools 0.11.0", - "log", "salsa", - "smol_str", "thiserror", ] [[package]] name = "cairo-lang-debug" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873ba77d4c3f780c727c7d6c738cded22b3f6d4023e30546dfe14f97a087887e" +checksum = "0c190deb7ba826a462fa7339e482d5e2df78d329435f4988b15f7752e033b5ac" dependencies = [ "cairo-lang-utils", ] [[package]] name = "cairo-lang-defs" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5031fff038c27ed43769b73a6f5d41aeaea34df9af862e024c23fbb4f076249" +checksum = "b42a34d9952b04fa0c96fafd08d170097fb5075ff81826a034ef9faa70556de8" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -436,7 +433,6 @@ dependencies = [ "cairo-lang-parser", "cairo-lang-syntax", "cairo-lang-utils", - "indexmap 2.0.2", "itertools 0.11.0", "salsa", "smol_str", @@ -444,34 +440,31 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b6cb1492e5784e1076320a5018ce7584f391b2f3b414bc0a8ab7c289fa118ce" +checksum = "c399832f9fc462cd51687a415c391ead4b99ee48c54cad5c8e1d5004ff6520c7" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-utils", "itertools 0.11.0", - "salsa", ] [[package]] name = "cairo-lang-eq-solver" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35dddbc63b2a4870891cc74498726aa32bfaa518596352f9bb101411cc4c584" +checksum = "d73846e0dec2a204bc429f7421020fc6a98ae48f20f0cfa2aa1091b78221d6ce" dependencies = [ "cairo-lang-utils", "good_lp", - "indexmap 2.0.2", - "itertools 0.11.0", ] [[package]] name = "cairo-lang-filesystem" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ce0b8e66a6085ae157d43b5c162d60166f0027d6f125c50ee74e4dc7916ff6" +checksum = "64f15f4a10963dcd5baa0386632c5ce4136d54f93d6c71cc16a49cbcbf774ee2" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -483,9 +476,9 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cc679f501725e03ee703559ed27d084c6f4031bd51ff86378cf845a85ee207" +checksum = "5547bb3e13841a840b4faad3eb7fe7c39b525220f708973b71b1b9077747758b" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -497,11 +490,11 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "id-arena", - "indexmap 2.0.2", + "indexmap 2.1.0", "itertools 0.11.0", "log", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "once_cell", "salsa", "smol_str", @@ -509,9 +502,9 @@ dependencies = [ [[package]] name = "cairo-lang-parser" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcadb046659134466bc7e11961ea8a56969dae8a54d8f985955ce0b95185c7f" +checksum = "197445f8db467e28dbeddc573047dd8f2a0ef3fcc3d1c32575162d4cf79988df" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -520,9 +513,8 @@ dependencies = [ "cairo-lang-utils", "colored", "itertools 0.11.0", - "log", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "salsa", "smol_str", "unescaper", @@ -530,9 +522,9 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4632790cd4ea11d4849934456a400eae7ed419f6d721f24a6b637df67b7e902f" +checksum = "9c3ea747577bd93e4791bdd57744dfddbc4b99ce056fffb5fd41340759642f91" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -543,41 +535,40 @@ dependencies = [ "indent", "indoc", "itertools 0.11.0", - "num-bigint", "salsa", "smol_str", ] [[package]] name = "cairo-lang-proc-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170838817fc33ddb65e0a9480526df0b226b148a0fca0a5cd7071be4c6683157" +checksum = "c8cc59c40344194d2cc825071080d887826dcf0df37de71e58fc8aa4c344bb84" dependencies = [ "cairo-lang-debug", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "cairo-lang-project" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4162ee976c61fdeb3b621f4a76fd256e46a5c0890f750a3a9d2c9560a3bc1daf" +checksum = "312b65dec1d0b8e1b420d7b464c0c771f18301177376432681c05c30f5ef9604" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", "serde", "smol_str", "thiserror", - "toml", + "toml 0.8.8", ] [[package]] name = "cairo-lang-semantic" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e544fa9a222bf2d007df2b5fc9b21c2a20ab7e17d6fefbcbc193de209451cd" +checksum = "7e18c57cd10bcf69b427b901ce058268d21f65f5199b33e36b72b02ba7ceff74" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -589,10 +580,10 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "id-arena", + "indoc", "itertools 0.11.0", - "log", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "once_cell", "salsa", "smol_str", @@ -600,10 +591,11 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e136b79e95a14ef38a2be91a67ceb85317407d336a5b0d418c33b23c78596a" +checksum = "84cf029a71e0176992cc401f7f182dc92e14a51662b1576240a7ecc79efac6bc" dependencies = [ + "anyhow", "cairo-lang-utils", "const-fnv1a-hash", "convert_case 0.6.0", @@ -612,10 +604,11 @@ dependencies = [ "lalrpop", "lalrpop-util", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "regex", "salsa", "serde", + "serde_json", "sha3", "smol_str", "thiserror", @@ -623,9 +616,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511ca7708faa7ba8d14ae26e1d60ead2d02028c8f664baf5ecb0fd6a0d1e20f6" +checksum = "529ed2d8d14ef4c2d77e45db597425488e194b8ab1d3210742a1c54d78743407" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -637,9 +630,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a25bc010b910919c01d5c57e937b0c3d330fc30d92702c0cb4061819df8df" +checksum = "d0cbe3dd4f663d7df902a2f10cf52990d62f178741fe1494de51f08bb89b7aa6" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -651,9 +644,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114091bb971c06fd072aca816af1c3f62566cd8a4b1453c786155161a36c7bce" +checksum = "6c5bed52b240e1546b08e075493b2df4030dba2199e019d36f52da1423f2c653" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -661,14 +654,11 @@ dependencies = [ "cairo-lang-filesystem", "cairo-lang-lowering", "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-proc-macros", "cairo-lang-semantic", "cairo-lang-sierra", "cairo-lang-syntax", "cairo-lang-utils", - "id-arena", - "indexmap 2.0.2", + "indexmap 2.1.0", "itertools 0.11.0", "num-bigint", "once_cell", @@ -678,9 +668,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1c799de62972dfd7112d563000695be94305b6f7d9bedd29f347799bf03e1c" +checksum = "fc16661a7a78f885f6b5a4fdb3c7463d9ee3f6bca83266b4f2b956e65579ec72" dependencies = [ "assert_matches", "cairo-felt", @@ -692,17 +682,16 @@ dependencies = [ "cairo-lang-utils", "indoc", "itertools 0.11.0", - "log", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "thiserror", ] [[package]] name = "cairo-lang-sierra-type-size" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fe73d9d58aaf9088f6ba802bcf43ce9ca4bd198190cf5bf91caa7d408dd11a" +checksum = "9f3fa025f6bc1c8d4556c9fc4609fb6f27071470ed47eb3bd0b5f9a159e51124" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -710,9 +699,9 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75df624e71e33a31a924e799dd2a9a8284204b41d8db9c51803317bd9edff81f" +checksum = "ac5523d9c5b8e7c98afb2907c2cf4821a251d94fc42d37940063a9f2adbea05f" dependencies = [ "anyhow", "cairo-felt", @@ -722,55 +711,50 @@ dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-plugins", "cairo-lang-semantic", "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-gas", "cairo-lang-sierra-generator", "cairo-lang-sierra-to-casm", "cairo-lang-syntax", "cairo-lang-utils", + "const_format", "convert_case 0.6.0", - "genco", "indent", "indoc", "itertools 0.11.0", - "log", "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "once_cell", "serde", "serde_json", "sha3", "smol_str", + "starknet-crypto 0.6.1", "thiserror", ] [[package]] name = "cairo-lang-syntax" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1af0ae21f9e539f97cfdf56f5ce0934dae5d87f568fd778c3d624a102f8dbb" +checksum = "8c8e9b19fa724135353470ee3452605f82edfec17a7dd4e8388d77152ea4fbd2" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-utils", "num-bigint", - "num-traits 0.2.16", + "num-traits 0.2.17", "salsa", "smol_str", - "thiserror", "unescaper", ] [[package]] name = "cairo-lang-syntax-codegen" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ffabf24f6a5506262edcece315260a82d9dfba3abe6548791a6d654563ad0" +checksum = "7a50c3a5dc5d890a523122e40dac59f3a430952cec73fe7312dd266ad865f049" dependencies = [ "genco", "xshell", @@ -778,15 +762,14 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f974b6e859f0b09c0f13ec8188c96e9e8bbb5da04214f911dbb5bcda67cb812b" +checksum = "88969fe46417affe9628bd039865693431837807eb981115f02756a35f488489" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "itertools 0.11.0", "num-bigint", - "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "parity-scale-codec", "schemars", "serde", @@ -816,10 +799,10 @@ dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", - "num-traits 0.2.16", + "num-traits 0.2.17", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -847,13 +830,12 @@ dependencies = [ [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -862,6 +844,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -879,9 +881,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -889,15 +891,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -913,9 +915,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" dependencies = [ "cfg-if", ] @@ -928,9 +930,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "subtle", @@ -977,7 +979,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -988,7 +990,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -1012,10 +1014,11 @@ checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ + "powerfmt", "serde", ] @@ -1045,22 +1048,22 @@ dependencies = [ [[package]] name = "diesel" -version = "2.1.3" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2268a214a6f118fce1838edba3d1561cf0e78d8de785475957a580a7f8c69d33" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" dependencies = [ - "bigdecimal 0.4.1", - "bitflags 2.4.0", + "bigdecimal 0.4.2", + "bitflags 2.4.1", "byteorder", "chrono", "diesel_derives 2.1.2", "itoa", "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "pq-sys", "serde_json", - "uuid 1.4.1", + "uuid 1.6.1", ] [[package]] @@ -1098,7 +1101,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -1118,7 +1121,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -1167,9 +1170,9 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "either" @@ -1216,12 +1219,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1311,9 +1314,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -1357,9 +1360,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -1372,9 +1375,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -1382,15 +1385,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -1399,38 +1402,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -1446,9 +1449,9 @@ dependencies = [ [[package]] name = "genco" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fd234893ffe9cf5b81224ebb1d21bbe2eeb94d95bac3ea25c97cba7293304d" +checksum = "98d7af598790738fee616426e669360fa361273b1b9c9b7f30c92fa627605cad" dependencies = [ "genco-macros", "relative-path", @@ -1457,13 +1460,13 @@ dependencies = [ [[package]] name = "genco-macros" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1c8cd3de2f32ee05ba2adaa90f8d0c354ffa0adeb2d186978d7ae70e5025e9" +checksum = "d4cf186fea4af17825116f72932fe52cce9a13bae39ff63b4dc0cfdb3fb4bde1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -1478,9 +1481,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "js-sys", @@ -1491,9 +1494,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "good_lp" @@ -1507,9 +1510,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -1517,7 +1520,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1532,9 +1535,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -1574,9 +1577,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1585,9 +1588,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1629,7 +1632,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -1638,9 +1641,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -1665,16 +1668,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1765,12 +1768,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "serde", ] @@ -1800,9 +1803,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" @@ -1812,7 +1815,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1835,15 +1838,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1900,9 +1903,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libm" @@ -1910,17 +1913,28 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1970,7 +1984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" dependencies = [ "serde", - "toml", + "toml 0.7.8", ] [[package]] @@ -2011,13 +2025,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2026,7 +2040,7 @@ version = "0.1.0" dependencies = [ "axum", "axum-macros", - "bigdecimal 0.4.1", + "bigdecimal 0.4.2", "chrono", "coingecko", "deadpool", @@ -2048,7 +2062,7 @@ dependencies = [ "strum", "tokio", "url", - "uuid 1.4.1", + "uuid 1.6.1", ] [[package]] @@ -2096,7 +2110,7 @@ dependencies = [ "matrixmultiply", "num-complex", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "rawpointer", ] @@ -2114,7 +2128,7 @@ checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "serde", ] @@ -2125,7 +2139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ "autocfg", - "num-traits 0.2.16", + "num-traits 0.2.17", ] [[package]] @@ -2135,7 +2149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", - "num-traits 0.2.16", + "num-traits 0.2.17", ] [[package]] @@ -2144,14 +2158,14 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" dependencies = [ - "num-traits 0.2.16", + "num-traits 0.2.17", ] [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -2177,9 +2191,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -2193,7 +2207,7 @@ version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -2210,7 +2224,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2233,9 +2247,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec", "bitvec", @@ -2247,9 +2261,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2275,7 +2289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", + "parking_lot_core 0.9.9", ] [[package]] @@ -2294,15 +2308,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -2339,7 +2353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.1.0", ] [[package]] @@ -2372,7 +2386,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2416,7 +2430,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2443,7 +2457,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "byteorder", "bytes", "fallible-iterator", @@ -2466,6 +2480,12 @@ dependencies = [ "postgres-protocol", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2489,9 +2509,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", @@ -2502,12 +2522,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "once_cell", - "toml_edit", + "toml_edit 0.20.7", ] [[package]] @@ -2536,9 +2555,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.68" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1106fec09662ec6dd98ccac0f81cef56984d0b49f75c92d8cbad76e20c005c" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -2624,15 +2643,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -2644,36 +2654,36 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.10.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.0", + "regex-syntax 0.8.2", ] [[package]] name = "regex-automata" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.0", + "regex-syntax 0.8.2", ] [[package]] @@ -2684,9 +2694,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "relative-path" @@ -2700,7 +2710,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -2755,17 +2765,16 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.20" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", + "getrandom", "libc", - "once_cell", - "spin 0.5.2", + "spin 0.9.8", "untrusted", - "web-sys", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2807,22 +2816,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", @@ -2832,18 +2841,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", ] [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", "untrusted", @@ -2857,9 +2866,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "salsa" @@ -2905,14 +2914,14 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -2923,9 +2932,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -2963,9 +2972,9 @@ dependencies = [ [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", "untrusted", @@ -3017,7 +3026,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3033,9 +3042,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -3065,9 +3074,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] @@ -3109,7 +3118,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3159,9 +3168,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smol_str" @@ -3174,9 +3183,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -3184,12 +3193,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3266,7 +3275,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff50e281d4fdb97988a3d5c7b7cae22b9d67bb2ef9be2cfafc17a1e35542cb53" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "flate2", "hex", "serde", @@ -3280,16 +3289,16 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693e6362f150f9276e429a910481fb7f3bcb8d6aa643743f587cfece0b374874" +checksum = "d3f2175b0b3fc24ff2ec6dc07f5a720498994effca7e78b11a6e1c1bd02cad52" dependencies = [ "crypto-bigint", "hex", "hmac", "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "rfc6979", "sha2", "starknet-crypto-codegen", @@ -3309,7 +3318,7 @@ dependencies = [ "hmac", "num-bigint", "num-integer", - "num-traits 0.2.16", + "num-traits 0.2.17", "rfc6979", "sha2", "starknet-crypto-codegen", @@ -3326,7 +3335,7 @@ checksum = "af6527b845423542c8a16e060ea1bc43f67229848e7cd4c4d80be994a84220ce" dependencies = [ "starknet-curve 0.4.0", "starknet-ff", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3369,7 +3378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "840be1a7eb5735863eee47d3a3f26df45b9be2c519e8da294e74b4d0524d77d1" dependencies = [ "starknet-core", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3422,7 +3431,7 @@ dependencies = [ "primitive-types", "serde", "serde_json", - "starknet-crypto 0.5.1", + "starknet-crypto 0.5.2", "thiserror", ] @@ -3481,7 +3490,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3503,9 +3512,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -3555,7 +3564,7 @@ dependencies = [ "fastrand", "redox_syscall 0.4.1", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3580,32 +3589,33 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "time" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -3652,9 +3662,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -3664,20 +3674,20 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3710,7 +3720,7 @@ dependencies = [ "postgres-protocol", "postgres-types", "rand", - "socket2 0.5.4", + "socket2 0.5.5", "tokio", "tokio-util", "whoami", @@ -3728,9 +3738,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3749,14 +3759,26 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.21.0", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -3767,7 +3789,31 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", @@ -3804,11 +3850,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-core", @@ -3816,18 +3861,18 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" @@ -3849,18 +3894,18 @@ dependencies = [ [[package]] name = "unescaper" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96a44ae11e25afb520af4534fd7b0bd8cd613e35a78def813b8cf41631fa3c8" +checksum = "d8f0f68e58d297ba8b22b8b5a96a87b863ba6bb46aaf51e19a4b02c5a6dd5b7f" dependencies = [ "thiserror", ] [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -3891,9 +3936,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" @@ -3918,9 +3963,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.4.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "getrandom", "rand", @@ -3956,9 +4001,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3966,24 +4011,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -3993,9 +4038,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4003,28 +4048,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4032,9 +4077,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "whoami" @@ -4078,12 +4123,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -4092,7 +4137,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -4101,13 +4155,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -4116,47 +4185,89 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" -version = "0.5.16" +version = "0.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" +checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" dependencies = [ "memchr", ] @@ -4168,7 +4279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4197,9 +4308,9 @@ checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -4212,5 +4323,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.41", ] diff --git a/README.md b/README.md index bfe32eb..c63aa95 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,4 @@ This service runs a prometheus server that returns metrics on the `/metrics` route. It powers our internal grafana dashboards and alerts. - + \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index dddcbee..b3803a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,7 +72,7 @@ async fn main() { pool.clone(), pair.clone(), sources, - *monitoring_config.decimals.get(&pair.clone()).unwrap(), + monitoring_config.clone(), ))), ] }) diff --git a/src/monitoring/mod.rs b/src/monitoring/mod.rs index 524b3db..30eb495 100644 --- a/src/monitoring/mod.rs +++ b/src/monitoring/mod.rs @@ -1,2 +1,3 @@ pub mod price_deviation; +pub mod source_deviation; pub mod time_since_last_update; diff --git a/src/monitoring/source_deviation.rs b/src/monitoring/source_deviation.rs new file mode 100644 index 0000000..1e0d982 --- /dev/null +++ b/src/monitoring/source_deviation.rs @@ -0,0 +1,46 @@ +use bigdecimal::ToPrimitive; +use num_bigint::ToBigInt; +use starknet::{ + core::{ + types::{BlockId, BlockTag, FieldElement, FunctionCall}, + utils::cairo_short_string_to_felt, + }, + macros::selector, + providers::Provider, +}; + +use crate::{config::Config, error::MonitoringError, models::SpotEntry}; + +/// Calculates the deviation from the on-chain price +pub async fn source_deviation(query: &SpotEntry, config: Config) -> Result { + let client = config.network.provider; + let field_pair = cairo_short_string_to_felt(&query.pair_id).expect("failed to convert pair id"); + + let on_chain_price = *client + .call( + FunctionCall { + contract_address: config.network.oracle_address, + entry_point_selector: selector!("get_data_median"), + calldata: vec![FieldElement::ZERO, field_pair], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to get median price") + .first() + .unwrap(); + + let decimals = config.decimals.get(&query.pair_id).unwrap(); + let on_chain_price = on_chain_price + .to_big_decimal(*decimals) + .to_bigint() + .unwrap(); + + let published_price = query.price.to_bigint().unwrap(); + + Ok( + ((published_price - on_chain_price.clone()) / on_chain_price) + .to_f64() + .unwrap(), + ) +} diff --git a/src/process_data.rs b/src/process_data.rs index 24c8106..e3c8968 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -1,10 +1,12 @@ extern crate diesel; extern crate dotenv; +use crate::config::Config; use crate::diesel::QueryDsl; use crate::error::MonitoringError; use crate::models::SpotEntry; use crate::monitoring::price_deviation::price_deviation; +use crate::monitoring::source_deviation::source_deviation; use crate::monitoring::time_since_last_update::time_since_last_update; use crate::schema::spot_entry::dsl::*; @@ -57,6 +59,17 @@ lazy_static! { .unwrap(); } +lazy_static! { + static ref PRICE_DEVIATION_SOURCE: GaugeVec = register_gauge_vec!( + opts!( + "price_deviation_source", + "Price deviation from the reference price." + ), + &["source"] + ) + .unwrap(); +} + pub async fn process_data_by_pair( pool: deadpool::managed::Pool>, pair: String, @@ -89,12 +102,15 @@ pub async fn process_data_by_pair_and_sources( pool: deadpool::managed::Pool>, pair: String, sources: Vec, - decimals: u32, + config: Config, ) -> Result { let mut timestamps = Vec::new(); + let decimals = *config.decimals.get(&pair.clone()).unwrap(); + for src in sources { - let res = process_data_by_pair_and_source(pool.clone(), &pair, &src, decimals).await?; + let res = + process_data_by_pair_and_source(pool.clone(), &pair, &src, decimals, &config).await?; timestamps.push(res); } @@ -106,6 +122,7 @@ pub async fn process_data_by_pair_and_source( pair: &str, src: &str, decimals: u32, + config: &Config, ) -> Result { let mut conn = pool .get() @@ -124,6 +141,7 @@ pub async fn process_data_by_pair_and_source( let time_labels = TIME_SINCE_LAST_UPDATE_SOURCE.with_label_values(&[src]); let price_labels = PAIR_PRICE.with_label_values(&[pair, src]); let deviation_labels = PRICE_DEVIATION.with_label_values(&[pair, src]); + let source_deviation_labels = PRICE_DEVIATION_SOURCE.with_label_values(&[src]); let price_as_f64 = data.price.to_f64().ok_or(MonitoringError::Price( "Failed to convert price to f64".to_string(), @@ -131,10 +149,12 @@ pub async fn process_data_by_pair_and_source( let normalized_price = price_as_f64 / (10_u64.pow(decimals)) as f64; let deviation = price_deviation(&data).await?; + let source_deviation = source_deviation(&data, config.clone()).await?; price_labels.set(normalized_price); time_labels.set(time as f64); deviation_labels.set(deviation); + source_deviation_labels.set(source_deviation); Ok(time) } From 4f558c44eeabe5988ae902eadb43d6a57e9dde05 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 17:40:38 +0100 Subject: [PATCH 06/13] feat: num sources metric --- src/monitoring/source_deviation.rs | 27 ++++++++++++++++----------- src/process_data.rs | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/monitoring/source_deviation.rs b/src/monitoring/source_deviation.rs index 1e0d982..c399051 100644 --- a/src/monitoring/source_deviation.rs +++ b/src/monitoring/source_deviation.rs @@ -12,11 +12,15 @@ use starknet::{ use crate::{config::Config, error::MonitoringError, models::SpotEntry}; /// Calculates the deviation from the on-chain price -pub async fn source_deviation(query: &SpotEntry, config: Config) -> Result { +/// Returns the deviation and the number of sources aggregated +pub async fn source_deviation( + query: &SpotEntry, + config: Config, +) -> Result<(f64, u32), MonitoringError> { let client = config.network.provider; let field_pair = cairo_short_string_to_felt(&query.pair_id).expect("failed to convert pair id"); - let on_chain_price = *client + let data = client .call( FunctionCall { contract_address: config.network.oracle_address, @@ -26,21 +30,22 @@ pub async fn source_deviation(query: &SpotEntry, config: Config) -> Result>, pair: String, @@ -142,6 +155,7 @@ pub async fn process_data_by_pair_and_source( let price_labels = PAIR_PRICE.with_label_values(&[pair, src]); let deviation_labels = PRICE_DEVIATION.with_label_values(&[pair, src]); let source_deviation_labels = PRICE_DEVIATION_SOURCE.with_label_values(&[src]); + let num_sources_labels = NUM_SOURCES.with_label_values(&[pair]); let price_as_f64 = data.price.to_f64().ok_or(MonitoringError::Price( "Failed to convert price to f64".to_string(), @@ -149,12 +163,14 @@ pub async fn process_data_by_pair_and_source( let normalized_price = price_as_f64 / (10_u64.pow(decimals)) as f64; let deviation = price_deviation(&data).await?; - let source_deviation = source_deviation(&data, config.clone()).await?; + let (source_deviation, num_sources_aggregated) = + source_deviation(&data, config.clone()).await?; price_labels.set(normalized_price); time_labels.set(time as f64); deviation_labels.set(deviation); source_deviation_labels.set(source_deviation); + num_sources_labels.set(num_sources_aggregated as i64); Ok(time) } From a4699b2a824dd44241c41ecd80db4b8d3f81f1ee Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 17:54:12 +0100 Subject: [PATCH 07/13] fix: remove some unwraps --- src/error.rs | 4 ++++ src/monitoring/price_deviation.rs | 13 ++++++++----- src/monitoring/source_deviation.rs | 6 ++++-- src/monitoring/time_since_last_update.rs | 3 ++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/error.rs b/src/error.rs index 4653b8c..0a42ba7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,6 +6,8 @@ pub enum MonitoringError { Database(diesel::result::Error), Connection(String), Api(String), + Conversion(String), + OnChain(String), } impl StdError for MonitoringError {} @@ -17,6 +19,8 @@ impl fmt::Display for MonitoringError { MonitoringError::Database(e) => write!(f, "Database Error: {}", e), MonitoringError::Connection(e) => write!(f, "Connection Error: {}", e), MonitoringError::Api(e) => write!(f, "API Error: {}", e), + MonitoringError::Conversion(e) => write!(f, "Conversion Error: {}", e), + MonitoringError::OnChain(e) => write!(f, "OnChain Error: {}", e), } } } diff --git a/src/monitoring/price_deviation.rs b/src/monitoring/price_deviation.rs index cfd1acd..d4fa89e 100644 --- a/src/monitoring/price_deviation.rs +++ b/src/monitoring/price_deviation.rs @@ -16,16 +16,19 @@ pub async fn price_deviation(query: &SpotEntry) -> Result .await .map_err(|e| MonitoringError::Api(e.to_string()))?; - let published_price = query - .price - .to_f64() - .expect("Failed to convert price to f64"); + // TODO: Check returned timestamp + + let published_price = query.price.to_f64().ok_or(MonitoringError::Conversion( + "Failed to convert price to f64".to_string(), + ))?; let reference_price = coingecko_price .get(coingecko_id) .expect("Failed to get coingecko price") .usd - .expect("Failed to get usd price"); + .ok_or(MonitoringError::Conversion( + "Failed get usd price".to_string(), + ))?; Ok((published_price - reference_price) / reference_price) } diff --git a/src/monitoring/source_deviation.rs b/src/monitoring/source_deviation.rs index c399051..e3b994c 100644 --- a/src/monitoring/source_deviation.rs +++ b/src/monitoring/source_deviation.rs @@ -30,7 +30,7 @@ pub async fn source_deviation( BlockId::Tag(BlockTag::Latest), ) .await - .expect("failed to get median price"); + .map_err(|e| MonitoringError::OnChain(e.to_string()))?; let decimals = config.decimals.get(&query.pair_id).unwrap(); let on_chain_price = data @@ -45,7 +45,9 @@ pub async fn source_deviation( let deviation = ((published_price - on_chain_price.clone()) / on_chain_price.clone()) .to_f64() .unwrap(); - let num_sources_aggregated = (*data.get(3).unwrap()).try_into().unwrap(); + let num_sources_aggregated = (*data.get(3).unwrap()).try_into().map_err(|e| { + MonitoringError::Conversion(format!("Failed to convert num sources {:?}", e)) + })?; Ok((deviation, num_sources_aggregated)) } diff --git a/src/monitoring/time_since_last_update.rs b/src/monitoring/time_since_last_update.rs index d56e26b..e2ca64c 100644 --- a/src/monitoring/time_since_last_update.rs +++ b/src/monitoring/time_since_last_update.rs @@ -4,7 +4,8 @@ use std::time::SystemTime; /// Calculate the time since the last update in seconds. pub fn time_since_last_update(query: &SpotEntry) -> u64 { - let datetime: DateTime = TimeZone::from_utc_datetime(&Utc, &query.timestamp.unwrap()); + let datetime: DateTime = + TimeZone::from_utc_datetime(&Utc, &query.timestamp.expect("Failed to get timestamp")); let timestamp = datetime.timestamp(); let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH); From 468eb7f413c15be1f5cd83511cc87f3ebde2fc17 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 17:57:23 +0100 Subject: [PATCH 08/13] feat: update coingecko mapping --- src/constants.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/constants.rs b/src/constants.rs index 8cbe980..5c4cd71 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -4,4 +4,10 @@ pub(crate) static COINGECKO_IDS: phf::Map<&'static str, &'static str> = phf_map! "BTC/USD" => "bitcoin", "ETH/USD" => "ethereum", "LUSD/USD" => "liquity-usd", + "WBTC/USD" => "wrapped-bitcoin", + "DAI/USD" => "dai", + "USDC/USD" => "usd-coin", + "USDT/USD" => "tether", + "WSTETH/USD" => "wrapped-steth", + "LORDS/USD" => "lords", }; From ffa51c163443341317276655079cc402eb2f6ad5 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 17:59:46 +0100 Subject: [PATCH 09/13] feat: ci --- .github/workflows/linters-cargo.yml | 23 ++++++++++++++ .github/workflows/linters.yml | 33 +++++++++++++++++++ .github/workflows/pull-request.yml | 23 ++++++++++++++ .github/workflows/rust-build.yml | 22 +++++++++++++ taplo/README.md | 49 +++++++++++++++++++++++++++++ taplo/taplo.toml | 11 +++++++ 6 files changed, 161 insertions(+) create mode 100644 .github/workflows/linters-cargo.yml create mode 100644 .github/workflows/linters.yml create mode 100644 .github/workflows/pull-request.yml create mode 100644 .github/workflows/rust-build.yml create mode 100644 taplo/README.md create mode 100644 taplo/taplo.toml diff --git a/.github/workflows/linters-cargo.yml b/.github/workflows/linters-cargo.yml new file mode 100644 index 0000000..50ab539 --- /dev/null +++ b/.github/workflows/linters-cargo.yml @@ -0,0 +1,23 @@ +--- +name: Task - Linters Cargo + +on: + workflow_dispatch: + workflow_call: + +jobs: + cargo-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + # selecting a toolchain either by action or manual `rustup` calls should happen + # before the plugin, as the cache uses the current rustc version as its cache key + - run: rustup show + + - uses: Swatinem/rust-cache@v2 + - name: Format and clippy + run: | + cargo fmt -- --check + cargo clippy --no-deps -- -D warnings + cargo clippy --tests --no-deps -- -D warnings \ No newline at end of file diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml new file mode 100644 index 0000000..1bbafa6 --- /dev/null +++ b/.github/workflows/linters.yml @@ -0,0 +1,33 @@ +--- +name: Task - Linters + +on: + workflow_dispatch: + workflow_call: + +jobs: + prettier: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run prettier + run: |- + npx prettier --check . + + markdown-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: avto-dev/markdown-lint@v1 + with: + config: "./.markdownlint.json" + args: "." + ignore: "./target" + + toml-lint: + runs-on: ubuntu-latest + steps: + - name: Checkout toml files + uses: actions/checkout@v3 + - name: Run toml check + run: npx @taplo/cli fmt --config ./taplo/taplo.toml --check \ No newline at end of file diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..e1dfa90 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,23 @@ +--- +name: Workflow - Pull Request + +on: + workflow_dispatch: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + linters: + name: Run linters + uses: ./.github/workflows/linters.yml + + rust_build: + name: Build Rust project + uses: ./.github/workflows/rust-build.yml + + linters_cargo: + name: Run Cargo linters + uses: ./.github/workflows/linters-cargo.yml + needs: rust_build \ No newline at end of file diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml new file mode 100644 index 0000000..6736f08 --- /dev/null +++ b/.github/workflows/rust-build.yml @@ -0,0 +1,22 @@ +--- +name: Task - Build Rust + +on: + workflow_dispatch: + workflow_call: + +jobs: + rust_build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + # selecting a toolchain either by action or manual `rustup` calls should happen + # before the plugin, as the cache uses the current rustc version as its cache key + - run: rustup show + + - uses: Swatinem/rust-cache@v2 + + - name: Build the project + run: | + cargo build --release --workspace \ No newline at end of file diff --git a/taplo/README.md b/taplo/README.md new file mode 100644 index 0000000..0b131e6 --- /dev/null +++ b/taplo/README.md @@ -0,0 +1,49 @@ +# Taplo + +[Taplo](https://github.com/tamasfe/taplo) is a TOML validator and formatter. It +provides a command-line interface (CLI) for working with TOML files. + +## Installation + +You can install Taplo using either cargo or Yarn or NPM. + +### Cargo + +```bash +cargo install taplo-cli --locked +``` + +### Yarn + +```bash +yarn global add @taplo/cli +``` + +### NPM + +```bash +npm install -g @taplo/cli +``` + +### Usage + +To check your TOML files for formatting issues, use the following command: + +```bash +npx @taplo/cli fmt --config taplo.toml --check +``` + +To format all TOML files in your project, use the following command: + +```bash +npx @taplo/cli fmt --config taplo.toml +``` + +This command will automatically format the TOML files, ensuring consistent and +readable formatting. + +### Configuration + +Taplo allows you to customize the formatting rules by adding configuration +options. You can find the available options and how to use them +[here](https://taplo.tamasfe.dev/configuration/formatter-options.html). \ No newline at end of file diff --git a/taplo/taplo.toml b/taplo/taplo.toml new file mode 100644 index 0000000..e49b662 --- /dev/null +++ b/taplo/taplo.toml @@ -0,0 +1,11 @@ +include = ["**/*.toml"] +exclude = ["**/bad.toml"] + +[formatting] +align_entries = false + +[[rule]] +keys = ["dependencies"] + +[rule.formatting] +reorder_keys = true From 3ba0513be5c027df1d892d217f393770f31e003d Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 18:02:27 +0100 Subject: [PATCH 10/13] fix: linters --- .github/workflows/linters-cargo.yml | 2 +- .github/workflows/linters.yml | 2 +- .github/workflows/pull-request.yml | 2 +- .github/workflows/rust-build.yml | 2 +- .vscode/settings.json | 7 ++----- Cargo.toml | 30 ++++++++++++++--------------- README.md | 1 - prometheus/alertmanager.yml | 22 ++++++++++----------- prometheus/alerts.rules.yml | 20 +++++++++---------- prometheus/prometheus.yml | 10 +++++----- taplo/README.md | 2 +- 11 files changed, 48 insertions(+), 52 deletions(-) diff --git a/.github/workflows/linters-cargo.yml b/.github/workflows/linters-cargo.yml index 50ab539..9617223 100644 --- a/.github/workflows/linters-cargo.yml +++ b/.github/workflows/linters-cargo.yml @@ -20,4 +20,4 @@ jobs: run: | cargo fmt -- --check cargo clippy --no-deps -- -D warnings - cargo clippy --tests --no-deps -- -D warnings \ No newline at end of file + cargo clippy --tests --no-deps -- -D warnings diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 1bbafa6..42f8c8d 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -30,4 +30,4 @@ jobs: - name: Checkout toml files uses: actions/checkout@v3 - name: Run toml check - run: npx @taplo/cli fmt --config ./taplo/taplo.toml --check \ No newline at end of file + run: npx @taplo/cli fmt --config ./taplo/taplo.toml --check diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index e1dfa90..93081bc 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -20,4 +20,4 @@ jobs: linters_cargo: name: Run Cargo linters uses: ./.github/workflows/linters-cargo.yml - needs: rust_build \ No newline at end of file + needs: rust_build diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml index 6736f08..f7cb3e0 100644 --- a/.github/workflows/rust-build.yml +++ b/.github/workflows/rust-build.yml @@ -19,4 +19,4 @@ jobs: - name: Build the project run: | - cargo build --release --workspace \ No newline at end of file + cargo build --release --workspace diff --git a/.vscode/settings.json b/.vscode/settings.json index e057c1c..c062259 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,3 @@ { - "rust-analyzer.linkedProjects": [ - "Cargo.toml", - "./Cargo.toml" - ] -} \ No newline at end of file + "rust-analyzer.linkedProjects": ["Cargo.toml", "./Cargo.toml"] +} diff --git a/Cargo.toml b/Cargo.toml index de29856..e4d0000 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,10 @@ edition = "2021" [dependencies] axum = { version = "0.6", features = ["macros", "multipart"] } axum-macros = "0.3" -chrono = "0.4" bigdecimal = "0.4.1" -num-bigint = "0.4" +chrono = "0.4" +coingecko = "1.0.1" +deadpool = { version = "0.9.3", features = ["managed"] } diesel = { version = "2.1.0", features = [ "postgres", "numeric", @@ -24,21 +25,20 @@ diesel-async = { version = "0.4.1", features = [ "postgres", "tokio", ] } -dotenv = "0.15.0" diesel_derives = "1.4.0" diesel_migrations = "2" -uuid = { version = "1.4", features = ["fast-rng", "v4", "serde"] } -tokio = { version = "1", features = ["full"] } -starknet_api = "0.4.1" -starknet = "0.8.0" -deadpool = { version = "0.9.3", features = ["managed"] } +dotenv = "0.15.0" +env_logger = "0.10.1" futures = "0.3.28" -prometheus = "0.13.3" -lazy_static = "1.4.0" hyper = "0.14.27" -url = "2.5.0" -strum = { version = "0.25.0", features = ["derive"] } -coingecko = "1.0.1" -phf = { version = "0.11", features = ["macros"] } +lazy_static = "1.4.0" log = "0.4.20" -env_logger = "0.10.1" +num-bigint = "0.4" +phf = { version = "0.11", features = ["macros"] } +prometheus = "0.13.3" +starknet = "0.8.0" +starknet_api = "0.4.1" +strum = { version = "0.25.0", features = ["derive"] } +tokio = { version = "1", features = ["full"] } +url = "2.5.0" +uuid = { version = "1.4", features = ["fast-rng", "v4", "serde"] } diff --git a/README.md b/README.md index c63aa95..bb3ca1d 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,3 @@ This service runs a prometheus server that returns metrics on the `/metrics` route. It powers our internal grafana dashboards and alerts. - \ No newline at end of file diff --git a/prometheus/alertmanager.yml b/prometheus/alertmanager.yml index ab6db7e..dd7c2b1 100644 --- a/prometheus/alertmanager.yml +++ b/prometheus/alertmanager.yml @@ -1,18 +1,18 @@ global: - smtp_smarthost: '${SMTP_HOST}' - smtp_from: '${SMTP_FROM}' - smtp_auth_username: '${SMTP_AUTH_USERNAME}' - smtp_auth_password: '${SMTP_AUTH_PASSWORD}' - smtp_require_tls: true + smtp_smarthost: "${SMTP_HOST}" + smtp_from: "${SMTP_FROM}" + smtp_auth_username: "${SMTP_AUTH_USERNAME}" + smtp_auth_password: "${SMTP_AUTH_PASSWORD}" + smtp_require_tls: true route: - group_by: ['instance', 'severity'] + group_by: ["instance", "severity"] group_wait: 30s group_interval: 5m repeat_interval: 4h - receiver: 'email_configs' + receiver: "email_configs" receivers: -- name: 'email_configs' - email_configs: - - to: '${EMAIL_TO}' - send_resolved: true \ No newline at end of file + - name: "email_configs" + email_configs: + - to: "${EMAIL_TO}" + send_resolved: true diff --git a/prometheus/alerts.rules.yml b/prometheus/alerts.rules.yml index 4c7a95f..89b5141 100644 --- a/prometheus/alerts.rules.yml +++ b/prometheus/alerts.rules.yml @@ -1,11 +1,11 @@ groups: -- name: example - rules: - - alert: TimeSinceLastUpdateTooHigh - expr: time_since_last_update_seconds > 1200 - for: 5m - labels: - severity: critical - annotations: - summary: "Time since the last update is too high" - description: "The time since the last update of {{ $labels.pair }} from {{ $labels.source }} has exceeded 1200 seconds." + - name: example + rules: + - alert: TimeSinceLastUpdateTooHigh + expr: time_since_last_update_seconds > 1200 + for: 5m + labels: + severity: critical + annotations: + summary: "Time since the last update is too high" + description: "The time since the last update of {{ $labels.pair }} from {{ $labels.source }} has exceeded 1200 seconds." diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml index 8547640..b7606c0 100644 --- a/prometheus/prometheus.yml +++ b/prometheus/prometheus.yml @@ -3,13 +3,13 @@ global: evaluation_interval: 15s scrape_configs: - - job_name: 'prometheus_monitoring' + - job_name: "prometheus_monitoring" static_configs: - - targets: ['127.0.0.1:8080'] + - targets: ["127.0.0.1:8080"] rule_files: - "alerts.rules.yml" alerting: alertmanagers: - - static_configs: - - targets: - - localhost:9093 + - static_configs: + - targets: + - localhost:9093 diff --git a/taplo/README.md b/taplo/README.md index 0b131e6..0d097bf 100644 --- a/taplo/README.md +++ b/taplo/README.md @@ -46,4 +46,4 @@ readable formatting. Taplo allows you to customize the formatting rules by adding configuration options. You can find the available options and how to use them -[here](https://taplo.tamasfe.dev/configuration/formatter-options.html). \ No newline at end of file +[here](https://taplo.tamasfe.dev/configuration/formatter-options.html). From 5e0ae98274fce7dca484a4738649743ce6526b7a Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Fri, 15 Dec 2023 23:40:01 +0100 Subject: [PATCH 11/13] feat: llama api + some fixes --- Cargo.lock | 16 +------- Cargo.toml | 3 +- prometheus/prometheus.yml | 2 +- src/config.rs | 22 +++++++---- src/main.rs | 2 + src/models.rs | 4 +- src/monitoring/price_deviation.rs | 61 +++++++++++++++++++++++++------ src/process_data.rs | 5 +++ src/server.rs | 2 +- 9 files changed, 79 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 454a76e..841c6b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,19 +815,6 @@ dependencies = [ "inout", ] -[[package]] -name = "coingecko" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24c2d346c689c0b8a27d4c921a35d8cac68cc266130bc82ba879155ca828da0" -dependencies = [ - "chrono", - "reqwest", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "colored" version = "2.1.0" @@ -2042,7 +2029,6 @@ dependencies = [ "axum-macros", "bigdecimal 0.4.2", "chrono", - "coingecko", "deadpool", "diesel", "diesel-async", @@ -2057,6 +2043,8 @@ dependencies = [ "num-bigint", "phf", "prometheus", + "reqwest", + "serde", "starknet", "starknet_api", "strum", diff --git a/Cargo.toml b/Cargo.toml index e4d0000..11aad28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ axum = { version = "0.6", features = ["macros", "multipart"] } axum-macros = "0.3" bigdecimal = "0.4.1" chrono = "0.4" -coingecko = "1.0.1" deadpool = { version = "0.9.3", features = ["managed"] } diesel = { version = "2.1.0", features = [ "postgres", @@ -36,6 +35,8 @@ log = "0.4.20" num-bigint = "0.4" 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.8.0" starknet_api = "0.4.1" strum = { version = "0.25.0", features = ["derive"] } diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml index b7606c0..eb6203e 100644 --- a/prometheus/prometheus.yml +++ b/prometheus/prometheus.yml @@ -5,7 +5,7 @@ global: scrape_configs: - job_name: "prometheus_monitoring" static_configs: - - targets: ["127.0.0.1:8080"] + - targets: ["host.docker.internal:8081"] rule_files: - "alerts.rules.yml" alerting: diff --git a/src/config.rs b/src/config.rs index edfa707..27a8008 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, sync::Arc}; use starknet::{ core::{ types::{BlockId, BlockTag, FieldElement, FunctionCall}, - utils::cairo_short_string_to_felt, + utils::{cairo_short_string_to_felt, parse_cairo_short_string}, }, macros::selector, providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, @@ -123,7 +123,7 @@ async fn init_oracle_config( .unwrap(); // Fetch publishers - let publishers = rpc_client + let publishers: Vec = rpc_client .call( FunctionCall { contract_address: publisher_registry_address, @@ -135,9 +135,11 @@ async fn init_oracle_config( .await .expect("failed to get publishers") .into_iter() - .map(|publisher| publisher.to_string()) + .map(|publisher| parse_cairo_short_string(&publisher).unwrap()) .collect(); + let publishers = publishers[1..].to_vec(); + let mut sources: HashMap> = HashMap::new(); let mut decimals: HashMap = HashMap::new(); @@ -189,7 +191,7 @@ async fn init_oracle_config( .await .expect("failed to get pair sources"); - let future_pair_sources = rpc_client + let _future_pair_sources = rpc_client .call( FunctionCall { contract_address: oracle_address, @@ -203,9 +205,15 @@ async fn init_oracle_config( // Store all sources for the given pair let mut pair_sources = Vec::new(); - for source in [spot_pair_sources, future_pair_sources].concat() { - if !pair_sources.contains(&source.to_string()) { - pair_sources.push(source.to_string()); + + // Remove first elements of sources' arrays + let spot_pair_sources = spot_pair_sources[1..].to_vec(); + // let future_pair_sources = future_pair_sources[1..].to_vec(); + + for source in spot_pair_sources { + let source = parse_cairo_short_string(&source).unwrap(); + if !pair_sources.contains(&source) { + pair_sources.push(source); } } diff --git a/src/main.rs b/src/main.rs index b3803a6..a2dc94d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,8 @@ async fn main() { ) .await; + log::info!("Successfully fetched config: {:?}", monitoring_config); + tokio::spawn(server::run_metrics_server()); let database_url: String = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); diff --git a/src/models.rs b/src/models.rs index b05da22..380ab3f 100644 --- a/src/models.rs +++ b/src/models.rs @@ -9,9 +9,9 @@ use diesel::{Queryable, QueryableByName, Selectable}; #[diesel(table_name = crate::schema::spot_entry)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct SpotEntry { - pub data_id: String, pub network: String, pub pair_id: String, + pub data_id: String, pub block_hash: String, pub block_number: i64, pub block_timestamp: Option, @@ -28,9 +28,9 @@ pub struct SpotEntry { #[diesel(table_name = crate::schema::future_entry)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct FutureEntry { - pub data_id: String, pub network: String, pub pair_id: String, + pub data_id: String, pub block_hash: String, pub block_number: i64, pub block_timestamp: Option, diff --git a/src/monitoring/price_deviation.rs b/src/monitoring/price_deviation.rs index d4fa89e..469a3b0 100644 --- a/src/monitoring/price_deviation.rs +++ b/src/monitoring/price_deviation.rs @@ -1,18 +1,52 @@ +use std::collections::HashMap; + use crate::{constants::COINGECKO_IDS, error::MonitoringError, models::SpotEntry}; use bigdecimal::ToPrimitive; -use coingecko::CoinGeckoClient; + +/// Data Transfer Object for Defillama API +/// e.g +///{ +// "coins": { +// "coingecko:bitcoin": { +// "price": 42220, +// "symbol": "BTC", +// "timestamp": 1702677632, +// "confidence": 0.99 +// } +// } +// } +#[derive(serde::Deserialize, Debug)] +struct CoinPricesDTO { + coins: HashMap, +} + +#[allow(unused)] +#[derive(serde::Deserialize, Debug)] +struct CoinPriceDTO { + price: f64, + symbol: String, + timestamp: u64, + confidence: f64, +} /// Calculates the deviation of the price from a trusted API (Coingecko) pub async fn price_deviation(query: &SpotEntry) -> Result { - let coingecko_client = CoinGeckoClient::default(); - let ids = &COINGECKO_IDS; let pair_id = query.pair_id.to_string(); let coingecko_id = *ids.get(&pair_id).expect("Failed to get coingecko id"); - let coingecko_price = coingecko_client - .price(&[coingecko_id], &["USD"], false, false, false, true) + let request_url = format!( + "https://coins.llama.fi/prices/current/coingecko:{id}", + id = coingecko_id, + ); + + let response = reqwest::get(&request_url) + .await + .map_err(|e| MonitoringError::Api(e.to_string()))?; + + let coins_prices: CoinPricesDTO = response + .json() .await .map_err(|e| MonitoringError::Api(e.to_string()))?; @@ -22,13 +56,16 @@ pub async fn price_deviation(query: &SpotEntry) -> Result "Failed to convert price to f64".to_string(), ))?; - let reference_price = coingecko_price - .get(coingecko_id) - .expect("Failed to get coingecko price") - .usd - .ok_or(MonitoringError::Conversion( - "Failed get usd price".to_string(), - ))?; + let api_id = format!("coingecko:{}", coingecko_id); + + let reference_price = coins_prices + .coins + .get(&api_id) + .ok_or(MonitoringError::Api(format!( + "Failed to get coingecko price for id {:?}", + coingecko_id + )))? + .price; Ok((published_price - reference_price) / reference_price) } diff --git a/src/process_data.rs b/src/process_data.rs index 41d39e0..c62fdfc 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -98,6 +98,8 @@ pub async fn process_data_by_pair( .first(&mut conn) .await; + log::info!("Processing data for pair: {}", pair); + match result { Ok(data) => { let seconds_since_last_publish = time_since_last_update(&data); @@ -122,6 +124,7 @@ pub async fn process_data_by_pair_and_sources( let decimals = *config.decimals.get(&pair.clone()).unwrap(); for src in sources { + log::info!("Processing data for pair: {} and source: {}", pair, src); let res = process_data_by_pair_and_source(pool.clone(), &pair, &src, decimals, &config).await?; timestamps.push(res); @@ -141,7 +144,9 @@ pub async fn process_data_by_pair_and_source( .get() .await .map_err(|_| MonitoringError::Connection("Failed to get connection".to_string()))?; + let filtered_by_source_result: Result = spot_entry + .filter(pair_id.eq(pair.clone())) .filter(source.eq(src)) .order(block_timestamp.desc()) .first(&mut conn) diff --git a/src/server.rs b/src/server.rs index a8f8809..bbd3878 100644 --- a/src/server.rs +++ b/src/server.rs @@ -9,7 +9,7 @@ pub async fn run_metrics_server() { .route("/", get(root_handler)) .route("/metrics", get(metrics_handler)); - let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); + let addr = SocketAddr::from(([0, 0, 0, 0], 8081)); info!("Server Started, listening on http://{}", addr); From f3a6671884f11d39232e8029ee88de1a8fc3e0fd Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Sat, 16 Dec 2023 00:02:33 +0100 Subject: [PATCH 12/13] fix: deviation --- src/monitoring/price_deviation.rs | 12 +++++------- src/monitoring/source_deviation.rs | 10 +++------- src/process_data.rs | 4 ++-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/monitoring/price_deviation.rs b/src/monitoring/price_deviation.rs index 469a3b0..fc2c366 100644 --- a/src/monitoring/price_deviation.rs +++ b/src/monitoring/price_deviation.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use crate::{constants::COINGECKO_IDS, error::MonitoringError, models::SpotEntry}; -use bigdecimal::ToPrimitive; /// Data Transfer Object for Defillama API /// e.g @@ -30,7 +29,10 @@ struct CoinPriceDTO { } /// Calculates the deviation of the price from a trusted API (Coingecko) -pub async fn price_deviation(query: &SpotEntry) -> Result { +pub async fn price_deviation( + query: &SpotEntry, + normalized_price: f64, +) -> Result { let ids = &COINGECKO_IDS; let pair_id = query.pair_id.to_string(); @@ -52,10 +54,6 @@ pub async fn price_deviation(query: &SpotEntry) -> Result // TODO: Check returned timestamp - let published_price = query.price.to_f64().ok_or(MonitoringError::Conversion( - "Failed to convert price to f64".to_string(), - ))?; - let api_id = format!("coingecko:{}", coingecko_id); let reference_price = coins_prices @@ -67,5 +65,5 @@ pub async fn price_deviation(query: &SpotEntry) -> Result )))? .price; - Ok((published_price - reference_price) / reference_price) + Ok((normalized_price - reference_price) / reference_price) } diff --git a/src/monitoring/source_deviation.rs b/src/monitoring/source_deviation.rs index e3b994c..3b22e11 100644 --- a/src/monitoring/source_deviation.rs +++ b/src/monitoring/source_deviation.rs @@ -1,5 +1,4 @@ use bigdecimal::ToPrimitive; -use num_bigint::ToBigInt; use starknet::{ core::{ types::{BlockId, BlockTag, FieldElement, FunctionCall}, @@ -15,6 +14,7 @@ use crate::{config::Config, error::MonitoringError, models::SpotEntry}; /// Returns the deviation and the number of sources aggregated pub async fn source_deviation( query: &SpotEntry, + normalized_price: f64, config: Config, ) -> Result<(f64, u32), MonitoringError> { let client = config.network.provider; @@ -37,14 +37,10 @@ pub async fn source_deviation( .first() .unwrap() .to_big_decimal(*decimals) - .to_bigint() - .unwrap(); - - let published_price = query.price.to_bigint().unwrap(); - - let deviation = ((published_price - on_chain_price.clone()) / on_chain_price.clone()) .to_f64() .unwrap(); + + let deviation = (normalized_price - on_chain_price) / on_chain_price; let num_sources_aggregated = (*data.get(3).unwrap()).try_into().map_err(|e| { MonitoringError::Conversion(format!("Failed to convert num sources {:?}", e)) })?; diff --git a/src/process_data.rs b/src/process_data.rs index c62fdfc..c077b24 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -167,9 +167,9 @@ pub async fn process_data_by_pair_and_source( ))?; let normalized_price = price_as_f64 / (10_u64.pow(decimals)) as f64; - let deviation = price_deviation(&data).await?; + let deviation = price_deviation(&data, normalized_price).await?; let (source_deviation, num_sources_aggregated) = - source_deviation(&data, config.clone()).await?; + source_deviation(&data, normalized_price, config.clone()).await?; price_labels.set(normalized_price); time_labels.set(time as f64); From ca5e9b8c8cb1c85b9c35ddd3342e95c7233f0925 Mon Sep 17 00:00:00 2001 From: 0xevolve Date: Sat, 16 Dec 2023 00:03:46 +0100 Subject: [PATCH 13/13] fix: clippy --- src/process_data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/process_data.rs b/src/process_data.rs index c077b24..089bd8b 100644 --- a/src/process_data.rs +++ b/src/process_data.rs @@ -146,7 +146,7 @@ pub async fn process_data_by_pair_and_source( .map_err(|_| MonitoringError::Connection("Failed to get connection".to_string()))?; let filtered_by_source_result: Result = spot_entry - .filter(pair_id.eq(pair.clone())) + .filter(pair_id.eq(pair)) .filter(source.eq(src)) .order(block_timestamp.desc()) .first(&mut conn)