Skip to content

Commit

Permalink
feat(da-clients): add Celestia client (matter-labs#2983)
Browse files Browse the repository at this point in the history
## What ❔

This PR adds a Celestia DA client.
The main complexity of this PR comes from our goal to lower the
operational load and not run the Celestia light node (which is a default
way of interacting with Celestia blockchain).

This was done by adapting Astria's Celestia client implementation to our
codebase and removing unneeded logical components.

Note that Celestia's main communication protocol is gRPC, which means we
have to import or maintain the proto definitions. I decided to reuse the
generated `.rs` files from Astria's repo to remove the need to maintain
the `.proto` files in our repo (not the cleanest way, but consider it a
rather temporary solution).
There is a
[celestia-proto](https://github.com/eigerco/lumina/tree/main/proto)
crate that has all the codegen that we need, but they don't generate the
gRPC client definitions, only the types, so we can't use them atm. I
will try to ask the team maintaining it to add such an option, then we
would be able to remove all the codegen from our repo, and simply import
it from celestia-proto.

Example config:
```
da_client:
  celestia:
    api_node_url: http://grpc-mocha.pops.one:9090
    namespace: 000000000000000000000000000000000000ca1de12a5e2d5beb9ba9
    chain_id: mocha-4
    timeout_ms: 10000
``` 
secrets:
```
da:
  celestia:
    private_key: PRIVATE_KEY_WITHOUT_0x_PREFIX
```

## Why ❔

To enable Celestia DA in ZK stack

## Checklist

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

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.
  • Loading branch information
dimazhornyk authored Oct 29, 2024
1 parent 6c034f6 commit d88b875
Show file tree
Hide file tree
Showing 44 changed files with 4,004 additions and 592 deletions.
1,767 changes: 1,322 additions & 445 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ opentelemetry-semantic-conventions = "0.16.0"
opentelemetry-appender-tracing = "0.5"
pin-project-lite = "0.2.13"
pretty_assertions = "1"
prost = "0.12.1"
prost = "0.12.6"
rand = "0.8"
rayon = "1.3.1"
regex = "1"
Expand Down Expand Up @@ -211,6 +211,13 @@ subxt-metadata = "0.34.0"
parity-scale-codec = { version = "3.6.9", default-features = false }
subxt-signer = { version = "0.34", default-features = false }

# Celestia
celestia-types = "0.6.1"
bech32 = "0.11.0"
ripemd = "0.1.3"
tonic = "0.11.0"
pbjson-types = "0.6.0"

# Here and below:
# We *always* pin the latest version of protocol to disallow accidental changes in the execution logic.
# However, for the historical version of protocol crates, we have lax requirements. Otherwise,
Expand Down
11 changes: 5 additions & 6 deletions core/bin/zksync_server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ use zksync_config::{
},
fri_prover_group::FriProverGroupConfig,
house_keeper::HouseKeeperConfig,
secrets::DataAvailabilitySecrets,
BasicWitnessInputProducerConfig, ContractsConfig, DatabaseSecrets, ExperimentalVmConfig,
ExternalPriceApiClientConfig, FriProofCompressorConfig, FriProverConfig,
FriProverGatewayConfig, FriWitnessGeneratorConfig, FriWitnessVectorGeneratorConfig,
L1Secrets, ObservabilityConfig, PrometheusConfig, ProofDataHandlerConfig,
ProtectiveReadsWriterConfig, Secrets,
BasicWitnessInputProducerConfig, ContractsConfig, DataAvailabilitySecrets, DatabaseSecrets,
ExperimentalVmConfig, ExternalPriceApiClientConfig, FriProofCompressorConfig,
FriProverConfig, FriProverGatewayConfig, FriWitnessGeneratorConfig,
FriWitnessVectorGeneratorConfig, L1Secrets, ObservabilityConfig, PrometheusConfig,
ProofDataHandlerConfig, ProtectiveReadsWriterConfig, Secrets,
},
ApiConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, DAClientConfig, DADispatcherConfig,
DBConfig, EthConfig, EthWatchConfig, ExternalProofIntegrationApiConfig, GasAdjusterConfig,
Expand Down
11 changes: 8 additions & 3 deletions core/bin/zksync_server/src/node_builder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module provides a "builder" for the main node,
//! as well as an interface to run the node with the specified components.
use anyhow::Context;
use anyhow::{bail, Context};
use zksync_config::{
configs::{
da_client::DAClientConfig, secrets::DataAvailabilitySecrets, wallets::Wallets,
Expand All @@ -26,7 +26,7 @@ use zksync_node_framework::{
consensus::MainNodeConsensusLayer,
contract_verification_api::ContractVerificationApiLayer,
da_clients::{
avail::AvailWiringLayer, no_da::NoDAClientWiringLayer,
avail::AvailWiringLayer, celestia::CelestiaWiringLayer, no_da::NoDAClientWiringLayer,
object_store::ObjectStorageClientWiringLayer,
},
da_dispatcher::DataAvailabilityDispatcherLayer,
Expand Down Expand Up @@ -507,16 +507,21 @@ impl MainNodeBuilder {
};

let secrets = try_load_config!(self.secrets.data_availability);

match (da_client_config, secrets) {
(DAClientConfig::Avail(config), DataAvailabilitySecrets::Avail(secret)) => {
self.node.add_layer(AvailWiringLayer::new(config, secret));
}

(DAClientConfig::Celestia(config), DataAvailabilitySecrets::Celestia(secret)) => {
self.node
.add_layer(CelestiaWiringLayer::new(config, secret));
}

(DAClientConfig::ObjectStore(config), _) => {
self.node
.add_layer(ObjectStorageClientWiringLayer::new(config));
}
_ => bail!("invalid pair of da_client and da_secrets"),
}

Ok(self)
Expand Down
20 changes: 0 additions & 20 deletions core/lib/basic_types/src/api_key.rs

This file was deleted.

3 changes: 1 addition & 2 deletions core/lib/basic_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ use serde::{de, Deserialize, Deserializer, Serialize};

#[macro_use]
mod macros;
pub mod api_key;
pub mod basic_fri_types;
pub mod commitment;
pub mod network;
pub mod protocol_version;
pub mod prover_dal;
pub mod pubdata_da;
pub mod seed_phrase;
pub mod secrets;
pub mod settlement;
pub mod tee_types;
pub mod url;
Expand Down
54 changes: 54 additions & 0 deletions core/lib/basic_types/src/secrets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use std::str::FromStr;

use secrecy::{ExposeSecret, Secret};

#[derive(Debug, Clone)]
pub struct SeedPhrase(pub Secret<String>);

impl PartialEq for SeedPhrase {
fn eq(&self, other: &Self) -> bool {
self.0.expose_secret().eq(other.0.expose_secret())
}
}

impl FromStr for SeedPhrase {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(SeedPhrase(s.parse()?))
}
}

#[derive(Debug, Clone)]
pub struct PrivateKey(pub Secret<String>);

impl PartialEq for PrivateKey {
fn eq(&self, other: &Self) -> bool {
self.0.expose_secret().eq(other.0.expose_secret())
}
}

impl FromStr for PrivateKey {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(PrivateKey(s.parse()?))
}
}

#[derive(Debug, Clone)]
pub struct APIKey(pub Secret<String>);

impl PartialEq for APIKey {
fn eq(&self, other: &Self) -> bool {
self.0.expose_secret().eq(other.0.expose_secret())
}
}

impl FromStr for APIKey {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(APIKey(s.parse()?))
}
}
20 changes: 0 additions & 20 deletions core/lib/basic_types/src/seed_phrase.rs

This file was deleted.

4 changes: 2 additions & 2 deletions core/lib/config/src/configs/da_client/avail.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use serde::Deserialize;
use zksync_basic_types::{api_key::APIKey, seed_phrase::SeedPhrase};
use zksync_basic_types::secrets::{APIKey, SeedPhrase};

pub const AVAIL_GAS_RELAY_CLIENT_NAME: &str = "GasRelay";
pub const AVAIL_FULL_CLIENT_NAME: &str = "FullClient";
Expand All @@ -14,7 +14,7 @@ pub enum AvailClientConfig {
#[derive(Clone, Debug, PartialEq, Deserialize)]
pub struct AvailConfig {
pub bridge_api_url: String,
pub timeout: usize,
pub timeout_ms: usize,
#[serde(flatten)]
pub config: AvailClientConfig,
}
Expand Down
15 changes: 15 additions & 0 deletions core/lib/config/src/configs/da_client/celestia.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use serde::Deserialize;
use zksync_basic_types::secrets::PrivateKey;

#[derive(Clone, Debug, Default, PartialEq, Deserialize)]
pub struct CelestiaConfig {
pub api_node_url: String,
pub namespace: String,
pub chain_id: String,
pub timeout_ms: u64,
}

#[derive(Clone, Debug, PartialEq)]
pub struct CelestiaSecrets {
pub private_key: PrivateKey,
}
5 changes: 4 additions & 1 deletion core/lib/config/src/configs/da_client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::{AvailConfig, ObjectStoreConfig};
use crate::{AvailConfig, CelestiaConfig, ObjectStoreConfig};

pub mod avail;
pub mod celestia;

pub const AVAIL_CLIENT_CONFIG_NAME: &str = "Avail";
pub const CELESTIA_CLIENT_CONFIG_NAME: &str = "Celestia";
pub const OBJECT_STORE_CLIENT_CONFIG_NAME: &str = "ObjectStore";

#[derive(Debug, Clone, PartialEq)]
pub enum DAClientConfig {
Avail(AvailConfig),
Celestia(CelestiaConfig),
ObjectStore(ObjectStoreConfig),
}
4 changes: 2 additions & 2 deletions core/lib/config/src/configs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub use self::{
commitment_generator::CommitmentGeneratorConfig,
contract_verifier::ContractVerifierConfig,
contracts::{ContractsConfig, EcosystemContracts},
da_client::{avail::AvailConfig, DAClientConfig},
da_client::{avail::AvailConfig, celestia::CelestiaConfig, DAClientConfig},
da_dispatcher::DADispatcherConfig,
database::{DBConfig, PostgresConfig},
eth_sender::{EthConfig, GasAdjusterConfig},
Expand All @@ -25,7 +25,7 @@ pub use self::{
proof_data_handler::{ProofDataHandlerConfig, TeeConfig},
prover_job_monitor::ProverJobMonitorConfig,
pruning::PruningConfig,
secrets::{DatabaseSecrets, L1Secrets, Secrets},
secrets::{DataAvailabilitySecrets, DatabaseSecrets, L1Secrets, Secrets},
snapshot_recovery::SnapshotRecoveryConfig,
snapshots_creator::SnapshotsCreatorConfig,
utils::PrometheusConfig,
Expand Down
6 changes: 5 additions & 1 deletion core/lib/config/src/configs/secrets.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use anyhow::Context;
use zksync_basic_types::url::SensitiveUrl;

use crate::configs::{consensus::ConsensusSecrets, da_client::avail::AvailSecrets};
use crate::configs::{
consensus::ConsensusSecrets,
da_client::{avail::AvailSecrets, celestia::CelestiaSecrets},
};

#[derive(Debug, Clone, PartialEq)]
pub struct DatabaseSecrets {
Expand All @@ -18,6 +21,7 @@ pub struct L1Secrets {
#[derive(Debug, Clone, PartialEq)]
pub enum DataAvailabilitySecrets {
Avail(AvailSecrets),
Celestia(CelestiaSecrets),
}

#[derive(Debug, Clone, PartialEq)]
Expand Down
4 changes: 2 additions & 2 deletions core/lib/config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![allow(clippy::upper_case_acronyms, clippy::derive_partial_eq_without_eq)]

pub use crate::configs::{
ApiConfig, AvailConfig, BaseTokenAdjusterConfig, ContractVerifierConfig, ContractsConfig,
DAClientConfig, DADispatcherConfig, DBConfig, EthConfig, EthWatchConfig,
ApiConfig, AvailConfig, BaseTokenAdjusterConfig, CelestiaConfig, ContractVerifierConfig,
ContractsConfig, DAClientConfig, DADispatcherConfig, DBConfig, EthConfig, EthWatchConfig,
ExternalProofIntegrationApiConfig, GasAdjusterConfig, GenesisConfig, ObjectStoreConfig,
PostgresConfig, SnapshotsCreatorConfig,
};
Expand Down
5 changes: 2 additions & 3 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use std::num::NonZeroUsize;
use rand::{distributions::Distribution, Rng};
use secrecy::Secret;
use zksync_basic_types::{
api_key::APIKey,
basic_fri_types::CircuitIdRoundTuple,
commitment::L1BatchCommitmentMode,
network::Network,
protocol_version::{ProtocolSemanticVersion, ProtocolVersionId, VersionPatch},
pubdata_da::PubdataSendingMode,
seed_phrase::SeedPhrase,
secrets::{APIKey, SeedPhrase},
vm::FastVmMode,
L1BatchNumber, L1ChainId, L2ChainId,
};
Expand Down Expand Up @@ -949,7 +948,7 @@ impl Distribution<configs::da_client::DAClientConfig> for EncodeDist {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> configs::da_client::DAClientConfig {
Avail(AvailConfig {
bridge_api_url: self.sample(rng),
timeout: self.sample(rng),
timeout_ms: self.sample(rng),
config: AvailClientConfig::FullClient(AvailDefaultConfig {
api_node_url: self.sample(rng),
app_id: self.sample(rng),
Expand Down
Loading

0 comments on commit d88b875

Please sign in to comment.