From b4255618708349c51f60f5c7fc26f9356d32b6ff Mon Sep 17 00:00:00 2001 From: Dima Zhornyk <55756184+dimazhornyk@users.noreply.github.com> Date: Tue, 27 Aug 2024 12:20:27 +0200 Subject: [PATCH] feat: add flag to enable/disable DA inclusion verification (#2647) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ This PR adds a config to explicitly enable/disable DA verification onchain. ## Why ❔ Without this feature, any chain using custom DA had to wait for full inclusion before they could commit a batch even if they were not doing the onchain verification. ## Checklist - [ ] 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`. --- core/lib/config/src/configs/da_dispatcher.rs | 11 +++++++ core/lib/config/src/testonly.rs | 1 + core/lib/env_config/src/da_dispatcher.rs | 2 ++ core/lib/protobuf_config/src/da_dispatcher.rs | 2 ++ .../src/proto/config/da_dispatcher.proto | 3 +- core/node/da_dispatcher/src/da_dispatcher.rs | 30 ++++++++++++------- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/core/lib/config/src/configs/da_dispatcher.rs b/core/lib/config/src/configs/da_dispatcher.rs index 303a2c0b54c1..e9ad6bd3c074 100644 --- a/core/lib/config/src/configs/da_dispatcher.rs +++ b/core/lib/config/src/configs/da_dispatcher.rs @@ -5,6 +5,7 @@ use serde::Deserialize; pub const DEFAULT_POLLING_INTERVAL_MS: u32 = 5000; pub const DEFAULT_MAX_ROWS_TO_DISPATCH: u32 = 100; pub const DEFAULT_MAX_RETRIES: u16 = 5; +pub const DEFAULT_USE_DUMMY_INCLUSION_DATA: bool = false; #[derive(Debug, Clone, PartialEq, Deserialize)] pub struct DADispatcherConfig { @@ -14,6 +15,10 @@ pub struct DADispatcherConfig { pub max_rows_to_dispatch: Option, /// The maximum number of retries for the dispatch of a blob. pub max_retries: Option, + /// Use dummy value as inclusion proof instead of getting it from the client. + // TODO: run a verification task to check if the L1 contract expects the inclusion proofs to + // avoid the scenario where contracts expect real proofs, and server is using dummy proofs. + pub use_dummy_inclusion_data: Option, } impl DADispatcherConfig { @@ -22,6 +27,7 @@ impl DADispatcherConfig { polling_interval_ms: Some(DEFAULT_POLLING_INTERVAL_MS), max_rows_to_dispatch: Some(DEFAULT_MAX_ROWS_TO_DISPATCH), max_retries: Some(DEFAULT_MAX_RETRIES), + use_dummy_inclusion_data: Some(DEFAULT_USE_DUMMY_INCLUSION_DATA), } } @@ -40,4 +46,9 @@ impl DADispatcherConfig { pub fn max_retries(&self) -> u16 { self.max_retries.unwrap_or(DEFAULT_MAX_RETRIES) } + + pub fn use_dummy_inclusion_data(&self) -> bool { + self.use_dummy_inclusion_data + .unwrap_or(DEFAULT_USE_DUMMY_INCLUSION_DATA) + } } diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index e028c3d3aec0..2ec91f5bec71 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -940,6 +940,7 @@ impl Distribution for EncodeDist { polling_interval_ms: self.sample(rng), max_rows_to_dispatch: self.sample(rng), max_retries: self.sample(rng), + use_dummy_inclusion_data: self.sample(rng), } } } diff --git a/core/lib/env_config/src/da_dispatcher.rs b/core/lib/env_config/src/da_dispatcher.rs index 194e4185b286..246752db91ac 100644 --- a/core/lib/env_config/src/da_dispatcher.rs +++ b/core/lib/env_config/src/da_dispatcher.rs @@ -26,6 +26,7 @@ mod tests { polling_interval_ms: Some(interval), max_rows_to_dispatch: Some(rows_limit), max_retries: Some(max_retries), + use_dummy_inclusion_data: Some(true), } } @@ -36,6 +37,7 @@ mod tests { DA_DISPATCHER_POLLING_INTERVAL_MS=5000 DA_DISPATCHER_MAX_ROWS_TO_DISPATCH=60 DA_DISPATCHER_MAX_RETRIES=7 + DA_DISPATCHER_USE_DUMMY_INCLUSION_DATA="true" "#; lock.set_env(config); let actual = DADispatcherConfig::from_env().unwrap(); diff --git a/core/lib/protobuf_config/src/da_dispatcher.rs b/core/lib/protobuf_config/src/da_dispatcher.rs index 1cafa37a1e19..d77073bd32cf 100644 --- a/core/lib/protobuf_config/src/da_dispatcher.rs +++ b/core/lib/protobuf_config/src/da_dispatcher.rs @@ -11,6 +11,7 @@ impl ProtoRepr for proto::DataAvailabilityDispatcher { polling_interval_ms: self.polling_interval_ms, max_rows_to_dispatch: self.max_rows_to_dispatch, max_retries: self.max_retries.map(|x| x as u16), + use_dummy_inclusion_data: self.use_dummy_inclusion_data, }) } @@ -19,6 +20,7 @@ impl ProtoRepr for proto::DataAvailabilityDispatcher { polling_interval_ms: this.polling_interval_ms, max_rows_to_dispatch: this.max_rows_to_dispatch, max_retries: this.max_retries.map(Into::into), + use_dummy_inclusion_data: this.use_dummy_inclusion_data, } } } diff --git a/core/lib/protobuf_config/src/proto/config/da_dispatcher.proto b/core/lib/protobuf_config/src/proto/config/da_dispatcher.proto index d1d913498a4e..dd366bd5b925 100644 --- a/core/lib/protobuf_config/src/proto/config/da_dispatcher.proto +++ b/core/lib/protobuf_config/src/proto/config/da_dispatcher.proto @@ -2,10 +2,9 @@ syntax = "proto3"; package zksync.config.da_dispatcher; -import "zksync/config/object_store.proto"; - message DataAvailabilityDispatcher { optional uint32 polling_interval_ms = 1; optional uint32 max_rows_to_dispatch = 2; optional uint32 max_retries = 3; + optional bool use_dummy_inclusion_data = 4; } diff --git a/core/node/da_dispatcher/src/da_dispatcher.rs b/core/node/da_dispatcher/src/da_dispatcher.rs index ea1858da25d3..f8e6f6b31723 100644 --- a/core/node/da_dispatcher/src/da_dispatcher.rs +++ b/core/node/da_dispatcher/src/da_dispatcher.rs @@ -5,7 +5,10 @@ use chrono::Utc; use rand::Rng; use tokio::sync::watch::Receiver; use zksync_config::DADispatcherConfig; -use zksync_da_client::{types::DAError, DataAvailabilityClient}; +use zksync_da_client::{ + types::{DAError, InclusionData}, + DataAvailabilityClient, +}; use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_types::L1BatchNumber; @@ -133,16 +136,21 @@ impl DataAvailabilityDispatcher { return Ok(()); }; - let inclusion_data = self - .client - .get_inclusion_data(blob_info.blob_id.as_str()) - .await - .with_context(|| { - format!( - "failed to get inclusion data for blob_id: {}, batch_number: {}", - blob_info.blob_id, blob_info.l1_batch_number - ) - })?; + let inclusion_data = if self.config.use_dummy_inclusion_data() { + self.client + .get_inclusion_data(blob_info.blob_id.as_str()) + .await + .with_context(|| { + format!( + "failed to get inclusion data for blob_id: {}, batch_number: {}", + blob_info.blob_id, blob_info.l1_batch_number + ) + })? + } else { + // if the inclusion verification is disabled, we don't need to wait for the inclusion + // data before committing the batch, so simply return an empty vector + Some(InclusionData { data: vec![] }) + }; let Some(inclusion_data) = inclusion_data else { return Ok(());