-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Implement eigenDA client remaining features #3243
base: main
Are you sure you want to change the base?
Implement eigenDA client remaining features #3243
Conversation
impl rlp encoding
Implement non auth blob dispersal for eigen client --------- Co-authored-by: Gianbelinche <[email protected]>
feat(eigen-client-extra-features): get inclusion data
add test for remote disperser cfg
* initial commit * Add tests * Add memstore * Add assert to tests * Add rest of memstore * Address pr comments * Remove to retriable error * Fix conflicts * Document memstore * Fix typo --------- Co-authored-by: Juan Munoz <[email protected]>
blob size limit --------- Co-authored-by: Gianbelinche <[email protected]>
* initial commit * Add tests * Add memstore * Add assert to tests * Add rest of memstore * Add soft confirmations * Remove print * Address pr comments * Remove to retriable error * Fix conflicts * Add inclusion data * Change status query timeout to millis * Document memstore * Fix typo * Fix typo * Format --------- Co-authored-by: Juan Munoz <[email protected]>
* initial commit * Add tests * Add memstore * Add assert to tests * Add rest of memstore * Address pr comments * Remove to retriable error * Fix conflicts * Add verifier * Fix verifier * Add path to points to config * Fix typo * Fix eigenda env test * Fix verifier test * Move eigendaservicemanager to generated * Remove unneeded imports * Document verifier * Modify errors * Address comments * Fix conflicts --------- Co-authored-by: Juan Munoz <[email protected]>
* initial commit * move file location * fix step
* Add eth confirmation depth * Fix error
#329) * Remove unused custom quorum numbers * Add serial to tests
feat(eigen-client-extra-features): fix clippy and add doc
feat(eigen-client-extra-features): merge main
…dule-update feat(eigen-client-extra-features): update contracts submodule
fn test_verify_commitment() { | ||
let verifier = super::Verifier::new(super::VerifierConfig { | ||
verify_certs: true, | ||
rpc_url: "https://ethereum-holesky-rpc.publicnode.com".to_string(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks like the test relies on the external RPC, which means it could be blocking the CI if RPC is unavailable
let's rework this to remove the external dependency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, the thing is that we can't test it locally since there is no working local setup for EigenDA. So we had to test on testnet directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use mocks instead of external calls?
|
||
let verifier_config = VerifierConfig { | ||
verify_certs: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe let's make it a part of the config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what part are you referring to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially thought about verify_certs
variable, but now that I think about it, it shouldn't exist at all
to verify the inclusion or not should be defined by the use_dummy_inclusion_data
variable, if it is true - the verifier won't even be used
rpc_url: config.eigenda_eth_rpc.clone(), | ||
svc_manager_addr: config.eigenda_svc_manager_address.clone(), | ||
max_blob_size: config.blob_size_limit, | ||
path_to_points: config.path_to_points.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that these points have to be present every time this code is run? This would add an ops load that we would ideally want to avoid. Is there a way to get rid of the points file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we need it every time that code is run. One solution can be to have the contents of the file bundled with the binary. The downside of that approach is that it will increase the size of the resulting binary in ~30mb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, I see
none of it is a great option tbh, let's do something to optimize this
maybe we could ask the EigenDA team to publish it to the S3/GCS bucket managed by them, and then in case the client is started with the verification enabled - it will fetch the points from the bucket
* Remove kzgpad * Add empty pad and unpad test
* Remove kzgpad * Move dependencies
* Add backon instead loops * Add constant for avg block time
* Remove extra config * Use bn254 crate
* Add zksync client * Call service manager with zksync client * Add rest of calls * Remove alloy * Remove unwraps * Remove todos * Harcode function selectors * Remove service manager json * Fix clippy
…merge-main Eigen client extra features merge main
pub disperser_rpc: String, | ||
/// Block height needed to reach in order to consider the blob finalized | ||
/// a value less or equal to 0 means that the disperser will not wait for finalization | ||
pub eth_confirmation_depth: i32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's better to use l1_
or settlement_layer_
here instead of eth_
because the settlement layer is not necessarily an Ethereum mainnet
/// a value less or equal to 0 means that the disperser will not wait for finalization | ||
pub eth_confirmation_depth: i32, | ||
/// URL of the Ethereum RPC server | ||
pub eigenda_eth_rpc: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can reuse the RPC that's used for sending txs to L1, it is already provided in the secrets
/// Address of the service manager contract | ||
pub eigenda_svc_manager_address: String, | ||
/// Maximum size permitted for a blob in bytes | ||
pub blob_size_limit: u32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't be a part of the config, it is defined by the "protocol" i.e. the max value that EigenDA can handle and there is a check in da_dispatcher
that max_pubdata_per_batch
is lower than that value
/// Path to the file containing the points used for KZG | ||
pub path_to_points: String, | ||
/// Chain ID of the Ethereum network | ||
pub chain_id: u64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like it is unused
@@ -37,8 +37,19 @@ message CelestiaConfig { | |||
} | |||
|
|||
message EigenConfig { | |||
optional string rpc_node_url = 1; | |||
optional uint64 inclusion_polling_interval_ms = 2; | |||
reserved 1,2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move it to the bottom of the message
for better readability and let's also reserve the field name, not only the index
(|| async { self.verifier.verify_certificate(blob_info.clone()).await }) | ||
.retry( | ||
&ConstantBuilder::default() | ||
.with_delay(Duration::from_secs(AVG_BLOCK_TIME)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you shouldn't use 12s delay here
if we assume this func is called with some interval (defined by da_dispatcher
) - we shouldn't be doing any sleeps here at all, only retries in case the request to L1 failed
.verify_commitment(blob_info.blob_header.commitment.clone(), data) | ||
.map_err(|_| anyhow::anyhow!("Failed to verify commitment"))?; | ||
|
||
self.loop_verify_certificate(blob_info.clone(), disperse_elapsed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, dispatch shouldn't be blocked by inclusion
} | ||
|
||
impl Verifier { | ||
const DEFAULT_PRIORITY_FEE_PER_GAS: u64 = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it needed if the client won't be sending any txs?
|
||
impl Verifier { | ||
const DEFAULT_PRIORITY_FEE_PER_GAS: u64 = 100; | ||
const BATCH_ID_TO_METADATA_HASH_FUNCTION_SELECTOR: [u8; 4] = [236, 203, 191, 201]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is going to be difficult to maintain, could you please use something like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just recalled that there is an easier way where you don't need to include the contracts in our codebase, example:
let func_selector = ethabi::short_signature(
"validatePubdata",
&[
ParamType::FixedBytes(32),
ParamType::FixedBytes(32),
ParamType::FixedBytes(32),
ParamType::FixedBytes(32),
ParamType::Bytes,
],
);
fn test_verify_commitment() { | ||
let verifier = super::Verifier::new(super::VerifierConfig { | ||
verify_certs: true, | ||
rpc_url: "https://ethereum-holesky-rpc.publicnode.com".to_string(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use mocks instead of external calls?
* Move inclusion logic * Remove unused import
* Move inclusion logic * Remove verify cert
* Change eth conf depth for settlement layer * Remove blob size limit * Move reserved * Change function name * Add constants to lib * Fix compilation
* initial commit * remove anyhow err * Format code * Fix compilation --------- Co-authored-by: Gianbelinche <[email protected]>
* Add option to download points * Fix test * Fix clippy * Change name to points source * Fix test * Fix test
…s with mock tests (#356) * initial commit * create verifier client trait * remove unwraps * Update core/node/da_clients/src/eigen/verifier.rs Ignore test Co-authored-by: Gianbelinche <[email protected]> * Update core/node/da_clients/src/eigen/sdk.rs Co-authored-by: Gianbelinche <[email protected]> * change ignore test comment * Format code --------- Co-authored-by: Gianbelinche <[email protected]>
…on docs (#360) * Remove steps to run from integration docs * Combine readme * Clarify readme
…and-main feat(eigen-client-extra-features): Merge Main
|
||
impl Default for PointsSource { | ||
fn default() -> Self { | ||
PointsSource::Path("".to_string()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that this was added to allow #[derive(Default)]
for EigenConfig
, but if someone actually uses it - it won't work for them
can we publish the points to some storage, e.g. GCS, and refer to that storage by default
/// Authenticated dispersal | ||
pub authenticated: bool, | ||
/// Verify the certificate of dispatched blobs | ||
pub verify_cert: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it used anywhere?
optional bool authenticated = 10; | ||
optional bool verify_cert = 11; | ||
oneof points_source { | ||
Path path = 12; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can do it like this
oneof points_source {
string path = 12;
string link = 13;
}
oneof
assumes that it is optional by default
The generated files are received by compiling the `.proto` files from EigenDA repo using the following function: | ||
There a 3 milestones defined, we are currently on the first one. | ||
|
||
### M0: Read and Write integration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as I understand, that's more of a Lambda's milestone here, MatterLabs has slightly different ones
let's consider either removing this or making it more generic like
- create an MVP client
- improve the client //we are here
- enable verification on L1
- optimize
|
||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if I understand it correctly - you are saying you want to integrate the EigenDA inclusion verification in our circuits
I doubt that it is possible, most likely a separate proof will be used for it
impl Verifier { | ||
pub const DEFAULT_PRIORITY_FEE_PER_GAS: u64 = 100; | ||
async fn save_points(link: String) -> Result<String, VerificationError> { | ||
let url_g1 = format!("{}{}", link, "/g1.point"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's better use the Url
package for this, to avoid issues when someone provides a path with trailing slash and it all fails
&format!("{}{}", path, "/g1.point"), | ||
"", | ||
&format!("{}{}", path, "/g2.point.powerOf2"), | ||
268435456, // 2 ^ 28 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's maybe use constant for it?
let mut data = BATCH_ID_TO_METADATA_HASH_FUNCTION_SELECTOR.to_vec(); | ||
let mut batch_id_vec = [0u8; 32]; | ||
U256::from(cert.blob_verification_proof.batch_id).to_big_endian(&mut batch_id_vec); | ||
data.append(batch_id_vec.to_vec().as_mut()); | ||
|
||
let call_request = CallRequest { | ||
to: Some( | ||
H160::from_str(&self.cfg.svc_manager_addr) | ||
.map_err(|_| VerificationError::ServiceManagerError)?, | ||
), | ||
data: Some(zksync_basic_types::web3::Bytes(data)), | ||
..Default::default() | ||
}; | ||
|
||
let res = self | ||
.signing_client | ||
.as_ref() | ||
.call_contract_function( | ||
call_request, | ||
Some(BlockId::Number(BlockNumber::Number(context_block.into()))), | ||
) | ||
.await | ||
.map_err(|_| VerificationError::ServiceManagerError)?; | ||
|
||
let expected_hash = res.0.to_vec(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all of this can be moved to the separate func for better readability
} | ||
} | ||
|
||
/// Mock struct for the Verifier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here with tests, can they be moved to a separate file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as per comment above, let's remove those and use some remote storage as default
What ❔
This PR adds extra functionality to the eigen client:
Why ❔
These features are needed to have a full featured client and to have the same features as when communicating with the EigenDA proxy.
Checklist
zkstack dev fmt
andzkstack dev lint
.