Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Gas Oracle): Conversion rate component #1319

35 changes: 35 additions & 0 deletions core/lib/zksync_core/src/dev_api_conversion_rate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use axum::{extract, extract::Json, routing::get, Router};
use tokio::sync::watch;
use zksync_config::configs::native_token_fetcher::NativeTokenFetcherConfig;

pub(crate) async fn run_server(
mut stop_receiver: watch::Receiver<bool>,
server_configs: &NativeTokenFetcherConfig,
) -> anyhow::Result<()> {
let app = Router::new().route("/conversion_rate/:token_address", get(get_conversion_rate));

let bind_address = if server_configs.host.starts_with("http://") {
&server_configs.host[7..] // If it starts with "http://", strip the prefix
} else {
&server_configs.host // Otherwise, return the original string
};

axum::Server::bind(&bind_address.parse().expect("Unable to parse socket address"))
.serve(app.into_make_service())
.with_graceful_shutdown(async move {
if stop_receiver.changed().await.is_err() {
tracing::warn!("Stop signal sender for conversion rate API server was dropped without sending a signal");
}
tracing::info!("Stop signal received, conversion rate server is shutting down");
})
.await
.expect("Conversion rate server failed");
tracing::info!("Conversion rate server shut down");
Ok(())
}

// basic handler that responds with a static string
async fn get_conversion_rate(extract::Path(_token_address): extract::Path<String>) -> Json<u64> {
tracing::info!("Received request for conversion rate");
Json(42)
}
27 changes: 24 additions & 3 deletions core/lib/zksync_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub mod basic_witness_input_producer;
pub mod block_reverter;
pub mod consensus;
pub mod consistency_checker;
pub mod dev_api_conversion_rate;
pub mod eth_sender;
pub mod eth_watch;
mod fee_model;
Expand Down Expand Up @@ -235,6 +236,8 @@ pub enum Component {
ProofDataHandler,
/// Native Token fetcher
NativeTokenFetcher,
/// Conversion rate API, for local development.
DevConversionRateApi,
}

#[derive(Debug)]
Expand Down Expand Up @@ -270,6 +273,7 @@ impl FromStr for Components {
"eth_tx_manager" => Ok(Components(vec![Component::EthTxManager])),
"proof_data_handler" => Ok(Components(vec![Component::ProofDataHandler])),
"native_token_fetcher" => Ok(Components(vec![Component::NativeTokenFetcher])),
"dev_conversion_rate_api" => Ok(Components(vec![Component::DevConversionRateApi])),
other => Err(format!("{} is not a valid component name", other)),
}
}
Expand Down Expand Up @@ -326,6 +330,23 @@ pub async fn initialize_components(
panic!("Circuit breaker triggered: {}", err);
});

let mut task_futures: Vec<JoinHandle<anyhow::Result<()>>> = Vec::new();
let (stop_sender, stop_receiver) = watch::channel(false);

// spawn the conversion rate API if it is enabled
if components.contains(&Component::DevConversionRateApi) {
let native_token_fetcher_config = configs
.native_token_fetcher_config
.clone()
.context("native_token_fetcher_config")?;

let stop_receiver = stop_receiver.clone();
let conversion_rate_task = tokio::spawn(async move {
dev_api_conversion_rate::run_server(stop_receiver, &native_token_fetcher_config).await
});
task_futures.push(conversion_rate_task);
};

// spawn the native ERC20 fetcher if it is enabled
let mut fetcher_component = if components.contains(&Component::NativeTokenFetcher) {
let fetcher = NativeTokenFetcherSingleton::new(
Expand All @@ -339,7 +360,7 @@ pub async fn initialize_components(
} else {
None
};
let (stop_sender, stop_receiver) = watch::channel(false);

let (cb_sender, cb_receiver) = oneshot::channel();

let conversion_rate_fetcher: Arc<dyn ConversionRateFetcher> =
Expand Down Expand Up @@ -380,10 +401,10 @@ pub async fn initialize_components(
res
});

let mut task_futures: Vec<JoinHandle<anyhow::Result<()>>> = vec![
task_futures.extend(vec![
prometheus_task,
tokio::spawn(circuit_breaker_checker.run(cb_sender, stop_receiver.clone())),
];
]);

if components.contains(&Component::WsApi)
|| components.contains(&Component::HttpApi)
Expand Down
1 change: 1 addition & 0 deletions core/lib/zksync_core/src/native_token_fetcher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl NativeTokenFetcher {
let conversion_rate = response.json::<u64>().await.context(
"Unable to parse the response of the native token conversion rate server",
)?;
tracing::info!("Fetched native token conversion rate: {}", conversion_rate);
self.latest_to_eth_conversion_rate
.store(conversion_rate, std::sync::atomic::Ordering::Relaxed);
error_reporter.reset();
Expand Down
8 changes: 0 additions & 8 deletions erc20_example.py

This file was deleted.

Loading