diff --git a/core/lib/config/src/configs/da_client/eigen.rs b/core/lib/config/src/configs/da_client/eigen.rs index 6e353b6b1928..a07d932d3dc8 100644 --- a/core/lib/config/src/configs/da_client/eigen.rs +++ b/core/lib/config/src/configs/da_client/eigen.rs @@ -7,13 +7,11 @@ pub struct EigenConfig { 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, + pub settlement_layer_confirmation_depth: i32, /// URL of the Ethereum RPC server pub eigenda_eth_rpc: String, /// 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, /// 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 diff --git a/core/lib/env_config/src/da_client.rs b/core/lib/env_config/src/da_client.rs index 43fe451618f5..8cd7658cd1db 100644 --- a/core/lib/env_config/src/da_client.rs +++ b/core/lib/env_config/src/da_client.rs @@ -250,10 +250,9 @@ mod tests { DA_CLIENT="Eigen" DA_EIGEN_CLIENT_TYPE="Disperser" DA_DISPERSER_RPC="http://localhost:8080" - DA_ETH_CONFIRMATION_DEPTH=0 + DA_SETTLEMENT_LAYER_CONFIRMATION_DEPTH=0 DA_EIGENDA_ETH_RPC="http://localhost:8545" DA_EIGENDA_SVC_MANAGER_ADDRESS="0x123" - DA_BLOB_SIZE_LIMIT=1000 DA_STATUS_QUERY_TIMEOUT=2 DA_STATUS_QUERY_INTERVAL=3 DA_WAIT_FOR_FINALIZATION=true @@ -269,10 +268,9 @@ mod tests { actual, DAClientConfig::Eigen(EigenConfig { disperser_rpc: "http://localhost:8080".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, eigenda_eth_rpc: "http://localhost:8545".to_string(), eigenda_svc_manager_address: "0x123".to_string(), - blob_size_limit: 1000, status_query_timeout: 2, status_query_interval: 3, wait_for_finalization: true, diff --git a/core/lib/protobuf_config/src/da_client.rs b/core/lib/protobuf_config/src/da_client.rs index f5cff8215738..210171be1875 100644 --- a/core/lib/protobuf_config/src/da_client.rs +++ b/core/lib/protobuf_config/src/da_client.rs @@ -56,15 +56,16 @@ impl ProtoRepr for proto::DataAvailabilityClient { disperser_rpc: required(&conf.disperser_rpc) .context("disperser_rpc")? .clone(), - eth_confirmation_depth: *required(&conf.eth_confirmation_depth) - .context("eth_confirmation_depth")?, + settlement_layer_confirmation_depth: *required( + &conf.settlement_layer_confirmation_depth, + ) + .context("settlement_layer_confirmation_depth")?, eigenda_eth_rpc: required(&conf.eigenda_eth_rpc) .context("eigenda_eth_rpc")? .clone(), eigenda_svc_manager_address: required(&conf.eigenda_svc_manager_address) .context("eigenda_svc_manager_address")? .clone(), - blob_size_limit: *required(&conf.blob_size_limit).context("blob_size_limit")?, status_query_timeout: *required(&conf.status_query_timeout) .context("status_query_timeout")?, status_query_interval: *required(&conf.status_query_interval) @@ -116,10 +117,11 @@ impl ProtoRepr for proto::DataAvailabilityClient { } Eigen(config) => proto::data_availability_client::Config::Eigen(proto::EigenConfig { disperser_rpc: Some(config.disperser_rpc.clone()), - eth_confirmation_depth: Some(config.eth_confirmation_depth), + settlement_layer_confirmation_depth: Some( + config.settlement_layer_confirmation_depth, + ), eigenda_eth_rpc: Some(config.eigenda_eth_rpc.clone()), eigenda_svc_manager_address: Some(config.eigenda_svc_manager_address.clone()), - blob_size_limit: Some(config.blob_size_limit), status_query_timeout: Some(config.status_query_timeout), status_query_interval: Some(config.status_query_interval), wait_for_finalization: Some(config.wait_for_finalization), diff --git a/core/lib/protobuf_config/src/proto/config/da_client.proto b/core/lib/protobuf_config/src/proto/config/da_client.proto index ce814c5657b0..8463629b3240 100644 --- a/core/lib/protobuf_config/src/proto/config/da_client.proto +++ b/core/lib/protobuf_config/src/proto/config/da_client.proto @@ -37,19 +37,19 @@ message CelestiaConfig { } message EigenConfig { - reserved 1,2; optional string disperser_rpc = 3; - optional int32 eth_confirmation_depth = 4; + optional int32 settlement_layer_confirmation_depth = 4; optional string eigenda_eth_rpc = 5; optional string eigenda_svc_manager_address = 6; - optional uint32 blob_size_limit = 7; - optional uint64 status_query_timeout = 8; - optional uint64 status_query_interval = 9; - optional bool wait_for_finalization = 10; - optional bool authenticated = 11; - optional bool verify_cert = 12; - optional string path_to_points = 13; - optional uint64 chain_id = 14; + 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; + optional string path_to_points = 12; + optional uint64 chain_id = 13; + reserved 1,2; + reserved "rpc_node_url","inclusion_polling_interval_ms"; } message DataAvailabilityClient { diff --git a/core/node/da_clients/src/eigen/client.rs b/core/node/da_clients/src/eigen/client.rs index a97c6feb3293..175297b9415b 100644 --- a/core/node/da_clients/src/eigen/client.rs +++ b/core/node/da_clients/src/eigen/client.rs @@ -46,15 +46,6 @@ impl DataAvailabilityClient for EigenClient { _: u32, // batch number data: Vec, ) -> Result { - if let Some(blob_size_limit) = self.blob_size_limit() { - if data.len() > blob_size_limit { - return Err(DAError { - error: anyhow!("Blob size limit exceeded"), - is_retriable: false, - }); - } - } - let blob_id = self .client .dispatch_blob(data) @@ -88,7 +79,7 @@ impl DataAvailabilityClient for EigenClient { } fn blob_size_limit(&self) -> Option { - Some(self.client.clone().config.blob_size_limit as usize) + Some(RawEigenClient::blob_size_limit()) } } @@ -111,12 +102,11 @@ mod tests { async fn test_non_auth_dispersal() { let config = EigenConfig { disperser_rpc: "https://disperser-holesky.eigenda.xyz:443".to_string(), - eth_confirmation_depth: -1, + settlement_layer_confirmation_depth: -1, eigenda_eth_rpc: "https://ethereum-holesky-rpc.publicnode.com".to_string(), eigenda_svc_manager_address: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), - blob_size_limit: 2 * 1024 * 1024, // 2MB - status_query_timeout: 1800000, // 30 minutes - status_query_interval: 5, // 5 ms + status_query_timeout: 1800000, // 30 minutes + status_query_interval: 5, // 5 ms wait_for_finalization: false, authenticated: false, verify_cert: true, @@ -154,12 +144,11 @@ mod tests { async fn test_auth_dispersal() { let config = EigenConfig { disperser_rpc: "https://disperser-holesky.eigenda.xyz:443".to_string(), - eth_confirmation_depth: -1, + settlement_layer_confirmation_depth: -1, eigenda_eth_rpc: "https://ethereum-holesky-rpc.publicnode.com".to_string(), eigenda_svc_manager_address: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), - blob_size_limit: 2 * 1024 * 1024, // 2MB - status_query_timeout: 1800000, // 30 minutes - status_query_interval: 5, // 5 ms + status_query_timeout: 1800000, // 30 minutes + status_query_interval: 5, // 5 ms wait_for_finalization: false, authenticated: true, verify_cert: true, @@ -196,14 +185,13 @@ mod tests { async fn test_wait_for_finalization() { let config = EigenConfig { disperser_rpc: "https://disperser-holesky.eigenda.xyz:443".to_string(), - blob_size_limit: 2 * 1024 * 1024, // 2MB - status_query_timeout: 1800000, // 30 minutes - status_query_interval: 5000, // 5000 ms + status_query_timeout: 1800000, // 30 minutes + status_query_interval: 5000, // 5000 ms wait_for_finalization: true, authenticated: true, verify_cert: true, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, eigenda_eth_rpc: "https://ethereum-holesky-rpc.publicnode.com".to_string(), eigenda_svc_manager_address: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), chain_id: 17000, @@ -233,51 +221,16 @@ mod tests { assert_eq!(retrieved_data.unwrap(), data); } - #[tokio::test] - async fn test_eigenda_dispatch_blob_too_large() { - let config = EigenConfig { - disperser_rpc: "https://disperser-holesky.eigenda.xyz:443".to_string(), - blob_size_limit: 99, - status_query_timeout: 1800000, // 30 minutes - status_query_interval: 5000, // 5000 ms - wait_for_finalization: true, - authenticated: true, - verify_cert: true, - path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, - eigenda_eth_rpc: "https://ethereum-holesky-rpc.publicnode.com".to_string(), - eigenda_svc_manager_address: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), - chain_id: 17000, - }; - let secrets = EigenSecrets { - private_key: PrivateKey::from_str( - "d08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6", - ) - .unwrap(), - }; - let client = EigenClient::new(config, secrets).await.unwrap(); - let data = vec![1u8; 100]; - let actual_error = client - .dispatch_blob(0, data.clone()) - .await - .err() - .unwrap() - .error; - let expected_error = anyhow!("Blob size limit exceeded"); - assert_eq!(format!("{}", actual_error), format!("{}", expected_error)); - } - #[tokio::test] #[serial] - async fn test_eth_confirmation_depth() { + async fn test_settlement_layer_confirmation_depth() { let config = EigenConfig { disperser_rpc: "https://disperser-holesky.eigenda.xyz:443".to_string(), - eth_confirmation_depth: 5, + settlement_layer_confirmation_depth: 5, eigenda_eth_rpc: "https://ethereum-holesky-rpc.publicnode.com".to_string(), eigenda_svc_manager_address: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), - blob_size_limit: 2 * 1024 * 1024, // 2MB - status_query_timeout: 1800000, // 30 minutes - status_query_interval: 5, // 5 ms + status_query_timeout: 1800000, // 30 minutes + status_query_interval: 5, // 5 ms wait_for_finalization: false, authenticated: false, verify_cert: true, @@ -311,15 +264,14 @@ mod tests { #[tokio::test] #[serial] - async fn test_auth_dispersal_eth_confirmation_depth() { + async fn test_auth_dispersal_settlement_layer_confirmation_depth() { let config = EigenConfig { disperser_rpc: "https://disperser-holesky.eigenda.xyz:443".to_string(), - eth_confirmation_depth: 5, + settlement_layer_confirmation_depth: 5, eigenda_eth_rpc: "https://ethereum-holesky-rpc.publicnode.com".to_string(), eigenda_svc_manager_address: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), - blob_size_limit: 2 * 1024 * 1024, // 2MB - status_query_timeout: 1800000, // 30 minutes - status_query_interval: 5, // 5 ms + status_query_timeout: 1800000, // 30 minutes + status_query_interval: 5, // 5 ms wait_for_finalization: false, authenticated: true, verify_cert: true, diff --git a/core/node/da_clients/src/eigen/eigenda-integration.md b/core/node/da_clients/src/eigen/eigenda-integration.md index fa31ef596d96..e15178e0fcfc 100644 --- a/core/node/da_clients/src/eigen/eigenda-integration.md +++ b/core/node/da_clients/src/eigen/eigenda-integration.md @@ -21,10 +21,9 @@ Changes needed both for local and mainnet/testnet setup. da_client: eigen: disperser_rpc: - eth_confirmation_depth: -1 + settlement_layer_confirmation_depth: -1 eigenda_eth_rpc: eigenda_svc_manager_address: '0xD4A7E1Bd8015057293f0D0A557088c286942e84b' - blob_size_limit: 2097152 status_query_timeout: 1800000 # ms status_query_interval: 5 # ms wait_for_finalization: false diff --git a/core/node/da_clients/src/eigen/lib.rs b/core/node/da_clients/src/eigen/lib.rs new file mode 100644 index 000000000000..46a7bc34bbd1 --- /dev/null +++ b/core/node/da_clients/src/eigen/lib.rs @@ -0,0 +1,3 @@ +pub const BATCH_ID_TO_METADATA_HASH_FUNCTION_SELECTOR: [u8; 4] = [236, 203, 191, 201]; +pub const QUORUM_ADVERSARY_THRESHOLD_PERCENTAGES_FUNCTION_SELECTOR: [u8; 4] = [134, 135, 254, 174]; +pub const QUORUM_NUMBERS_REQUIRED_FUNCTION_SELECTOR: [u8; 4] = [225, 82, 52, 255]; diff --git a/core/node/da_clients/src/eigen/mod.rs b/core/node/da_clients/src/eigen/mod.rs index a198c13e03a1..fe979becdb9f 100644 --- a/core/node/da_clients/src/eigen/mod.rs +++ b/core/node/da_clients/src/eigen/mod.rs @@ -1,5 +1,6 @@ mod blob_info; mod client; +mod lib; mod sdk; mod verifier; diff --git a/core/node/da_clients/src/eigen/sdk.rs b/core/node/da_clients/src/eigen/sdk.rs index 0cffca5ba092..0704b26c9a23 100644 --- a/core/node/da_clients/src/eigen/sdk.rs +++ b/core/node/da_clients/src/eigen/sdk.rs @@ -39,6 +39,7 @@ pub(crate) const AVG_BLOCK_TIME: u64 = 12; impl RawEigenClient { pub(crate) const BUFFER_SIZE: usize = 1000; + const BLOB_SIZE_LIMIT: usize = 1024 * 1024 * 2; // 2 MB pub async fn new(private_key: SecretKey, config: EigenConfig) -> anyhow::Result { let endpoint = @@ -50,9 +51,10 @@ impl RawEigenClient { let verifier_config = VerifierConfig { rpc_url: config.eigenda_eth_rpc.clone(), svc_manager_addr: config.eigenda_svc_manager_address.clone(), - max_blob_size: config.blob_size_limit, + max_blob_size: Self::BLOB_SIZE_LIMIT as u32, path_to_points: config.path_to_points.clone(), - eth_confirmation_depth: config.eth_confirmation_depth.max(0) as u32, + settlement_layer_confirmation_depth: config.settlement_layer_confirmation_depth.max(0) + as u32, private_key: hex::encode(private_key.secret_bytes()), chain_id: config.chain_id, }; @@ -66,6 +68,10 @@ impl RawEigenClient { }) } + pub fn blob_size_limit() -> usize { + Self::BLOB_SIZE_LIMIT + } + async fn dispatch_blob_non_authenticated(&self, data: Vec) -> anyhow::Result { let padded_data = convert_by_padding_empty_byte(&data); let request = disperser::DisperseBlobRequest { @@ -80,7 +86,7 @@ impl RawEigenClient { Ok(hex::encode(disperse_reply.request_id)) } - async fn loop_verify_certificate( + async fn perform_verification( &self, blob_info: BlobInfo, disperse_elapsed: Duration, @@ -155,7 +161,7 @@ impl RawEigenClient { .verify_commitment(blob_info.blob_header.commitment.clone(), data.unwrap()) .map_err(|_| anyhow::anyhow!("Failed to verify commitment"))?; - self.loop_verify_certificate(blob_info.clone(), disperse_elapsed) + self.perform_verification(blob_info.clone(), disperse_elapsed) .await?; let verification_proof = blob_info.blob_verification_proof.clone(); diff --git a/core/node/da_clients/src/eigen/verifier.rs b/core/node/da_clients/src/eigen/verifier.rs index 3beaeeccc980..b505f6f3c2d3 100644 --- a/core/node/da_clients/src/eigen/verifier.rs +++ b/core/node/da_clients/src/eigen/verifier.rs @@ -13,7 +13,14 @@ use zksync_types::{ }; use zksync_web3_decl::client::{Client, DynClient, L1}; -use super::blob_info::{BatchHeader, BlobHeader, BlobInfo, G1Commitment}; +use super::{ + blob_info::{BatchHeader, BlobHeader, BlobInfo, G1Commitment}, + lib::{ + BATCH_ID_TO_METADATA_HASH_FUNCTION_SELECTOR, + QUORUM_ADVERSARY_THRESHOLD_PERCENTAGES_FUNCTION_SELECTOR, + QUORUM_NUMBERS_REQUIRED_FUNCTION_SELECTOR, + }, +}; #[derive(Debug)] pub enum VerificationError { @@ -38,7 +45,7 @@ pub struct VerifierConfig { pub svc_manager_addr: String, pub max_blob_size: u32, pub path_to_points: String, - pub eth_confirmation_depth: u32, + pub settlement_layer_confirmation_depth: u32, pub private_key: String, pub chain_id: u64, } @@ -55,9 +62,6 @@ pub struct Verifier { impl Verifier { const DEFAULT_PRIORITY_FEE_PER_GAS: u64 = 100; - const BATCH_ID_TO_METADATA_HASH_FUNCTION_SELECTOR: [u8; 4] = [236, 203, 191, 201]; - const QUORUM_ADVERSARY_THRESHOLD_PERCENTAGES_FUNCTION_SELECTOR: [u8; 4] = [134, 135, 254, 174]; - const QUORUM_NUMBERS_REQUIRED_FUNCTION_SELECTOR: [u8; 4] = [225, 82, 52, 255]; pub fn new(cfg: VerifierConfig) -> Result { let srs_points_to_load = cfg.max_blob_size / 32; let kzg = Kzg::setup( @@ -266,17 +270,17 @@ impl Verifier { .map_err(|_| VerificationError::ServiceManagerError)? .as_u64(); - if self.cfg.eth_confirmation_depth == 0 { + if self.cfg.settlement_layer_confirmation_depth == 0 { return Ok(latest); } - Ok(latest - (self.cfg.eth_confirmation_depth as u64 - 1)) + Ok(latest - (self.cfg.settlement_layer_confirmation_depth as u64 - 1)) } /// Verifies the certificate batch hash async fn verify_batch(&self, cert: BlobInfo) -> Result<(), VerificationError> { let context_block = self.get_context_block().await?; - let mut data = Self::BATCH_ID_TO_METADATA_HASH_FUNCTION_SELECTOR.to_vec(); + 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()); @@ -369,7 +373,7 @@ impl Verifier { &self, quorum_number: u32, ) -> Result { - let data = Self::QUORUM_ADVERSARY_THRESHOLD_PERCENTAGES_FUNCTION_SELECTOR.to_vec(); + let data = QUORUM_ADVERSARY_THRESHOLD_PERCENTAGES_FUNCTION_SELECTOR.to_vec(); let call_request = CallRequest { to: Some( @@ -434,7 +438,7 @@ impl Verifier { confirmed_quorums.insert(blob_header.blob_quorum_params[i].quorum_number, true); } - let data = Self::QUORUM_NUMBERS_REQUIRED_FUNCTION_SELECTOR.to_vec(); + let data = QUORUM_NUMBERS_REQUIRED_FUNCTION_SELECTOR.to_vec(); let call_request = CallRequest { to: Some( H160::from_str(&self.cfg.svc_manager_addr) @@ -486,7 +490,7 @@ mod test { svc_manager_addr: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), max_blob_size: 2 * 1024 * 1024, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, private_key: "0xd08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6" .to_string(), chain_id: 17000, @@ -514,7 +518,7 @@ mod test { svc_manager_addr: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), max_blob_size: 2 * 1024 * 1024, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, private_key: "0xd08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6" .to_string(), chain_id: 17000, @@ -603,7 +607,7 @@ mod test { svc_manager_addr: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), max_blob_size: 2 * 1024 * 1024, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, private_key: "0xd08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6" .to_string(), chain_id: 17000, @@ -648,7 +652,7 @@ mod test { svc_manager_addr: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), max_blob_size: 2 * 1024 * 1024, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, private_key: "0xd08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6" .to_string(), chain_id: 17000, @@ -676,7 +680,7 @@ mod test { svc_manager_addr: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), max_blob_size: 2 * 1024 * 1024, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, private_key: "0xd08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6" .to_string(), chain_id: 17000, @@ -765,7 +769,7 @@ mod test { svc_manager_addr: "0xD4A7E1Bd8015057293f0D0A557088c286942e84b".to_string(), max_blob_size: 2 * 1024 * 1024, path_to_points: "../../../resources".to_string(), - eth_confirmation_depth: 0, + settlement_layer_confirmation_depth: 0, private_key: "0xd08aa7ae1bb5ddd46c3c2d8cdb5894ab9f54dec467233686ca42629e826ac4c6" .to_string(), chain_id: 17000,