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

[DRAFT]: Add token price fetcher from coingecko #2315

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e40eb73
node framework + config flow
shahar4 Jun 10, 2024
476addc
migration + dal
shahar4 Jun 11, 2024
8967d86
use dal
shahar4 Jun 12, 2024
7e19e94
fmt
shahar4 Jun 12, 2024
4ab267e
fmt
shahar4 Jun 12, 2024
876a6e1
fix compilation
ischasny Jun 12, 2024
3eb58d1
wired base token adjuster into the fee model
ischasny Jun 13, 2024
e6c2686
Wired base token price to fee calculator
ischasny Jun 13, 2024
63777b0
add sqlx queries
ischasny Jun 13, 2024
d3ba4c7
Lint fixes
ischasny Jun 13, 2024
9b9fdf6
update cargo lock
ischasny Jun 13, 2024
6f4cce6
Adjusted interface
ischasny Jun 14, 2024
a2b45e1
add fee model tests
ischasny Jun 14, 2024
62d54dd
rename base_token_ratio
ischasny Jun 14, 2024
09aa927
flow seems complete
shahar4 Jun 19, 2024
bbd9f7c
working sqlx + converting params themselves
shahar4 Jun 20, 2024
313444f
real working sqlx
shahar4 Jun 20, 2024
9160131
flow through updating params
shahar4 Jun 21, 2024
cce90e1
one happy test
shahar4 Jun 21, 2024
92ce099
self CR and unit test. i tests out
shahar4 Jun 23, 2024
3adef45
merge main
shahar4 Jun 23, 2024
adba682
cargo lock
shahar4 Jun 23, 2024
681735a
retry fetching price and some self CR to make CI happy
shahar4 Jun 23, 2024
0ff2aac
feat: add coingecko price fetcher
ischasny Jun 24, 2024
bd3b422
small refactor
ischasny Jun 24, 2024
c3490e6
add cg auth header
ischasny Jun 25, 2024
c7d8110
fixed address formatting
ischasny Jun 25, 2024
a0d6aec
add cmc api implementation
ischasny Jun 27, 2024
0052b79
improved tests
ischasny Jun 27, 2024
c77dcb1
finish cmc api, fix tests
ischasny Jun 28, 2024
994e4e2
finish cmc api tests
ischasny Jun 28, 2024
c14710d
Add average strategy
ischasny Jul 1, 2024
ba01641
add fail over strategy
ischasny Jul 2, 2024
c45d86e
restored cargo.lock
ischasny Jul 2, 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
32 changes: 32 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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 @@ -66,6 +67,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 @@ -265,3 +267,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"}
6 changes: 4 additions & 2 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, DBConfig, EthConfig, EthWatchConfig, GasAdjusterConfig,
GenesisConfig, ObjectStoreConfig, PostgresConfig, SnapshotsCreatorConfig,
ApiConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, DBConfig, EthConfig,
EthWatchConfig, GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig,
SnapshotsCreatorConfig,
};
use zksync_core_leftovers::{
genesis_init, is_genesis_needed,
Expand Down Expand Up @@ -270,5 +271,6 @@ fn load_env_config() -> anyhow::Result<TempConfigStore> {
snapshot_creator: SnapshotsCreatorConfig::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(),
})
}
13 changes: 13 additions & 0 deletions core/bin/zksync_server/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use zksync_node_api_server::{
};
use zksync_node_framework::{
implementations::layers::{
base_token_adjuster::BaseTokenAdjusterLayer,
circuit_breaker_checker::CircuitBreakerCheckerLayer,
commitment_generator::CommitmentGeneratorLayer,
consensus::{ConsensusLayer, Mode as ConsensusMode},
Expand Down Expand Up @@ -145,11 +146,13 @@ impl MainNodeBuilder {
.context("Gas adjuster")?;
let state_keeper_config = try_load_config!(self.configs.state_keeper_config);
let eth_sender_config = try_load_config!(self.configs.eth);
let base_token_adjuster_config = try_load_config!(self.configs.base_token_adjuster);
let sequencer_l1_gas_layer = SequencerL1GasLayer::new(
gas_adjuster_config,
self.genesis_config.clone(),
state_keeper_config,
try_load_config!(eth_sender_config.sender).pubdata_sending_mode,
base_token_adjuster_config,
);
self.node.add_layer(sequencer_l1_gas_layer);
Ok(self)
Expand Down Expand Up @@ -444,6 +447,13 @@ impl MainNodeBuilder {
Ok(self)
}

fn add_base_token_adjuster_layer(mut self) -> anyhow::Result<Self> {
let config = try_load_config!(self.configs.base_token_adjuster);
self.node.add_layer(BaseTokenAdjusterLayer::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 @@ -531,6 +541,9 @@ impl MainNodeBuilder {
Component::VmRunnerProtectiveReads => {
self = self.add_vm_runner_protective_reads_layer()?;
}
Component::BaseTokenAdjuster => {
self = self.add_base_token_adjuster_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 external APIs shall be polled every 30 seconds for a new price.
pub const DEFAULT_INTERVAL_MS: u64 = 30_000;

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct BaseTokenAdjusterConfig {
/// How often to fetch external APIs for a new ETH<->Base-Token price.
pub price_polling_interval_ms: Option<u64>,

/// Base token symbol. If none, an assumption of ETH is made.
pub base_token: Option<String>,
}

impl BaseTokenAdjusterConfig {
pub fn for_tests() -> Self {
Self {
price_polling_interval_ms: Some(DEFAULT_INTERVAL_MS),
base_token: Option::from("ETH".to_string()),
}
}

pub fn price_polling_interval(&self) -> Duration {
match self.price_polling_interval_ms {
Some(interval) => Duration::from_millis(interval),
None => Duration::from_millis(DEFAULT_INTERVAL_MS),
}
}
}
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},
fri_prover_group::FriProverGroupConfig,
house_keeper::HouseKeeperConfig,
Expand Down Expand Up @@ -36,4 +37,5 @@ pub struct GeneralConfig {
pub observability: Option<ObservabilityConfig>,
pub protective_reads_writer_config: Option<ProtectiveReadsWriterConfig>,
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,
contract_verifier::ContractVerifierConfig,
contracts::{ContractsConfig, EcosystemContracts},
database::{DBConfig, PostgresConfig},
Expand All @@ -24,6 +25,7 @@ pub use self::{
};

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

pub use crate::configs::{
ApiConfig, ContractVerifierConfig, ContractsConfig, DBConfig, EthConfig, EthWatchConfig,
GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig, SnapshotsCreatorConfig,
ApiConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, ContractsConfig, 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_price;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CREATE TABLE base_token_prices (
id SERIAL PRIMARY KEY,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,

ratio_timestamp TIMESTAMP NOT NULL,
base_token_price NUMERIC NOT NULL,
eth_price NUMERIC NOT NULL,

used_in_l1 BOOLEAN NOT NULL DEFAULT FALSE
);
59 changes: 59 additions & 0 deletions core/lib/dal/src/base_token_dal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use bigdecimal::BigDecimal;
use zksync_db_connection::{connection::Connection, error::DalResult, instrument::InstrumentExt};

use crate::{models::storage_base_token_price::StorageBaseTokenPrice, Core};

#[derive(Debug)]
pub struct BaseTokenDal<'a, 'c> {
pub(crate) storage: &'a mut Connection<'c, Core>,
}

impl BaseTokenDal<'_, '_> {
pub async fn insert_token_price(
&mut self,
base_token_price: &BigDecimal,
eth_price: &BigDecimal,
ratio_timestamp: &chrono::NaiveDateTime,
) -> DalResult<usize> {
let row = sqlx::query!(
r#"
INSERT INTO
base_token_prices (base_token_price, eth_price, ratio_timestamp, created_at, updated_at)
VALUES
($1, $2, $3, NOW(), NOW())
RETURNING
id
"#,
base_token_price,
eth_price,
ratio_timestamp,
)
.instrument("insert_base_token_price")
.fetch_one(self.storage)
.await?;

Ok(row.id as usize)
}

// TODO (PE-128): pub async fn mark_l1_update()

pub async fn get_latest_price(&mut self) -> DalResult<StorageBaseTokenPrice> {
let row = sqlx::query_as!(
StorageBaseTokenPrice,
r#"
SELECT
*
FROM
base_token_prices
ORDER BY
created_at DESC
LIMIT
1
"#,
)
.instrument("get_latest_base_token_price")
.fetch_one(self.storage)
.await?;
Ok(row)
}
}
Loading
Loading