Skip to content

Commit

Permalink
feat: Base Token Fundamentals (#2204)
Browse files Browse the repository at this point in the history
## What ❔

This PR puts in place the major pieces needed in the Base Token flow as
described in the [design
doc](https://www.notion.so/matterlabs/Custom-Base-Token-Tech-Design-74e158112f24463c82d96415bed76d04).

This PR adds a preliminary flow of:
- Periodically fetch the new price from an external API
- Update the conversion ration in the DB
- Have the Fee Model use the latest stored conversion ratio

In the scope of this PR:
- Introducing BaseTokenAdjuster to the Node Framework
- Adding the DB migration and the associated DAL
- Adding the proper configs for this layer to work
- Conditionally updating the gas price with a BaseToken<->ETH conversion
ratio such that it's used in charging the gas in the base token and
estimating gas for txs.
- Unit + Integration tests

Out of scope of this PR:
- Protocol contract changes needed for a base token chain to work (these
are already merged)
- Using an external API to fetch prices
- Updating the L1 with the conversion ratio
- Observability, API redundancy,

## Why ❔
Multiple ZK Chains are ready to go on mainnet with a custom token used
as the gas token.

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] Tests for the changes have been added / updated.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted via `zk fmt` and `zk lint`.
- [x] Spellcheck has been run via `zk spellcheck`.

---------

Co-authored-by: Ivan Schasny <ivan.schasny@gmail.com>
  • Loading branch information
shahar4 and ischasny authored Jul 3, 2024
1 parent 9c6bf29 commit 39709f5
Show file tree
Hide file tree
Showing 59 changed files with 1,211 additions and 83 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-core-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
base_token: ["Eth", "Custom"]
deployment_mode: ["Rollup", "Validium"]
env:
SERVER_COMPONENTS: "api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,da_dispatcher${{ matrix.consensus && ',consensus' || '' }}"
SERVER_COMPONENTS: "api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,da_dispatcher,base_token_ratio_persister${{ matrix.consensus && ',consensus' || '' }}"

runs-on: [matterlabs-ci-runner]
steps:
Expand Down Expand Up @@ -309,7 +309,7 @@ jobs:
runs-on: [matterlabs-ci-runner]

env:
SERVER_COMPONENTS: "api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,da_dispatcher${{ matrix.consensus && ',consensus' || '' }}"
SERVER_COMPONENTS: "api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,da_dispatcher,base_token_ratio_persister${{ matrix.consensus && ',consensus' || '' }}"
EXT_NODE_FLAGS: "${{ matrix.consensus && '-- --enable-consensus' || '' }}"

steps:
Expand Down
31 changes: 31 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ members = [
"core/node/contract_verification_server",
"core/node/api_server",
"core/node/tee_verifier_input_producer",
"core/node/base_token_adjuster",
# Libraries
"core/lib/db_connection",
"core/lib/zksync_core_leftovers",
Expand Down Expand Up @@ -69,6 +70,7 @@ members = [
"core/lib/web3_decl",
"core/lib/snapshots_applier",
"core/lib/crypto_primitives",
"core/lib/external_price_api",
# Test infrastructure
"core/tests/test_account",
"core/tests/loadnext",
Expand Down Expand Up @@ -248,6 +250,7 @@ zksync_types = { path = "core/lib/types" }
zksync_utils = { path = "core/lib/utils" }
zksync_web3_decl = { path = "core/lib/web3_decl" }
zksync_crypto_primitives = { path = "core/lib/crypto_primitives" }
zksync_external_price_api = { path = "core/lib/external_price_api" }

# Framework and components
zksync_node_framework = { path = "core/node/node_framework" }
Expand All @@ -274,3 +277,4 @@ zksync_node_consensus = { path = "core/node/consensus" }
zksync_contract_verification_server = { path = "core/node/contract_verification_server" }
zksync_node_api_server = { path = "core/node/api_server" }
zksync_tee_verifier_input_producer = { path = "core/node/tee_verifier_input_producer" }
zksync_base_token_adjuster = {path = "core/node/base_token_adjuster"}
8 changes: 5 additions & 3 deletions core/bin/zksync_server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ use zksync_config::{
L1Secrets, ObservabilityConfig, PrometheusConfig, ProofDataHandlerConfig,
ProtectiveReadsWriterConfig, Secrets,
},
ApiConfig, ContractVerifierConfig, DADispatcherConfig, DBConfig, EthConfig, EthWatchConfig,
GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig, SnapshotsCreatorConfig,
ApiConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, DADispatcherConfig, DBConfig,
EthConfig, EthWatchConfig, GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig,
SnapshotsCreatorConfig,
};
use zksync_core_leftovers::{
genesis_init, is_genesis_needed,
Expand Down Expand Up @@ -47,7 +48,7 @@ struct Cli {
/// Comma-separated list of components to launch.
#[arg(
long,
default_value = "api,tree,eth,state_keeper,housekeeper,tee_verifier_input_producer,commitment_generator,da_dispatcher"
default_value = "api,tree,eth,state_keeper,housekeeper,tee_verifier_input_producer,commitment_generator,da_dispatcher,base_token_ratio_persister"
)]
components: ComponentsToRun,
/// Path to the yaml config. If set, it will be used instead of env vars.
Expand Down Expand Up @@ -271,6 +272,7 @@ fn load_env_config() -> anyhow::Result<TempConfigStore> {
da_dispatcher_config: DADispatcherConfig::from_env().ok(),
protective_reads_writer_config: ProtectiveReadsWriterConfig::from_env().ok(),
core_object_store: ObjectStoreConfig::from_env().ok(),
base_token_adjuster_config: BaseTokenAdjusterConfig::from_env().ok(),
commitment_generator: None,
pruning: None,
snapshot_recovery: None,
Expand Down
19 changes: 19 additions & 0 deletions core/bin/zksync_server/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use zksync_node_api_server::{
};
use zksync_node_framework::{
implementations::layers::{
base_token_ratio_persister::BaseTokenRatioPersisterLayer,
base_token_ratio_provider::BaseTokenRatioProviderLayer,
circuit_breaker_checker::CircuitBreakerCheckerLayer,
commitment_generator::CommitmentGeneratorLayer,
consensus::{ConsensusLayer, Mode as ConsensusMode},
Expand Down Expand Up @@ -57,6 +59,7 @@ use zksync_node_framework::{
},
service::{ZkStackService, ZkStackServiceBuilder},
};
use zksync_types::SHARED_BRIDGE_ETHER_TOKEN_ADDRESS;
use zksync_vlog::prometheus::PrometheusExporterConfig;

/// Macro that looks into a path to fetch an optional config,
Expand Down Expand Up @@ -148,6 +151,11 @@ impl MainNodeBuilder {
}

fn add_sequencer_l1_gas_layer(mut self) -> anyhow::Result<Self> {
// 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 gas_adjuster_config = try_load_config!(self.configs.eth)
.gas_adjuster
.context("Gas adjuster")?;
Expand Down Expand Up @@ -495,6 +503,14 @@ impl MainNodeBuilder {
Ok(self)
}

fn add_base_token_ratio_persister_layer(mut self) -> anyhow::Result<Self> {
let config = try_load_config!(self.configs.base_token_adjuster);
self.node
.add_layer(BaseTokenRatioPersisterLayer::new(config));

Ok(self)
}

pub fn build(mut self, mut components: Vec<Component>) -> anyhow::Result<ZkStackService> {
// Add "base" layers (resources and helper tasks).
self = self
Expand Down Expand Up @@ -585,6 +601,9 @@ impl MainNodeBuilder {
Component::VmRunnerProtectiveReads => {
self = self.add_vm_runner_protective_reads_layer()?;
}
Component::BaseTokenRatioPersister => {
self = self.add_base_token_ratio_persister_layer()?;
}
}
}
Ok(self.node.build()?)
Expand Down
31 changes: 31 additions & 0 deletions core/lib/config/src/configs/base_token_adjuster.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::time::Duration;

use serde::Deserialize;

/// By default the ratio persister will run every 30 seconds.
pub const DEFAULT_INTERVAL_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.
#[serde(default = "BaseTokenAdjusterConfig::default_interval")]
pub price_polling_interval_ms: u64,
}

impl Default for BaseTokenAdjusterConfig {
fn default() -> Self {
Self {
price_polling_interval_ms: Self::default_interval(),
}
}
}

impl BaseTokenAdjusterConfig {
fn default_interval() -> u64 {
DEFAULT_INTERVAL_MS
}

pub fn price_polling_interval(&self) -> Duration {
Duration::from_millis(self.price_polling_interval_ms)
}
}
1 change: 1 addition & 0 deletions core/lib/config/src/configs/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct ContractsConfig {
pub l2_testnet_paymaster_addr: Option<Address>,
pub l1_multicall3_addr: Address,
pub ecosystem_contracts: Option<EcosystemContracts>,
// Used by the RPC API and by the node builder in wiring the BaseTokenRatioProvider layer.
pub base_token_addr: Option<Address>,
}

Expand Down
2 changes: 1 addition & 1 deletion core/lib/config/src/configs/eth_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl SenderConfig {
}
}

#[derive(Debug, Deserialize, Copy, Clone, PartialEq)]
#[derive(Debug, Deserialize, Copy, Clone, PartialEq, Default)]
pub struct GasAdjusterConfig {
/// Priority Fee to be used by GasAdjuster
pub default_priority_fee_per_gas: u64,
Expand Down
2 changes: 2 additions & 0 deletions core/lib/config/src/configs/general.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
configs::{
base_token_adjuster::BaseTokenAdjusterConfig,
chain::{CircuitBreakerConfig, MempoolConfig, OperationsManagerConfig, StateKeeperConfig},
da_dispatcher::DADispatcherConfig,
fri_prover_group::FriProverGroupConfig,
Expand Down Expand Up @@ -43,4 +44,5 @@ pub struct GeneralConfig {
pub snapshot_recovery: Option<SnapshotRecoveryConfig>,
pub pruning: Option<PruningConfig>,
pub core_object_store: Option<ObjectStoreConfig>,
pub base_token_adjuster: Option<BaseTokenAdjusterConfig>,
}
2 changes: 2 additions & 0 deletions core/lib/config/src/configs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Public re-exports
pub use self::{
api::ApiConfig,
base_token_adjuster::BaseTokenAdjusterConfig,
commitment_generator::CommitmentGeneratorConfig,
contract_verifier::ContractVerifierConfig,
contracts::{ContractsConfig, EcosystemContracts},
Expand Down Expand Up @@ -28,6 +29,7 @@ pub use self::{
};

pub mod api;
pub mod base_token_adjuster;
pub mod chain;
mod commitment_generator;
pub mod consensus;
Expand Down
6 changes: 3 additions & 3 deletions core/lib/config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![allow(clippy::upper_case_acronyms, clippy::derive_partial_eq_without_eq)]

pub use crate::configs::{
ApiConfig, ContractVerifierConfig, ContractsConfig, DADispatcherConfig, DBConfig, EthConfig,
EthWatchConfig, GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig,
SnapshotsCreatorConfig,
ApiConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, ContractsConfig,
DADispatcherConfig, DBConfig, EthConfig, EthWatchConfig, GasAdjusterConfig, GenesisConfig,
ObjectStoreConfig, PostgresConfig, SnapshotsCreatorConfig,
};

pub mod configs;
Expand Down

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS base_token_ratios;
Loading

0 comments on commit 39709f5

Please sign in to comment.