Skip to content

Commit

Permalink
feat: Minimal External API Fetcher (#2383)
Browse files Browse the repository at this point in the history
## What ❔

For chains running with a custom base token, use live prices in creating
ETH<->BaseToken conversion ratios.
This PR
- adds a first `PriceAPIClientResource` with a `PriceAPIClient`
CoinGecko client.
- Uses this client in the `BaseTokenRatioPersister` to fetch new prices
and create new ratios

Not included in this PR and will be follow-up work:
- Redundancy in the number of external price feeds used
- Different "strategies" for how true price converged from multiple
price feeds

## Why ❔

For the base token flow, we need to be be able to fetch live prices of
BaseToken & ETH from which to create the conversion ratios.

## Checklist

- [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`.

---------

Co-authored-by: dimazhornyk <[email protected]>
Co-authored-by: Igor Aleksanov <[email protected]>
  • Loading branch information
3 people authored Jul 9, 2024
1 parent 5886b8d commit 9f255c0
Show file tree
Hide file tree
Showing 41 changed files with 775 additions and 91 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,vm_runner_bwip,da_dispatcher,base_token_ratio_persister${{ matrix.consensus && ',consensus' || '' }}"
SERVER_COMPONENTS: "api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,vm_runner_bwip,da_dispatcher${{ matrix.consensus && ',consensus' || '' }}${{ matrix.base_token == 'Custom' && ',base_token_ratio_persister' || '' }}"

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,vm_runner_bwip,da_dispatcher,base_token_ratio_persister${{ matrix.consensus && ',consensus' || '' }}"
SERVER_COMPONENTS: "api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,vm_runner_bwip,da_dispatcher${{ matrix.consensus && ',consensus' || '' }}${{ matrix.base_token == 'Custom' && ',base_token_ratio_persister' || '' }}"
EXT_NODE_FLAGS: "${{ matrix.consensus && '-- --enable-consensus' || '' }}"

steps:
Expand Down
85 changes: 56 additions & 29 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ tracing-subscriber = "0.3"
tracing-opentelemetry = "0.21.0"
url = "2"
web3 = "0.19.0"
fraction = "0.15.3"

# Proc-macro
syn = "2.0"
Expand Down
10 changes: 6 additions & 4 deletions core/bin/zksync_server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ use zksync_config::{
fri_prover_group::FriProverGroupConfig,
house_keeper::HouseKeeperConfig,
BasicWitnessInputProducerConfig, ContractsConfig, DatabaseSecrets,
FriProofCompressorConfig, FriProverConfig, FriProverGatewayConfig,
FriWitnessGeneratorConfig, FriWitnessVectorGeneratorConfig, L1Secrets, ObservabilityConfig,
PrometheusConfig, ProofDataHandlerConfig, ProtectiveReadsWriterConfig, Secrets,
ExternalPriceApiClientConfig, FriProofCompressorConfig, FriProverConfig,
FriProverGatewayConfig, FriWitnessGeneratorConfig, FriWitnessVectorGeneratorConfig,
L1Secrets, ObservabilityConfig, PrometheusConfig, ProofDataHandlerConfig,
ProtectiveReadsWriterConfig, Secrets,
},
ApiConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, DADispatcherConfig, DBConfig,
EthConfig, EthWatchConfig, GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig,
Expand Down Expand Up @@ -43,7 +44,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,base_token_ratio_persister"
default_value = "api,tree,eth,state_keeper,housekeeper,tee_verifier_input_producer,commitment_generator,da_dispatcher"
)]
components: ComponentsToRun,
/// Path to the yaml config. If set, it will be used instead of env vars.
Expand Down Expand Up @@ -230,5 +231,6 @@ fn load_env_config() -> anyhow::Result<TempConfigStore> {
commitment_generator: None,
pruning: None,
snapshot_recovery: None,
external_price_api_client_config: ExternalPriceApiClientConfig::from_env().ok(),
})
}
38 changes: 34 additions & 4 deletions core/bin/zksync_server/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ use zksync_node_api_server::{
};
use zksync_node_framework::{
implementations::layers::{
base_token_ratio_persister::BaseTokenRatioPersisterLayer,
base_token_ratio_provider::BaseTokenRatioProviderLayer,
base_token::{
base_token_ratio_persister::BaseTokenRatioPersisterLayer,
base_token_ratio_provider::BaseTokenRatioProviderLayer,
coingecko_client::CoingeckoClientLayer, forced_price_client::ForcedPriceClientLayer,
no_op_external_price_api_client::NoOpExternalPriceApiClientLayer,
},
circuit_breaker_checker::CircuitBreakerCheckerLayer,
commitment_generator::CommitmentGeneratorLayer,
consensus::MainNodeConsensusLayer,
Expand Down Expand Up @@ -516,6 +520,29 @@ impl MainNodeBuilder {
Ok(self)
}

fn add_external_api_client_layer(mut self) -> anyhow::Result<Self> {
let config = try_load_config!(self.configs.external_price_api_client_config);
match config.source.as_str() {
CoingeckoClientLayer::CLIENT_NAME => {
self.node.add_layer(CoingeckoClientLayer::new(config));
}
NoOpExternalPriceApiClientLayer::CLIENT_NAME => {
self.node.add_layer(NoOpExternalPriceApiClientLayer);
}
ForcedPriceClientLayer::CLIENT_NAME => {
self.node.add_layer(ForcedPriceClientLayer::new(config));
}
_ => {
anyhow::bail!(
"Unknown external price API client source: {}",
config.source
);
}
}

Ok(self)
}

fn add_vm_runner_bwip_layer(mut self) -> anyhow::Result<Self> {
let basic_witness_input_producer_config =
try_load_config!(self.configs.basic_witness_input_producer_config);
Expand All @@ -529,8 +556,9 @@ 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));
.add_layer(BaseTokenRatioPersisterLayer::new(config, contracts_config));

Ok(self)
}
Expand Down Expand Up @@ -669,7 +697,9 @@ impl MainNodeBuilder {
self = self.add_vm_runner_protective_reads_layer()?;
}
Component::BaseTokenRatioPersister => {
self = self.add_base_token_ratio_persister_layer()?;
self = self
.add_external_api_client_layer()?
.add_base_token_ratio_persister_layer()?;
}
Component::VmRunnerBwip => {
self = self.add_vm_runner_bwip_layer()?;
Expand Down
1 change: 1 addition & 0 deletions core/lib/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ zksync_crypto_primitives.workspace = true
zksync_consensus_utils.workspace = true
zksync_concurrency.workspace = true

url.workspace = true
anyhow.workspace = true
rand.workspace = true
secrecy.workspace = true
Expand Down
Loading

0 comments on commit 9f255c0

Please sign in to comment.