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

feat(eigen-client-pr-comments): Eigen client pr comments #365

Merged
merged 17 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Cargo.lock

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

24 changes: 4 additions & 20 deletions core/lib/config/src/configs/da_client/eigen.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
use serde::Deserialize;
use zksync_basic_types::secrets::PrivateKey;

#[derive(Clone, Debug, PartialEq, Deserialize)]
pub enum PointsSource {
Path(String),
Link(String),
}

impl Default for PointsSource {
fn default() -> Self {
PointsSource::Path("".to_string())
}
}
/// Configuration for the EigenDA remote disperser client.
#[derive(Clone, Debug, PartialEq, Deserialize, Default)]
pub struct EigenConfig {
Expand All @@ -24,18 +12,14 @@ pub struct EigenConfig {
pub eigenda_eth_rpc: String,
/// Address of the service manager contract
pub eigenda_svc_manager_address: String,
/// Maximun amount of time in milliseconds to wait for a status query response
pub status_query_timeout: u64,
/// Interval in milliseconds to query the status of a blob
pub status_query_interval: u64,
/// Wait for the blob to be finalized before returning the response
pub wait_for_finalization: bool,
/// Authenticated dispersal
pub authenticated: bool,
/// Verify the certificate of dispatched blobs
pub verify_cert: bool,
/// Path or link to the file containing the points used for KZG
pub points_source: PointsSource,
/// Url to the file containing the G1 point used for KZG
pub g1_url: String,
/// Url to the file containing the G2 point used for KZG
pub g2_url: String,
/// Chain ID of the Ethereum network
pub chain_id: u64,
}
Expand Down

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

39 changes: 39 additions & 0 deletions core/lib/dal/src/data_availability_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,43 @@ impl DataAvailabilityDal<'_, '_> {
})
.collect())
}

/// Fetches the pubdata for the L1 batch with a given blob id.
pub async fn get_blob_data_by_blob_id(
&mut self,
blob_id: &str,
) -> DalResult<Option<L1BatchDA>> {
let row = sqlx::query!(
r#"
SELECT
number,
pubdata_input
FROM
l1_batches
LEFT JOIN
data_availability
ON data_availability.l1_batch_number = l1_batches.number
WHERE
number != 0
AND data_availability.blob_id = $1
AND pubdata_input IS NOT NULL
ORDER BY
number
LIMIT
1
"#,
blob_id,
)
.instrument("get_blob_data_by_blob_id")
.with_arg("blob_id", &blob_id)
.fetch_optional(self.storage)
.await?
.map(|row| L1BatchDA {
// `unwrap` is safe here because we have a `WHERE` clause that filters out `NULL` values
pubdata: row.pubdata_input.unwrap(),
l1_batch_number: L1BatchNumber(row.number as u32),
});

Ok(row)
}
}
57 changes: 20 additions & 37 deletions core/lib/env_config/src/da_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,18 @@ impl FromEnv for DAClientConfig {
}),
CELESTIA_CLIENT_CONFIG_NAME => Self::Celestia(envy_load("da_celestia_config", "DA_")?),
EIGEN_CLIENT_CONFIG_NAME => Self::Eigen(EigenConfig {
disperser_rpc: env::var("DA_DISPERSER_RPC")?,
disperser_rpc: env::var("EIGENDA_DISPERSER_RPC")?,
settlement_layer_confirmation_depth: env::var(
"DA_SETTLEMENT_LAYER_CONFIRMATION_DEPTH",
"EIGENDA_SETTLEMENT_LAYER_CONFIRMATION_DEPTH",
)?
.parse()?,
eigenda_eth_rpc: env::var("DA_EIGENDA_ETH_RPC")?,
eigenda_svc_manager_address: env::var("DA_EIGENDA_SVC_MANAGER_ADDRESS")?,
status_query_timeout: env::var("DA_STATUS_QUERY_TIMEOUT")?.parse()?,
status_query_interval: env::var("DA_STATUS_QUERY_INTERVAL")?.parse()?,
wait_for_finalization: env::var("DA_WAIT_FOR_FINALIZATION")?.parse()?,
authenticated: env::var("DA_AUTHENTICATED")?.parse()?,
verify_cert: env::var("DA_VERIFY_CERT")?.parse()?,
points_source: match env::var("DA_POINTS_SOURCE")?.as_str() {
"Path" => zksync_config::configs::da_client::eigen::PointsSource::Path(
env::var("DA_POINTS_PATH")?,
),
"Link" => zksync_config::configs::da_client::eigen::PointsSource::Link(
env::var("DA_POINTS_LINK")?,
),
_ => anyhow::bail!("Unknown Eigen points type"),
},
chain_id: env::var("DA_CHAIN_ID")?.parse()?,
eigenda_eth_rpc: env::var("EIGENDA_EIGENDA_ETH_RPC")?,
eigenda_svc_manager_address: env::var("EIGENDA_EIGENDA_SVC_MANAGER_ADDRESS")?,
wait_for_finalization: env::var("EIGENDA_WAIT_FOR_FINALIZATION")?.parse()?,
authenticated: env::var("EIGENDA_AUTHENTICATED")?.parse()?,
g1_url: env::var("EIGENDA_G1_URL")?.parse()?,
g2_url: env::var("EIGENDA_G2_URL")?.parse()?,
chain_id: env::var("EIGENDA_CHAIN_ID")?.parse()?,
}),
OBJECT_STORE_CLIENT_CONFIG_NAME => {
Self::ObjectStore(envy_load("da_object_store", "DA_")?)
Expand Down Expand Up @@ -121,7 +111,6 @@ mod tests {
configs::{
da_client::{
avail::{AvailClientConfig, AvailDefaultConfig},
eigen::PointsSource,
DAClientConfig::{self, ObjectStore},
},
object_store::ObjectStoreMode::GCS,
Expand Down Expand Up @@ -276,19 +265,15 @@ mod tests {
let mut lock = MUTEX.lock();
let config = r#"
DA_CLIENT="Eigen"
DA_EIGEN_CLIENT_TYPE="Disperser"
DA_DISPERSER_RPC="http://localhost:8080"
DA_SETTLEMENT_LAYER_CONFIRMATION_DEPTH=0
DA_EIGENDA_ETH_RPC="http://localhost:8545"
DA_EIGENDA_SVC_MANAGER_ADDRESS="0x123"
DA_STATUS_QUERY_TIMEOUT=2
DA_STATUS_QUERY_INTERVAL=3
DA_WAIT_FOR_FINALIZATION=true
DA_AUTHENTICATED=false
DA_VERIFY_CERT=false
DA_POINTS_SOURCE="Path"
DA_POINTS_PATH="resources"
DA_CHAIN_ID=1
EIGENDA_DISPERSER_RPC="http://localhost:8080"
EIGENDA_SETTLEMENT_LAYER_CONFIRMATION_DEPTH=0
EIGENDA_EIGENDA_ETH_RPC="http://localhost:8545"
EIGENDA_EIGENDA_SVC_MANAGER_ADDRESS="0x123"
EIGENDA_WAIT_FOR_FINALIZATION=true
EIGENDA_AUTHENTICATED=false
EIGENDA_G1_URL="resources1"
EIGENDA_G2_URL="resources2"
EIGENDA_CHAIN_ID=1
"#;
lock.set_env(config);

Expand All @@ -300,12 +285,10 @@ mod tests {
settlement_layer_confirmation_depth: 0,
eigenda_eth_rpc: "http://localhost:8545".to_string(),
eigenda_svc_manager_address: "0x123".to_string(),
status_query_timeout: 2,
status_query_interval: 3,
wait_for_finalization: true,
authenticated: false,
verify_cert: false,
points_source: PointsSource::Path("resources".to_string()),
g1_url: "resources1".to_string(),
g2_url: "resources2".to_string(),
chain_id: 1
})
);
Expand Down
37 changes: 5 additions & 32 deletions core/lib/protobuf_config/src/da_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use zksync_config::configs::{
use zksync_protobuf::{required, ProtoRepr};

use crate::proto::{
da_client::{self as proto, Link, Path},
da_client::{self as proto},
object_store as object_store_proto,
};

Expand Down Expand Up @@ -69,25 +69,11 @@ impl ProtoRepr for proto::DataAvailabilityClient {
eigenda_svc_manager_address: required(&conf.eigenda_svc_manager_address)
.context("eigenda_svc_manager_address")?
.clone(),
status_query_timeout: *required(&conf.status_query_timeout)
.context("status_query_timeout")?,
status_query_interval: *required(&conf.status_query_interval)
.context("status_query_interval")?,
wait_for_finalization: *required(&conf.wait_for_finalization)
.context("wait_for_finalization")?,
authenticated: *required(&conf.authenticated).context("authenticated")?,
verify_cert: *required(&conf.verify_cert).context("verify_cert")?,
points_source: match conf.points_source.clone() {
Some(proto::eigen_config::PointsSource::Path(path)) => {
let path = required(&path.path).context("path")?;
zksync_config::configs::da_client::eigen::PointsSource::Path(path.clone())
}
Some(proto::eigen_config::PointsSource::Link(link)) => {
let link = required(&link.link).context("link")?;
zksync_config::configs::da_client::eigen::PointsSource::Link(link.clone())
}
None => return Err(anyhow::anyhow!("Invalid Eigen DA configuration")),
},
g1_url: required(&conf.g1_url).context("g1_url")?.clone(),
g2_url: required(&conf.g2_url).context("g2_url")?.clone(),
chain_id: *required(&conf.chain_id).context("chain_id")?,
}),
proto::data_availability_client::Config::ObjectStore(conf) => {
Expand Down Expand Up @@ -133,23 +119,10 @@ impl ProtoRepr for proto::DataAvailabilityClient {
),
eigenda_eth_rpc: Some(config.eigenda_eth_rpc.clone()),
eigenda_svc_manager_address: Some(config.eigenda_svc_manager_address.clone()),
status_query_timeout: Some(config.status_query_timeout),
status_query_interval: Some(config.status_query_interval),
wait_for_finalization: Some(config.wait_for_finalization),
authenticated: Some(config.authenticated),
verify_cert: Some(config.verify_cert),
points_source: Some(match &config.points_source {
zksync_config::configs::da_client::eigen::PointsSource::Path(path) => {
proto::eigen_config::PointsSource::Path(Path {
path: Some(path.to_string()),
})
}
zksync_config::configs::da_client::eigen::PointsSource::Link(link) => {
proto::eigen_config::PointsSource::Link(Link {
link: Some(link.to_string()),
})
}
}),
g1_url: Some(config.g1_url.clone()),
g2_url: Some(config.g2_url.clone()),
chain_id: Some(config.chain_id),
}),
ObjectStore(config) => proto::data_availability_client::Config::ObjectStore(
Expand Down
23 changes: 5 additions & 18 deletions core/lib/protobuf_config/src/proto/config/da_client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,16 @@ message CelestiaConfig {
optional uint64 timeout_ms = 4;
}

message Path {
optional string path = 1;
}

message Link {
optional string link = 1;
}

message EigenConfig {
optional string disperser_rpc = 3;
optional int32 settlement_layer_confirmation_depth = 4;
optional string eigenda_eth_rpc = 5;
optional string eigenda_svc_manager_address = 6;
optional uint64 status_query_timeout = 7;
optional uint64 status_query_interval = 8;
optional bool wait_for_finalization = 9;
optional bool authenticated = 10;
optional bool verify_cert = 11;
oneof points_source {
Path path = 12;
Link link = 13;
}
optional uint64 chain_id = 14;
optional bool wait_for_finalization = 7;
optional bool authenticated = 8;
optional string g1_url = 9;
optional string g2_url = 10;
optional uint64 chain_id = 11;
reserved 1,2;
reserved "rpc_node_url","inclusion_polling_interval_ms";
}
Expand Down
2 changes: 1 addition & 1 deletion core/node/da_clients/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ pbjson-types.workspace = true

# Eigen dependencies
tokio-stream.workspace = true
rlp.workspace = true
rand.workspace = true
sha3.workspace = true
tiny-keccak.workspace = true
Expand All @@ -66,3 +65,4 @@ num-bigint.workspace = true
serial_test.workspace = true
zksync_web3_decl.workspace = true
zksync_eth_client.workspace = true
url.workspace = true
24 changes: 0 additions & 24 deletions core/node/da_clients/src/eigen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,6 @@ EigenDA is as a high-throughput data availability layer for rollups. It is an Ei
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/).

## Status

There a 3 milestones defined, we are currently on the first one.

### M0: Read and Write integration

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

### M1: Secure integration with ZKProver

For this milestone the scope is to replace the mocked L1 verification logic with EigenDA compatible verifier. It should
integrate EigenDA certificate verification, and use it as the equivalent part for 4844 versioned hash. More importantly
modify the equivalence proof in Zksync L1 contract such that the proof can be verified correctly with respect to the
EigenDA commitment, which also lives in BN254 as zksync. Start with 128MiB blob, then 2MiB, up-to 32MiB blobs. Prepare
documentation and tooling in order to onboard rollups with EigenDA.

### M2: Secure and cost efficient

The scope is to explore approaches to reduce cost. For example, faster proof generation time. Verify EigenDA signature
inside circuit, this requires L2 having access to L1 state. Integrate EigenDA into ZKporter.

## Temporary

In order to implement the integration we generated some `.proto` files from EigenDA repo that were compiled using the
Expand Down
Loading
Loading