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: update base token rate on L1 #2589

Merged
merged 58 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
faf1460
feat: update base token ratio on l1
ischasny Jul 24, 2024
4fab78e
add todos
ischasny Aug 1, 2024
cb930aa
moved constants ot configs, update contracts
ischasny Aug 2, 2024
3e3e8f6
update contracts reference
ischasny Aug 2, 2024
5d64aad
Fix tests
ischasny Aug 5, 2024
4cd304d
Update contracts link
ischasny Aug 5, 2024
0ec90d6
lint fixes
ischasny Aug 5, 2024
b2ef8f2
Update contracts reference
ischasny Aug 5, 2024
1630b0c
Add integration test
ischasny Aug 5, 2024
04e4a4f
lint fixes
ischasny Aug 6, 2024
62caecf
fix test
ischasny Aug 6, 2024
a3ad9c5
lint fixes
ischasny Aug 6, 2024
3aae0ec
skip IT for eth based chain
ischasny Aug 6, 2024
590b43a
skip IT for eth based chain
ischasny Aug 6, 2024
e39cf01
fix tests
ischasny Aug 6, 2024
96f9879
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 6, 2024
01eb799
renamed CLI parameter
ischasny Aug 6, 2024
8d587ab
renamed CLI parameter
ischasny Aug 6, 2024
0bea7e9
fix tests, configs
ischasny Aug 6, 2024
822426e
update max tx gas
ischasny Aug 7, 2024
c57a037
experiment with fixing integration tests
ischasny Aug 7, 2024
ad47fbf
add logging
ischasny Aug 7, 2024
0c17a22
Try switching docker env from calldata to blobs
ischasny Aug 8, 2024
0998f3c
revert back to calldata
ischasny Aug 8, 2024
bcb3ab6
try higher gas limit
ischasny Aug 8, 2024
2c76674
try higher numerator / denominators
ischasny Aug 8, 2024
7eb8996
update to latest contracts
ischasny Aug 8, 2024
58b1caa
update to latest contracts
ischasny Aug 8, 2024
612653d
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 8, 2024
558d3a0
fix build
ischasny Aug 8, 2024
c06cc8c
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 8, 2024
968c8be
point to correct contracts
ischasny Aug 8, 2024
92a867c
point to last contracts
ischasny Aug 8, 2024
26f257e
fix tests
ischasny Aug 8, 2024
d1fc2d9
compatibility fix
ischasny Aug 8, 2024
c9c621a
lint
ischasny Aug 8, 2024
5fffa3b
polish up
ischasny Aug 9, 2024
016c0e5
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 9, 2024
a80c738
point to the latest contracts
ischasny Aug 9, 2024
40b9dd1
review comments
ischasny Aug 13, 2024
4cd277b
added tx send retries
ischasny Aug 13, 2024
1a147e8
add retry loop
ischasny Aug 13, 2024
7a49e2c
fixed types
ischasny Aug 13, 2024
b5c0bcd
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 13, 2024
15bba3f
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 13, 2024
d19d897
lint
ischasny Aug 13, 2024
aa67e1e
added eth fees scaling
ischasny Aug 14, 2024
5683c8f
fix test
ischasny Aug 14, 2024
d5b21d7
review comments
ischasny Aug 14, 2024
9feb928
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 14, 2024
aeed97f
fix integration test
ischasny Aug 14, 2024
a18002c
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 15, 2024
a264e68
set numerator and denominator to different values
ischasny Aug 15, 2024
4ec92d7
review comments
ischasny Aug 19, 2024
191a861
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 19, 2024
6056372
fix naming
ischasny Aug 19, 2024
812ddd1
Fix test
ischasny Aug 19, 2024
324d404
Merge branch 'main' into ivan/pe-128-base-token-l1-update
ischasny Aug 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions core/bin/zksync_server/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,14 @@ impl MainNodeBuilder {
fn add_base_token_ratio_persister_layer(mut self) -> anyhow::Result<Self> {
let config = try_load_config!(self.configs.base_token_adjuster);
let contracts_config = self.contracts_config.clone();
self.node
.add_layer(BaseTokenRatioPersisterLayer::new(config, contracts_config));
let wallets = self.wallets.clone();
let l1_chain_id = self.genesis_config.l1_chain_id;
self.node.add_layer(BaseTokenRatioPersisterLayer::new(
config,
contracts_config,
wallets,
l1_chain_id,
));

Ok(self)
}
Expand Down
91 changes: 91 additions & 0 deletions core/lib/config/src/configs/base_token_adjuster.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
use std::time::Duration;

use anyhow::Context;
use serde::Deserialize;
use zksync_basic_types::H256;
use zksync_crypto_primitives::K256PrivateKey;

/// 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;

/// Default max amount of gas that a L1 base token update can consume per transaction
pub const DEFAULT_MAX_TX_GAS: u64 = 80_000;

/// Default max amount of gas that a L1 base token update can consume per transaction
pub const DEFAULT_PRIORITY_FEE_PER_GAS: u64 = 1_000_000_000;
ischasny marked this conversation as resolved.
Show resolved Hide resolved

/// Default maximum number of attempts to get L1 transaction receipt
const DEFAULT_L1_RECEIPT_CHECKING_MAX_ATTEMPTS: u32 = 3;

/// Default maximum number of attempts to submit L1 transaction
const DEFAULT_L1_TX_SENDING_MAX_ATTEMPTS: u32 = 3;

/// Default number of milliseconds to sleep between receipt checking attempts
const DEFAULT_L1_RECEIPT_CHECKING_SLEEP_MS: u64 = 30_000;

/// Default number of milliseconds to sleep between transaction sending attempts
const DEFAULT_L1_TX_SENDING_SLEEP_MS: u64 = 30_000;

#[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.
Expand All @@ -17,13 +38,39 @@ pub struct BaseTokenAdjusterConfig {
/// 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,

/// Max amount of gas that L1 base token update can consume per transaction
#[serde(default = "BaseTokenAdjusterConfig::default_max_tx_gas")]
pub max_tx_gas: u64,

/// Default priority fee per gas used to instantiate the signing client
#[serde(default = "BaseTokenAdjusterConfig::default_priority_fee_per_gas")]
pub default_priority_fee_per_gas: u64,

/// Maximum number of attempts to get L1 transaction receipt before failing over
pub l1_receipt_checking_max_attempts: Option<u32>,

/// Number of seconds to sleep between the receipt checking attempts
pub l1_receipt_checking_sleep_ms: Option<u64>,

/// Maximum number of attempts to submit L1 transaction before failing over
pub l1_tx_sending_max_attempts: Option<u32>,

/// Number of seconds to sleep between the transaction sending attempts
pub l1_tx_sending_sleep_ms: Option<u64>,
}

impl Default for BaseTokenAdjusterConfig {
fn default() -> Self {
Self {
price_polling_interval_ms: Self::default_polling_interval(),
price_cache_update_interval_ms: Self::default_cache_update_interval(),
max_tx_gas: Self::default_max_tx_gas(),
default_priority_fee_per_gas: Self::default_priority_fee_per_gas(),
l1_receipt_checking_max_attempts: Some(DEFAULT_L1_RECEIPT_CHECKING_MAX_ATTEMPTS),
l1_receipt_checking_sleep_ms: Some(DEFAULT_L1_RECEIPT_CHECKING_SLEEP_MS),
l1_tx_sending_max_attempts: Some(DEFAULT_L1_TX_SENDING_MAX_ATTEMPTS),
l1_tx_sending_sleep_ms: Some(DEFAULT_L1_TX_SENDING_SLEEP_MS),
}
}
}
Expand All @@ -41,7 +88,51 @@ impl BaseTokenAdjusterConfig {
DEFAULT_CACHE_UPDATE_INTERVAL
}

fn default_priority_fee_per_gas() -> u64 {
DEFAULT_PRIORITY_FEE_PER_GAS
}

pub fn price_cache_update_interval(&self) -> Duration {
Duration::from_millis(self.price_cache_update_interval_ms)
}

pub fn l1_tx_sending_max_attempts(&self) -> u32 {
self.l1_tx_sending_max_attempts
.map_or(DEFAULT_L1_TX_SENDING_MAX_ATTEMPTS, |x| x)
}

pub fn l1_receipt_checking_max_attempts(&self) -> u32 {
self.l1_receipt_checking_max_attempts
.map_or(DEFAULT_L1_RECEIPT_CHECKING_MAX_ATTEMPTS, |x| x)
}

pub fn l1_receipt_checking_sleep_duration(&self) -> Duration {
Duration::from_millis(
self.l1_receipt_checking_sleep_ms
.map_or(DEFAULT_L1_RECEIPT_CHECKING_SLEEP_MS, |x| x),
)
}

pub fn l1_tx_sending_sleep_duration(&self) -> Duration {
Duration::from_millis(
self.l1_tx_sending_sleep_ms
.map_or(DEFAULT_L1_TX_SENDING_SLEEP_MS, |x| x),
)
}

fn default_max_tx_gas() -> u64 {
DEFAULT_MAX_TX_GAS
}

pub fn private_key(&self) -> anyhow::Result<Option<K256PrivateKey>> {
std::env::var("TOKEN_MULTIPLIER_SETTER_PRIVATE_KEY")
.ok()
.map(|pk| {
let private_key_bytes: H256 =
pk.parse().context("failed parsing private key bytes")?;
K256PrivateKey::from_bytes(private_key_bytes)
.context("private key bytes are invalid")
})
.transpose()
}
}
16 changes: 13 additions & 3 deletions core/lib/config/src/configs/external_price_api_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@ use serde::Deserialize;

pub const DEFAULT_TIMEOUT_MS: u64 = 10_000;

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct ForcedPriceClientConfig {
/// Forced conversion ratio
pub numerator: Option<u64>,
pub denominator: Option<u64>,
/// Forced fluctuation. It defines how much percent numerator /
/// denominator should fluctuate from their forced values. If it's None or 0, then ForcedPriceClient
/// will return the same quote every time it's called. Otherwise, ForcedPriceClient will return
/// forced_quote +/- forced_fluctuation % from its values.
pub fluctuation: Option<u32>,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct ExternalPriceApiClientConfig {
pub source: String,
pub base_url: Option<String>,
pub api_key: Option<String>,
#[serde(default = "ExternalPriceApiClientConfig::default_timeout")]
pub client_timeout_ms: u64,
/// Forced conversion ratio. Only used with the ForcedPriceClient.
pub forced_numerator: Option<u64>,
pub forced_denominator: Option<u64>,
pub forced: Option<ForcedPriceClientConfig>,
}

impl ExternalPriceApiClientConfig {
Expand Down
9 changes: 9 additions & 0 deletions core/lib/config/src/configs/wallets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ pub struct StateKeeper {
pub fee_account: AddressWallet,
}

#[derive(Debug, Clone, PartialEq)]
pub struct TokenMultiplierSetter {
pub wallet: Wallet,
}

#[derive(Debug, Clone, PartialEq)]
pub struct Wallets {
pub eth_sender: Option<EthSender>,
pub state_keeper: Option<StateKeeper>,
pub token_multiplier_setter: Option<TokenMultiplierSetter>,
}

impl Wallets {
Expand All @@ -87,6 +93,9 @@ impl Wallets {
state_keeper: Some(StateKeeper {
fee_account: AddressWallet::from_address(H160::repeat_byte(0x3)),
}),
token_multiplier_setter: Some(TokenMultiplierSetter {
wallet: Wallet::from_private_key_bytes(H256::repeat_byte(0x4), None).unwrap(),
}),
}
}
}
26 changes: 23 additions & 3 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use zksync_basic_types::{
use zksync_consensus_utils::EncodeDist;
use zksync_crypto_primitives::K256PrivateKey;

use crate::configs::{self, eth_sender::PubdataSendingMode};
use crate::configs::{
self, eth_sender::PubdataSendingMode, external_price_api_client::ForcedPriceClientConfig,
};

trait Sample {
fn sample(rng: &mut (impl Rng + ?Sized)) -> Self;
Expand Down Expand Up @@ -893,11 +895,20 @@ impl Distribution<configs::wallets::EthSender> for EncodeDist {
}
}

impl Distribution<configs::wallets::TokenMultiplierSetter> for EncodeDist {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> configs::wallets::TokenMultiplierSetter {
configs::wallets::TokenMultiplierSetter {
wallet: self.sample(rng),
}
}
}

impl Distribution<configs::wallets::Wallets> for EncodeDist {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> configs::wallets::Wallets {
configs::wallets::Wallets {
state_keeper: self.sample_opt(|| self.sample(rng)),
eth_sender: self.sample_opt(|| self.sample(rng)),
token_multiplier_setter: self.sample_opt(|| self.sample(rng)),
}
}
}
Expand Down Expand Up @@ -1022,6 +1033,12 @@ impl Distribution<configs::base_token_adjuster::BaseTokenAdjusterConfig> for Enc
configs::base_token_adjuster::BaseTokenAdjusterConfig {
price_polling_interval_ms: self.sample(rng),
price_cache_update_interval_ms: self.sample(rng),
max_tx_gas: self.sample(rng),
default_priority_fee_per_gas: self.sample(rng),
l1_receipt_checking_max_attempts: self.sample(rng),
l1_receipt_checking_sleep_ms: self.sample(rng),
l1_tx_sending_max_attempts: self.sample(rng),
l1_tx_sending_sleep_ms: self.sample(rng),
}
}
}
Expand Down Expand Up @@ -1049,8 +1066,11 @@ impl Distribution<configs::external_price_api_client::ExternalPriceApiClientConf
base_url: self.sample(rng),
api_key: self.sample(rng),
client_timeout_ms: self.sample(rng),
forced_numerator: self.sample(rng),
forced_denominator: self.sample(rng),
forced: Some(ForcedPriceClientConfig {
numerator: self.sample(rng),
denominator: self.sample(rng),
fluctuation: self.sample(rng),
}),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/lib/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const DIAMOND_INIT_CONTRACT_FILE: (&str, &str) = (
);
const GOVERNANCE_CONTRACT_FILE: (&str, &str) = ("governance", "IGovernance.sol/IGovernance.json");
const CHAIN_ADMIN_CONTRACT_FILE: (&str, &str) = ("governance", "IChainAdmin.sol/IChainAdmin.json");

const MULTICALL3_CONTRACT_FILE: (&str, &str) = ("dev-contracts", "Multicall3.sol/Multicall3.json");
const VERIFIER_CONTRACT_FILE: (&str, &str) = ("state-transition", "Verifier.sol/Verifier.json");
const _IERC20_CONTRACT_FILE: &str =
Expand Down
28 changes: 23 additions & 5 deletions core/lib/env_config/src/external_price_api_client.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
use zksync_config::configs::ExternalPriceApiClientConfig;
use zksync_config::configs::{
external_price_api_client::ForcedPriceClientConfig, ExternalPriceApiClientConfig,
};

use crate::{envy_load, FromEnv};

impl FromEnv for ExternalPriceApiClientConfig {
fn from_env() -> anyhow::Result<Self> {
envy_load("external_price_api_client", "EXTERNAL_PRICE_API_CLIENT_")
let mut config: ExternalPriceApiClientConfig =
envy_load("external_price_api_client", "EXTERNAL_PRICE_API_CLIENT_")?;
config.forced = ForcedPriceClientConfig::from_env().ok();
Ok(config)
}
}

impl FromEnv for ForcedPriceClientConfig {
fn from_env() -> anyhow::Result<Self> {
envy_load(
"external_price_api_client_forced",
"EXTERNAL_PRICE_API_CLIENT_FORCED_",
)
}
}

#[cfg(test)]
mod tests {
use zksync_config::configs::external_price_api_client::{
ExternalPriceApiClientConfig, DEFAULT_TIMEOUT_MS,
ExternalPriceApiClientConfig, ForcedPriceClientConfig, DEFAULT_TIMEOUT_MS,
};

use super::*;
Expand All @@ -25,8 +39,11 @@ mod tests {
base_url: Some("https://pro-api.coingecko.com".to_string()),
api_key: Some("qwerty12345".to_string()),
client_timeout_ms: DEFAULT_TIMEOUT_MS,
forced_numerator: Some(100),
forced_denominator: Some(1),
forced: Some(ForcedPriceClientConfig {
numerator: Some(100),
denominator: Some(1),
fluctuation: Some(10),
}),
}
}

Expand All @@ -39,6 +56,7 @@ mod tests {
EXTERNAL_PRICE_API_CLIENT_API_KEY=qwerty12345
EXTERNAL_PRICE_API_CLIENT_FORCED_NUMERATOR=100
EXTERNAL_PRICE_API_CLIENT_FORCED_DENOMINATOR=1
EXTERNAL_PRICE_API_CLIENT_FORCED_FLUCTUATION=10
"#;
lock.set_env(config);

Expand Down
Loading
Loading