diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index 2144e9598a6f..3f8995d2efdc 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -155,7 +155,9 @@ impl MainNodeBuilder { fn add_sequencer_l1_gas_layer(mut self) -> anyhow::Result { // Ensure the BaseTokenRatioProviderResource is inserted if the base token is not ETH. if self.contracts_config.base_token_addr != Some(SHARED_BRIDGE_ETHER_TOKEN_ADDRESS) { - self.node.add_layer(BaseTokenRatioProviderLayer {}); + let base_token_adjuster_config = try_load_config!(self.configs.base_token_adjuster); + self.node + .add_layer(BaseTokenRatioProviderLayer::new(base_token_adjuster_config)); } let gas_adjuster_config = try_load_config!(self.configs.eth) diff --git a/core/lib/config/src/configs/base_token_adjuster.rs b/core/lib/config/src/configs/base_token_adjuster.rs index 11d669429e05..4ef253989cd2 100644 --- a/core/lib/config/src/configs/base_token_adjuster.rs +++ b/core/lib/config/src/configs/base_token_adjuster.rs @@ -2,30 +2,46 @@ use std::time::Duration; use serde::Deserialize; -/// By default the ratio persister will run every 30 seconds. +/// By default, the ratio persister will run every 30 seconds. pub const DEFAULT_INTERVAL_MS: u64 = 30_000; +/// By default, refetch ratio from db every 0.5 second +pub const DEFAULT_CACHE_UPDATE_INTERVAL: u64 = 500; + #[derive(Debug, Clone, PartialEq, Deserialize)] pub struct BaseTokenAdjusterConfig { /// How often to spark a new cycle of the ratio persister to fetch external prices and persis ratios. - #[serde(default = "BaseTokenAdjusterConfig::default_interval")] + #[serde(default = "BaseTokenAdjusterConfig::default_polling_interval")] pub price_polling_interval_ms: u64, + + /// We (in memory) cache the ratio fetched from db. This interval defines frequency of refetch from db. + #[serde(default = "BaseTokenAdjusterConfig::default_cache_update_interval")] + pub price_cache_update_interval_ms: u64, } impl Default for BaseTokenAdjusterConfig { fn default() -> Self { Self { - price_polling_interval_ms: Self::default_interval(), + price_polling_interval_ms: Self::default_polling_interval(), + price_cache_update_interval_ms: Self::default_cache_update_interval(), } } } impl BaseTokenAdjusterConfig { - fn default_interval() -> u64 { + fn default_polling_interval() -> u64 { DEFAULT_INTERVAL_MS } pub fn price_polling_interval(&self) -> Duration { Duration::from_millis(self.price_polling_interval_ms) } + + fn default_cache_update_interval() -> u64 { + DEFAULT_CACHE_UPDATE_INTERVAL + } + + pub fn price_cache_update_interval(&self) -> Duration { + Duration::from_millis(self.price_cache_update_interval_ms) + } } diff --git a/core/lib/protobuf_config/src/base_token_adjuster.rs b/core/lib/protobuf_config/src/base_token_adjuster.rs index d8dea17daec0..850acb4bae20 100644 --- a/core/lib/protobuf_config/src/base_token_adjuster.rs +++ b/core/lib/protobuf_config/src/base_token_adjuster.rs @@ -11,12 +11,17 @@ impl ProtoRepr for proto::BaseTokenAdjuster { price_polling_interval_ms: self .price_polling_interval_ms .expect("price_polling_interval_ms"), + + price_cache_update_interval_ms: self + .price_cache_update_interval_ms + .expect("price_cache_update_interval_ms"), }) } fn build(this: &Self::Type) -> Self { Self { price_polling_interval_ms: Some(this.price_polling_interval_ms), + price_cache_update_interval_ms: Some(this.price_cache_update_interval_ms), } } } diff --git a/core/lib/protobuf_config/src/proto/config/base_token_adjuster.proto b/core/lib/protobuf_config/src/proto/config/base_token_adjuster.proto index 67e97dd14cda..f3adad8707b5 100644 --- a/core/lib/protobuf_config/src/proto/config/base_token_adjuster.proto +++ b/core/lib/protobuf_config/src/proto/config/base_token_adjuster.proto @@ -4,4 +4,5 @@ package zksync.config.base_token_adjuster; message BaseTokenAdjuster { optional uint64 price_polling_interval_ms = 1; + optional uint64 price_cache_update_interval_ms = 2; } diff --git a/core/node/base_token_adjuster/src/base_token_ratio_provider.rs b/core/node/base_token_adjuster/src/base_token_ratio_provider.rs index 83a135e7148e..a89c2d909a15 100644 --- a/core/node/base_token_adjuster/src/base_token_ratio_provider.rs +++ b/core/node/base_token_adjuster/src/base_token_ratio_provider.rs @@ -2,17 +2,15 @@ use std::{ fmt::Debug, num::NonZeroU64, sync::{Arc, RwLock}, - time::Duration, }; use anyhow::Context; use async_trait::async_trait; use tokio::sync::watch; +use zksync_config::BaseTokenAdjusterConfig; use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_types::fee_model::BaseTokenConversionRatio; -const CACHE_UPDATE_INTERVAL: Duration = Duration::from_millis(500); - #[async_trait] pub trait BaseTokenRatioProvider: Debug + Send + Sync + 'static { fn get_conversion_ratio(&self) -> BaseTokenConversionRatio; @@ -22,13 +20,18 @@ pub trait BaseTokenRatioProvider: Debug + Send + Sync + 'static { pub struct DBBaseTokenRatioProvider { pub pool: ConnectionPool, pub latest_ratio: Arc>, + config: BaseTokenAdjusterConfig, } impl DBBaseTokenRatioProvider { - pub async fn new(pool: ConnectionPool) -> anyhow::Result { + pub async fn new( + pool: ConnectionPool, + config: BaseTokenAdjusterConfig, + ) -> anyhow::Result { let fetcher = Self { pool, latest_ratio: Arc::default(), + config, }; fetcher.update_latest_price().await?; @@ -46,7 +49,7 @@ impl DBBaseTokenRatioProvider { } pub async fn run(&self, mut stop_receiver: watch::Receiver) -> anyhow::Result<()> { - let mut timer = tokio::time::interval(CACHE_UPDATE_INTERVAL); + let mut timer = tokio::time::interval(self.config.price_cache_update_interval()); while !*stop_receiver.borrow_and_update() { tokio::select! { diff --git a/core/node/node_framework/src/implementations/layers/base_token_ratio_provider.rs b/core/node/node_framework/src/implementations/layers/base_token_ratio_provider.rs index 465b61cdd1e6..4a15895b5241 100644 --- a/core/node/node_framework/src/implementations/layers/base_token_ratio_provider.rs +++ b/core/node/node_framework/src/implementations/layers/base_token_ratio_provider.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use zksync_base_token_adjuster::DBBaseTokenRatioProvider; +use zksync_config::BaseTokenAdjusterConfig; use crate::{ implementations::resources::{ @@ -22,7 +23,15 @@ use crate::{ /// If the base token is ETH, a default, no-op impl of the BaseTokenRatioProviderResource is used by other /// layers to always return a conversion ratio of 1. #[derive(Debug)] -pub struct BaseTokenRatioProviderLayer; +pub struct BaseTokenRatioProviderLayer { + config: BaseTokenAdjusterConfig, +} + +impl BaseTokenRatioProviderLayer { + pub fn new(config: BaseTokenAdjusterConfig) -> Self { + Self { config } + } +} #[derive(Debug, FromContext)] #[context(crate = crate)] @@ -50,7 +59,7 @@ impl WiringLayer for BaseTokenRatioProviderLayer { async fn wire(self, input: Self::Input) -> Result { let replica_pool = input.replica_pool.get().await.unwrap(); - let ratio_provider = DBBaseTokenRatioProvider::new(replica_pool).await?; + let ratio_provider = DBBaseTokenRatioProvider::new(replica_pool, self.config).await?; // Cloning the provided preserves the internal state. Ok(Output { ratio_provider: Arc::new(ratio_provider.clone()).into(), diff --git a/etc/env/base/base_token_adjuster.toml b/etc/env/base/base_token_adjuster.toml index 100da3b7224f..b1b997eb67ac 100644 --- a/etc/env/base/base_token_adjuster.toml +++ b/etc/env/base/base_token_adjuster.toml @@ -4,3 +4,5 @@ # How often to poll external price feeds for the base token price. price_polling_interval_ms = "30000" + +price_cache_update_interval_ms = "2000" diff --git a/etc/env/file_based/general.yaml b/etc/env/file_based/general.yaml index fbd7c816b1bb..0a7dc41e5766 100644 --- a/etc/env/file_based/general.yaml +++ b/etc/env/file_based/general.yaml @@ -297,6 +297,7 @@ prover_group: aggregation_round: 1 base_token_adjuster: price_polling_interval_ms: 30000 + price_cache_update_interval_ms: 2000 house_keeper: l1_batch_metrics_reporting_interval_ms: 10000