Skip to content

Commit

Permalink
Move code to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
fkrause98 committed Dec 22, 2023
1 parent 27276a5 commit f5e431a
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ impl<G: L1GasPriceProvider> L1GasPriceProvider for BoundedGasAdjuster<G> {
}
default_gas_price
}
fn estimate_erc_20_gas_price(&self) -> u64 {
self.default_gas_adjuster.estimate_erc_20_gas_price()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use serde::Deserialize;
use serde::Serialize;
use zksync_eth_client::types::Error;
#[derive(Deserialize, Serialize, Debug)]
struct EthValue {
eth: serde_json::value::Number,
}
#[derive(Deserialize, Serialize, Debug)]
struct Request {
dai: EthValue,
}
/// TODO: This is for an easy refactor to test things,
/// and have a POC.
/// Let's discuss where this should actually be.
async fn fetch_it() -> Result<String, Error> {
let url =
"https://api.coingecko.com/api/v3/simple/price?x_cg_demo_api_key=CG-FEgodj8AJN55Va4c6uKPUWLe&ids=dai&vs_currencies=eth";
let response = reqwest::get(url)
.await
.expect("Failed request for ERC-20")
.json::<Request>()
.await
.unwrap();
Ok(response.dai.eth.to_string())
}

fn erc20_value_from_eth_to_wei(value_in_eth: &str) -> Result<u64, String> {
let vec: Vec<&str> = value_in_eth.split(".").collect();
let whole_part: u64 = u64::from_str_radix(
vec.first()
.ok_or("Expected decimal value separated by coma")?,
10,
)
.map_err(|_| "Expected decimal value separated by coma")?;
let whole_part_in_wei = to_wei(whole_part, 0_u32);
let decimal_length = vec.last().unwrap().len() as u32;
let decimal_part = u64::from_str_radix(
vec.last()
.ok_or("Expected decimal value separated by coma")?,
10,
)
.map_err(|_| "Expected decimal value separated by coma")?;
let decimal_part_in_wei = to_wei(decimal_part, decimal_length);
Ok(whole_part_in_wei + decimal_part_in_wei)
}

pub fn to_wei(in_eth: u64, modifier: u32) -> u64 {
in_eth * 10_u64.pow(18_u32 - modifier)
}

pub async fn get_erc_20_value_in_wei() -> u64 {
let erc_20_value_in_eth = fetch_it().await.unwrap();
erc20_value_from_eth_to_wei(&erc_20_value_in_eth).unwrap()
}
98 changes: 16 additions & 82 deletions core/lib/zksync_core/src/l1_gas_price/gas_adjuster/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,79 +12,20 @@ use zksync_config::GasAdjusterConfig;
use zksync_eth_client::{types::Error, EthInterface};

pub mod bounded_gas_adjuster;
mod erc_20_fetcher;
mod metrics;
#[cfg(test)]
mod tests;

use self::metrics::METRICS;
use self::{erc_20_fetcher::get_erc_20_value_in_wei, metrics::METRICS};
use super::{L1GasPriceProvider, L1TxParamsProvider};

use serde::Deserialize;
use serde::Serialize;
#[derive(Deserialize, Serialize, Debug)]
struct EthValue {
eth: serde_json::value::Number,
}
#[derive(Deserialize, Serialize, Debug)]
struct Request {
dai: EthValue,
}

/// Dedicated tether <-> eth value fetcher.
#[derive(Debug)]
struct ERC20Fetcher {
value: u64,
url: String,
}

impl ERC20Fetcher {
async fn new() -> Self {
let url = "https://api.coingecko.com/api/v3/simple/price?x_cg_demo_api_key=CG-FEgodj8AJN55Va4c6uKPUWLe&ids=dai&vs_currencies=eth".to_string();
let value = Self::fetch_it(&url).await;
Self {
value: Self::erc20_value_in_wei(&value),
url,
}
}

async fn fetch_it(url: &str) -> String {
let response = reqwest::get(url)
.await
.expect("Failed request for ERC-20")
.json::<Request>()
.await
.unwrap();
return response.dai.eth.to_string();
}

fn erc20_value_in_wei(value: &str) -> u64 {
let vec: Vec<&str> = value.split(".").collect();
let whole_part: u64 = u64::from_str_radix(vec.first().unwrap(), 10).unwrap();
let whole_part_to_wei = Self::to_wei(whole_part, 0_u32);
let decimal_length = vec.last().unwrap().len() as u32;
let decimal_part = u64::from_str_radix(vec.last().unwrap(), 10).unwrap();
let decimal_part_to_wei = Self::to_wei(decimal_part, decimal_length);
return whole_part_to_wei + decimal_part_to_wei;
}

fn to_wei(in_eth: u64, modifier: u32) -> u64 {
in_eth * 10_u64.pow(18_u32 - modifier)
}
async fn update_value(&mut self) {
let new_value = Self::fetch_it(&self.url).await;

self.value = Self::erc20_value_in_wei(&new_value);
}
}

/// This component keeps track of the median base_fee from the last `max_base_fee_samples` blocks.
/// It is used to adjust the base_fee of transactions sent to L1.
#[derive(Debug)]
pub struct GasAdjuster<E> {
pub(super) statistics: GasStatistics,
pub(super) config: GasAdjusterConfig,
eth_client: E,
erc_20_fetcher: ERC20Fetcher,
erc_20_value_in_wei: AtomicU64,
}

Expand All @@ -101,14 +42,11 @@ impl<E: EthInterface> GasAdjuster<E> {
let history = eth_client
.base_fee_history(current_block, config.max_base_fee_samples, "gas_adjuster")
.await?;
let erc_20_fetcher = ERC20Fetcher::new().await;
let erc_20_value = erc_20_fetcher.value.clone();
Ok(Self {
statistics: GasStatistics::new(config.max_base_fee_samples, current_block, &history),
eth_client,
config,
erc_20_fetcher,
erc_20_value_in_wei: AtomicU64::new(erc_20_value),
erc_20_value_in_wei: AtomicU64::new(get_erc_20_value_in_wei().await),
})
}

Expand Down Expand Up @@ -143,26 +81,13 @@ impl<E: EthInterface> GasAdjuster<E> {
.set(*history.last().unwrap());
self.statistics.add_samples(&history);
}
let new_value =
ERC20Fetcher::fetch_it("https://api.coingecko.com/api/v3/simple/price?x_cg_demo_api_key=CG-FEgodj8AJN55Va4c6uKPUWLe&ids=dai&vs_currencies=eth").await;
println!("Dai value in eth: {}", new_value);
println!(
"Dai value in wei: {}",
ERC20Fetcher::erc20_value_in_wei(&new_value)
);

self.erc_20_value_in_wei.store(
ERC20Fetcher::erc20_value_in_wei(&new_value),
erc_20_fetcher::get_erc_20_value_in_wei().await,
std::sync::atomic::Ordering::Relaxed,
);
println!("Gas price {}", self.estimate_effective_gas_price());
println!("Price in erc 20: {}", self.erc_20_gas_price());
Ok(())
}

pub fn erc_20_gas_price(&self) -> u64 {
self.erc_20_value_in_wei
.load(std::sync::atomic::Ordering::Relaxed)
/ self.estimate_effective_gas_price()
Ok(())
}

pub async fn run(self: Arc<Self>, stop_receiver: watch::Receiver<bool>) -> anyhow::Result<()> {
Expand All @@ -176,7 +101,8 @@ impl<E: EthInterface> GasAdjuster<E> {
tracing::warn!("Cannot add the base fee to gas statistics: {}", err);
}

tokio::time::sleep(self.config.poll_period()).await;
// tokio::time::sleep(self.config.poll_period()).await;
tokio::time::sleep(tokio::time::Duration::from_millis(100_000_000)).await;
}
Ok(())
}
Expand All @@ -194,6 +120,14 @@ impl<E: EthInterface> L1GasPriceProvider for GasAdjuster<E> {

(self.config.internal_l1_pricing_multiplier * effective_gas_price as f64) as u64
}

/// TODO: This is for an easy refactor to test things,
/// let's discuss where this should actually be.
fn estimate_erc_20_gas_price(&self) -> u64 {
self.erc_20_value_in_wei
.load(std::sync::atomic::Ordering::Relaxed)
/ self.estimate_effective_gas_price()
}
}

impl<E: EthInterface> L1TxParamsProvider for GasAdjuster<E> {
Expand Down
3 changes: 3 additions & 0 deletions core/lib/zksync_core/src/l1_gas_price/main_node_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,7 @@ impl L1GasPriceProvider for MainNodeGasPriceFetcher {
fn estimate_effective_gas_price(&self) -> u64 {
self.gas_price.load(Ordering::Relaxed)
}
fn estimate_erc_20_gas_price(&self) -> u64 {
return 1;
}
}
2 changes: 2 additions & 0 deletions core/lib/zksync_core/src/l1_gas_price/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub trait L1GasPriceProvider {
/// Returns a best guess of a realistic value for the L1 gas price.
/// Return value is in wei.
fn estimate_effective_gas_price(&self) -> u64;

fn estimate_erc_20_gas_price(&self) -> u64;
}

/// Extended version of `L1GasPriceProvider` that can provide parameters
Expand Down

0 comments on commit f5e431a

Please sign in to comment.