Skip to content

Commit

Permalink
Merge pull request #307 from lambdaclass/eigenda-proxy-config
Browse files Browse the repository at this point in the history
feat: Eigenda Config
  • Loading branch information
juanbono authored Oct 18, 2024
2 parents e859ca2 + 7f948de commit 4a19f54
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 40 deletions.
8 changes: 7 additions & 1 deletion core/bin/zksync_server/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,13 @@ impl MainNodeBuilder {
}

fn add_eigenda_proxy_layer(mut self) -> anyhow::Result<Self> {
self.node.add_layer(EigenDAProxyLayer::new());
let da_config = try_load_config!(self.configs.da_client_config);
match da_config {
DAClientConfig::EigenDA(config) => {
self.node.add_layer(EigenDAProxyLayer::new(config));
}
_ => {}
}
Ok(self)
}

Expand Down
30 changes: 26 additions & 4 deletions core/lib/config/src/configs/da_client/eigen_da.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
use serde::Deserialize;

#[derive(Clone, Debug, PartialEq, Deserialize)]

pub enum EigenDAConfig {
MemStore(MemStoreConfig),
Disperser(DisperserConfig),
}

#[derive(Clone, Debug, PartialEq, Deserialize, Default)]
pub struct MemStoreConfig {
pub api_node_url: String, // todo: This should be removed once eigenda proxy is no longer used
pub custom_quorum_numbers: Option<Vec<u32>>, // todo: This should be removed once eigenda proxy is no longer used
pub account_id: Option<String>, // todo: This should be removed once eigenda proxy is no longer used
pub max_blob_size_bytes: u64,
pub blob_expiration: u64,
pub get_latency: u64,
pub put_latency: u64,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Default)]
pub struct EigenDAConfig {
pub api_node_url: String,
pub custom_quorum_numbers: Option<Vec<u32>>,
pub account_id: Option<String>,
pub struct DisperserConfig {
pub api_node_url: String, // todo: This should be removed once eigenda proxy is no longer used
pub custom_quorum_numbers: Option<Vec<u32>>, // todo: This should be removed once eigenda proxy is no longer used
pub account_id: Option<String>, // todo: This should be removed once eigenda proxy is no longer used
pub disperser_rpc: String,
pub eth_confirmation_depth: i32,
pub eigenda_eth_rpc: String,
pub eigenda_svc_manager_addr: String,
}
113 changes: 93 additions & 20 deletions core/lib/protobuf_config/src/da_client.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use anyhow::Context;
use zksync_config::{
configs::{
self,
da_client::{
eigen_da::EigenDAConfig,
eigen_da::{DisperserConfig, EigenDAConfig, MemStoreConfig},
DAClientConfig::{Avail, EigenDA, ObjectStore},
},
{self},
},
AvailConfig,
};
Expand Down Expand Up @@ -34,13 +34,54 @@ impl ProtoRepr for proto::DataAvailabilityClient {
proto::data_availability_client::Config::ObjectStore(conf) => {
ObjectStore(object_store_proto::ObjectStore::read(conf)?)
}
proto::data_availability_client::Config::EigenDa(conf) => EigenDA(EigenDAConfig {
api_node_url: required(&conf.api_node_url)
.context("api_node_url")?
.clone(),
custom_quorum_numbers: Some(conf.custom_quorum_numbers.clone()),
account_id: conf.account_id.clone(),
}),
proto::data_availability_client::Config::EigenDa(conf) => {
let config = required(&conf.config).context("config")?;
let eigenda_config = match config {
proto::eigen_da_config::Config::MemStore(conf) => {
EigenDAConfig::MemStore(MemStoreConfig {
api_node_url: required(&conf.api_node_url)
.context("api_node_url")?
.clone(),
custom_quorum_numbers: Some(conf.custom_quorum_numbers.clone()),
account_id: conf.account_id.clone(),
max_blob_size_bytes: required(&conf.max_blob_size_bytes)
.context("max_blob_size_bytes")?
.clone(),
blob_expiration: required(&conf.blob_expiration)
.context("blob_expiration")?
.clone(),
get_latency: required(&conf.get_latency)
.context("get_latency")?
.clone(),
put_latency: required(&conf.put_latency)
.context("put_latency")?
.clone(),
})
}
proto::eigen_da_config::Config::Disperser(conf) => {
EigenDAConfig::Disperser(DisperserConfig {
api_node_url: required(&conf.api_node_url)
.context("api_node_url")?
.clone(),
custom_quorum_numbers: Some(conf.custom_quorum_numbers.clone()),
account_id: conf.account_id.clone(),
disperser_rpc: required(&conf.disperser_rpc)
.context("disperser_rpc")?
.clone(),
eth_confirmation_depth: required(&conf.eth_confirmation_depth)
.context("eth_confirmation_depth")?
.clone(),
eigenda_eth_rpc: required(&conf.eigenda_eth_rpc)
.context("eigenda_eth_rpc")?
.clone(),
eigenda_svc_manager_addr: required(&conf.eigenda_svc_manager_addr)
.context("eigenda_svc_manager_addr")?
.clone(),
})
}
};
EigenDA(eigenda_config)
}
};

Ok(client)
Expand All @@ -64,17 +105,49 @@ impl ProtoRepr for proto::DataAvailabilityClient {
object_store_proto::ObjectStore::build(config),
)),
},
EigenDA(config) => Self {
config: Some(proto::data_availability_client::Config::EigenDa(
proto::EigenDaConfig {
api_node_url: Some(config.api_node_url.clone()),
custom_quorum_numbers: config
.custom_quorum_numbers
.clone()
.unwrap_or_default(),
account_id: config.account_id.clone(),
},
)),
EigenDA(config) => match config {
EigenDAConfig::MemStore(config) => Self {
config: Some(proto::data_availability_client::Config::EigenDa(
proto::EigenDaConfig {
config: Some(proto::eigen_da_config::Config::MemStore(
proto::MemStoreConfig {
api_node_url: Some(config.api_node_url.clone()),
custom_quorum_numbers: config
.custom_quorum_numbers
.clone()
.unwrap_or_default(),
account_id: config.account_id.clone(),
max_blob_size_bytes: Some(config.max_blob_size_bytes),
blob_expiration: Some(config.blob_expiration),
get_latency: Some(config.get_latency),
put_latency: Some(config.put_latency),
},
)),
},
)),
},
EigenDAConfig::Disperser(config) => Self {
config: Some(proto::data_availability_client::Config::EigenDa(
proto::EigenDaConfig {
config: Some(proto::eigen_da_config::Config::Disperser(
proto::DisperserConfig {
api_node_url: Some(config.api_node_url.clone()),
custom_quorum_numbers: config
.custom_quorum_numbers
.clone()
.unwrap_or_default(),
account_id: config.account_id.clone(),
disperser_rpc: Some(config.disperser_rpc.clone()),
eth_confirmation_depth: Some(config.eth_confirmation_depth),
eigenda_eth_rpc: Some(config.eigenda_eth_rpc.clone()),
eigenda_svc_manager_addr: Some(
config.eigenda_svc_manager_addr.clone(),
),
},
)),
},
)),
},
},
}
}
Expand Down
27 changes: 24 additions & 3 deletions core/lib/protobuf_config/src/proto/config/da_client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,31 @@ message AvailConfig {
reserved 3; reserved "seed";
}

message MemStoreConfig {
optional string api_node_url = 1; // TODO: This should be removed once eigenda proxy is no longer used
repeated uint32 custom_quorum_numbers = 2; // TODO: This should be removed once eigenda proxy is no longer used
optional string account_id = 3; // TODO: This should be removed once eigenda proxy is no longer used
optional uint64 max_blob_size_bytes = 5;
optional uint64 blob_expiration = 6;
optional uint64 get_latency = 7;
optional uint64 put_latency = 8;
}

message DisperserConfig {
optional string api_node_url = 1; // TODO: This should be removed once eigenda proxy is no longer used
repeated uint32 custom_quorum_numbers = 2; // TODO: This should be removed once eigenda proxy is no longer used
optional string account_id = 3; // TODO: This should be removed once eigenda proxy is no longer used
optional string disperser_rpc = 4;
optional int32 eth_confirmation_depth = 5;
optional string eigenda_eth_rpc = 6;
optional string eigenda_svc_manager_addr = 7;
}

message EigenDaConfig {
optional string api_node_url = 1;
repeated uint32 custom_quorum_numbers = 2;
optional string account_id = 3;
oneof config {
MemStoreConfig mem_store = 1;
DisperserConfig disperser = 2;
}
}

message DataAvailabilityClient {
Expand Down
12 changes: 10 additions & 2 deletions core/node/da_clients/src/eigen_da.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ impl DataAvailabilityClient for EigenDAClient {
_batch_number: u32,
blob_data: Vec<u8>,
) -> Result<types::DispatchResponse, types::DAError> {
let api_node_url = match &self.config {
EigenDAConfig::MemStore(config) => &config.api_node_url,
EigenDAConfig::Disperser(config) => &config.api_node_url,
}; // TODO: This should be removed once eigenda proxy is no longer used
let response = self
.client
.post(format!("{}/put/", self.config.api_node_url))
.post(format!("{}/put/", api_node_url))
.header(http::header::CONTENT_TYPE, "application/octetstream")
.body(blob_data)
.send()
Expand All @@ -53,9 +57,13 @@ impl DataAvailabilityClient for EigenDAClient {
&self,
blob_id: &str,
) -> anyhow::Result<Option<types::InclusionData>, types::DAError> {
let api_node_url = match &self.config {
EigenDAConfig::MemStore(config) => &config.api_node_url,
EigenDAConfig::Disperser(config) => &config.api_node_url,
}; // TODO: This should be removed once eigenda proxy is no longer used
let response = self
.client
.get(format!("{}/get/0x{}", self.config.api_node_url, blob_id))
.get(format!("{}/get/0x{}", api_node_url, blob_id))
.send()
.await
.map_err(to_retriable_error)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
IntoContext,
};

#[derive(Debug, Default)]
#[derive(Debug)]
pub struct EigenDAWiringLayer {
config: EigenDAConfig,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use zksync_config::configs::da_client::eigen_da::EigenDAConfig;

use crate::{
implementations::resources::{
object_store::ObjectStoreResource,
Expand All @@ -11,7 +13,9 @@ use crate::{

/// Wiring layer for eigenda server.
#[derive(Debug)]
pub struct EigenDAProxyLayer {}
pub struct EigenDAProxyLayer {
eigenda_config: EigenDAConfig,
}

#[derive(Debug, FromContext)]
#[context(crate = crate)]
Expand All @@ -28,8 +32,8 @@ pub struct Output {
}

impl EigenDAProxyLayer {
pub fn new() -> Self {
Self {}
pub fn new(eigenda_config: EigenDAConfig) -> Self {
Self { eigenda_config }
}
}

Expand Down
36 changes: 30 additions & 6 deletions eigenda-integration.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,48 @@
# Zksync-era <> EigenDA Integration

EigenDA is as a high-throughput data availability layer for rollups. It is an EigenLayer AVS (Actively Validated Service), so it leverages Ethereum's economic security instead of bootstrapping a new network with its own validators.
EigenDA is as a high-throughput data availability layer for rollups. It is an EigenLayer AVS (Actively Validated
Service), so it leverages Ethereum's economic security instead of bootstrapping a new network with its own validators.
For more information you can check the [docs](https://docs.eigenda.xyz/).

## Scope

The scope of this first milestone is to spin up a local EigenDA dev environment, spin up a local zksync-era dev environment and integrate them. Instead of sending 4844 blobs, the zksync-era sends blobs to EigenDA. EigenDA provides a high level client called [eigenda-proxy](https://github.com/Layr-Labs/eigenda-proxy), and it is used to communicate with the EigenDA disperser in a secury and easy way.
On L1, mock the verification logic, such that blocks continue building. Increase the blob size from 4844 size to 2MiB blob.
Deploy the integration to Holesky testnet and provide scripts to setup a network using EigenDA as DA provider.
The scope of this first milestone is to spin up a local EigenDA dev environment, spin up a local zksync-era dev
environment and integrate them. Instead of sending 4844 blobs, the zksync-era sends blobs to EigenDA. EigenDA provides a
high level client called [eigenda-proxy](https://github.com/Layr-Labs/eigenda-proxy), and it is used to communicate with
the EigenDA disperser in a secury and easy way. On L1, mock the verification logic, such that blocks continue building.
Increase the blob size from 4844 size to 2MiB blob. Deploy the integration to Holesky testnet and provide scripts to
setup a network using EigenDA as DA provider.

## Common changes

Changes needed both for local and mainnet/testnet setup.

1. Add `da_client` to `etc/env/file_based/general.yaml`:

If you want to use memstore:

```yaml
da_client:
eigen_da:
memstore:
api_node_url: http://127.0.0.1:4242 # TODO: This should be removed once eigenda proxy is no longer used
max_blob_size_bytes: 2097152
blob_expiration: 100000
get_latency: 100
put_latency: 100
```
If you want to use disperser:
```yaml
da_client:
eigen_da:
api_node_url: http://127.0.0.1:4242
disperser:
api_node_url: http://127.0.0.1:4242 # TODO: This should be removed once eigenda proxy is no longer used
disperser_rpc: <your_desired_disperser>
eth_confirmation_depth: -1
eigenda_eth_rpc: <your_desired_rpc>
eigenda_svc_manager_addr: '0xD4A7E1Bd8015057293f0D0A557088c286942e84b'
```
2. Add `eigenda-proxy` to the `docker-compose.yml` file:
Expand All @@ -27,7 +51,7 @@ da_client:
eigenda-proxy:
image: ghcr.io/layr-labs/eigenda-proxy
ports:
- "4242:4242"
- '4242:4242'
command: ./eigenda-proxy --addr 0.0.0.0 --port 4242 --memstore.enabled --eigenda-max-blob-length "2MiB"
```

Expand Down

0 comments on commit 4a19f54

Please sign in to comment.