forked from matter-labs/zksync
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ticker): separates dev and proxy tickers
- Loading branch information
Showing
5 changed files
with
154 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pub mod dev_liquidity_provider; | ||
pub mod dev_price_provider; | ||
pub mod proxy_price_provider; |
116 changes: 116 additions & 0 deletions
116
core/bin/zksync_api/src/bin/providers/proxy_price_provider.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use std::{ | ||
collections::HashMap, | ||
sync::Arc, | ||
time::{Duration, Instant}, | ||
}; | ||
use tokio::sync::Mutex; | ||
|
||
use actix_web::{web, HttpResponse, Scope}; | ||
use serde_json::Value; | ||
use zksync_api::fee_ticker::CoinGeckoTypes::CoinsListItem; | ||
|
||
struct ResponseCache<T> { | ||
data: T, | ||
last_fetched: Instant, | ||
} | ||
|
||
#[derive(Clone)] | ||
struct ProxyState { | ||
cache: Arc<Mutex<HashMap<String, ResponseCache<Value>>>>, | ||
} | ||
|
||
async fn proxy_request( | ||
url: &str, | ||
cache: &Mutex<HashMap<String, ResponseCache<Value>>>, | ||
) -> HttpResponse { | ||
let mut lock = cache.lock().await; | ||
|
||
// Check cache first | ||
if let Some(cached) = lock.get(url) { | ||
if cached.last_fetched.elapsed() < Duration::from_secs(5) { | ||
// TODO: configure timeout (or use existing one) | ||
return HttpResponse::Ok().json(&cached.data); | ||
} | ||
} | ||
|
||
// Fetch data if not in cache or stale | ||
|
||
match reqwest::get(url).await { | ||
Ok(response) => match response.json::<Value>().await { | ||
Ok(data) => { | ||
// Cache the fetched data | ||
lock.insert( | ||
url.to_string(), | ||
ResponseCache { | ||
data: data.clone(), | ||
last_fetched: Instant::now(), | ||
}, | ||
); | ||
HttpResponse::Ok().json(data) | ||
} | ||
Err(_) => HttpResponse::InternalServerError().finish(), | ||
}, | ||
Err(_) => HttpResponse::InternalServerError().finish(), | ||
} | ||
} | ||
|
||
const RIF_TOKEN_TESTNET_ADDRESS: &str = "0x19f64674D8a5b4e652319F5e239EFd3bc969a1FE"; | ||
|
||
async fn fetch_coins_list(_: web::Data<ProxyState>, _: web::Path<(bool,)>) -> HttpResponse { | ||
let rootstock_platform: HashMap<String, Option<String>> = vec![( | ||
"rootstock".to_string(), | ||
Some(RIF_TOKEN_TESTNET_ADDRESS.to_string()), | ||
)] | ||
.into_iter() | ||
.collect(); | ||
let rif_token = CoinsListItem { | ||
id: "rif-token".to_string(), | ||
platforms: Some(rootstock_platform.clone()), | ||
name: "RIF Token".to_string(), | ||
symbol: "RIF".to_string(), | ||
}; | ||
let rbtc = CoinsListItem { | ||
id: "rootstock".to_string(), | ||
symbol: "rbtc".to_string(), | ||
name: "Rootstock RSK".to_string(), | ||
platforms: Some(rootstock_platform), | ||
}; | ||
let coin_list: &[CoinsListItem] = &[rif_token, rbtc]; | ||
|
||
HttpResponse::Ok().json(coin_list) | ||
} | ||
|
||
async fn fetch_market_chart( | ||
data: web::Data<ProxyState>, | ||
path: web::Path<(String,)>, | ||
) -> HttpResponse { | ||
let (coin_id,) = path.into_inner(); | ||
let url = format!( | ||
"https://api.coingecko.com/api/v3/coins/{}/market_chart", | ||
coin_id | ||
); | ||
|
||
proxy_request(&url, &data.cache).await | ||
} | ||
|
||
fn fetch_coinmarketcap_price() -> HttpResponse { | ||
HttpResponse::NotImplemented().json("{}") | ||
} | ||
|
||
pub(crate) fn create_price_service() -> Scope { | ||
let shared_data = web::Data::new(ProxyState { | ||
cache: std::sync::Arc::new(Mutex::new(HashMap::new())), | ||
}); | ||
|
||
web::scope("") | ||
.app_data(web::Data::new(shared_data)) | ||
.route( | ||
"/cryptocurrency/quotes/latest", | ||
web::get().to(fetch_coinmarketcap_price), | ||
) | ||
.route("/api/v3/coins/list", web::get().to(fetch_coins_list)) | ||
.route( | ||
"/api/v3/coins/{coin_id}/market_chart", | ||
web::get().to(fetch_market_chart), | ||
) | ||
} |
Oops, something went wrong.