Skip to content

Commit 84a8f9b

Browse files
feat(batcher): add bool configuration option for enabling pre-verification of proofs (#381)
Co-authored-by: Nicolas Rampoldi <58613770+NicolasRampoldi@users.noreply.github.com>
1 parent 4f2ee26 commit 84a8f9b

4 files changed

Lines changed: 42 additions & 17 deletions

File tree

batcher/aligned-batcher/src/config/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub struct BatcherConfigFromYaml {
1313
pub max_proof_size: usize,
1414
pub max_batch_size: usize,
1515
pub eth_ws_reconnects: usize,
16+
pub pre_verification_is_enabled: bool,
1617
}
1718

1819
#[derive(Debug, Deserialize)]

batcher/aligned-batcher/src/lib.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use std::sync::Arc;
66
use std::time::Duration;
77

88
use crate::eth::BatchVerifiedEventStream;
9+
use aligned_batcher_lib::types::{
10+
BatchInclusionData, VerificationCommitmentBatch, VerificationData, VerificationDataCommitment,
11+
};
912
use aws_sdk_s3::client::Client as S3Client;
1013
use eth::BatchVerifiedFilter;
1114
use ethers::prelude::{Middleware, Provider};
@@ -18,24 +21,22 @@ use tokio::net::{TcpListener, TcpStream};
1821
use tokio::sync::{Mutex, RwLock};
1922
use tokio::time::timeout;
2023
use tokio_tungstenite::tungstenite::error::ProtocolError;
21-
use tokio_tungstenite::tungstenite::protocol::{CloseFrame, frame::coding::CloseCode};
24+
use tokio_tungstenite::tungstenite::protocol::{frame::coding::CloseCode, CloseFrame};
2225
use tokio_tungstenite::tungstenite::{Error, Message};
2326
use tokio_tungstenite::WebSocketStream;
2427
use types::batch_queue::BatchQueue;
2528
use types::errors::BatcherError;
26-
use aligned_batcher_lib::types::{BatchInclusionData, VerificationCommitmentBatch, VerificationData, VerificationDataCommitment};
27-
use zk_utils::verify;
2829

2930
use crate::config::{ConfigFromYaml, ContractDeploymentOutput};
3031
use crate::eth::AlignedLayerServiceManager;
3132

3233
mod config;
3334
mod eth;
34-
pub mod s3;
35-
pub mod types;
3635
pub mod gnark;
3736
pub mod halo2;
37+
pub mod s3;
3838
pub mod sp1;
39+
pub mod types;
3940
mod zk_utils;
4041

4142
const S3_BUCKET_NAME: &str = "storage.alignedlayer.com";
@@ -50,6 +51,7 @@ pub struct Batcher {
5051
max_proof_size: usize,
5152
max_batch_size: usize,
5253
last_uploaded_batch_block: Mutex<u64>,
54+
pre_verification_is_enabled: bool,
5355
}
5456

5557
impl Batcher {
@@ -95,6 +97,7 @@ impl Batcher {
9597
max_proof_size: config.batcher.max_proof_size,
9698
max_batch_size: config.batcher.max_batch_size,
9799
last_uploaded_batch_block: Mutex::new(last_uploaded_batch_block),
100+
pre_verification_is_enabled: config.batcher.pre_verification_is_enabled,
98101
}
99102
}
100103

@@ -162,12 +165,18 @@ impl Batcher {
162165
message: Message,
163166
ws_conn_sink: Arc<RwLock<SplitSink<WebSocketStream<TcpStream>, Message>>>,
164167
) -> Result<(), tokio_tungstenite::tungstenite::Error> {
165-
// Deserialize task from message
168+
// Deserialize verification data from message
166169
let verification_data: VerificationData =
167170
serde_json::from_str(message.to_text().expect("Message is not text"))
168171
.expect("Failed to deserialize task");
169172

170-
if verification_data.proof.len() <= self.max_proof_size && verify(&verification_data){
173+
if verification_data.proof.len() <= self.max_proof_size {
174+
// When pre-verification is enabled, batcher will verify proofs for faster feedback with clients
175+
if self.pre_verification_is_enabled && !zk_utils::verify(&verification_data) {
176+
return Err(tokio_tungstenite::tungstenite::Error::Protocol(
177+
ProtocolError::HandshakeIncomplete,
178+
));
179+
}
171180
self.add_to_batch(verification_data, ws_conn_sink.clone())
172181
.await;
173182
} else {
@@ -324,7 +333,8 @@ impl Batcher {
324333
/// finalizes the batch.
325334
async fn handle_new_block(&self, block_number: u64) -> Result<(), BatcherError> {
326335
while let Some(finalized_batch) = self.is_batch_ready(block_number).await {
327-
self.finalize_batch(block_number, finalized_batch, false).await?;
336+
self.finalize_batch(block_number, finalized_batch, false)
337+
.await?;
328338
}
329339
Ok(())
330340
}

batcher/aligned-batcher/src/zk_utils/mod.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use aligned_batcher_lib::types::{ProvingSystemId, VerificationData};
2-
use crate::sp1::verify_sp1_proof;
3-
use crate::halo2::kzg::verify_halo2_kzg;
4-
use crate::halo2::ipa::verify_halo2_ipa;
51
use crate::gnark::verify_gnark;
2+
use crate::halo2::ipa::verify_halo2_ipa;
3+
use crate::halo2::kzg::verify_halo2_kzg;
4+
use crate::sp1::verify_sp1_proof;
5+
use aligned_batcher_lib::types::{ProvingSystemId, VerificationData};
66
use log::{debug, warn};
77

8-
98
pub(crate) fn verify(verification_data: &VerificationData) -> bool {
109
match verification_data.proving_system {
1110
ProvingSystemId::SP1 => {
@@ -21,7 +20,10 @@ pub(crate) fn verify(verification_data: &VerificationData) -> bool {
2120
.as_ref()
2221
.expect("Verification key is required");
2322

24-
let pub_input = verification_data.pub_input.as_ref().expect("Public input is required");
23+
let pub_input = verification_data
24+
.pub_input
25+
.as_ref()
26+
.expect("Public input is required");
2527
let is_valid = verify_halo2_kzg(&verification_data.proof, pub_input, vk);
2628
debug!("Halo2-KZG proof is valid: {}", is_valid);
2729
is_valid
@@ -32,7 +34,10 @@ pub(crate) fn verify(verification_data: &VerificationData) -> bool {
3234
.as_ref()
3335
.expect("Verification key is required");
3436

35-
let pub_input = verification_data.pub_input.as_ref().expect("Public input is required");
37+
let pub_input = verification_data
38+
.pub_input
39+
.as_ref()
40+
.expect("Public input is required");
3641
let is_valid = verify_halo2_ipa(&verification_data.proof, pub_input, vk);
3742
debug!("Halo2-IPA proof is valid: {}", is_valid);
3843
is_valid
@@ -45,8 +50,16 @@ pub(crate) fn verify(verification_data: &VerificationData) -> bool {
4550
.as_ref()
4651
.expect("Verification key is required");
4752

48-
let pub_input = verification_data.pub_input.as_ref().expect("Public input is required");
49-
let is_valid = verify_gnark(&verification_data.proving_system, &verification_data.proof, pub_input, vk);
53+
let pub_input = verification_data
54+
.pub_input
55+
.as_ref()
56+
.expect("Public input is required");
57+
let is_valid = verify_gnark(
58+
&verification_data.proving_system,
59+
&verification_data.proof,
60+
pub_input,
61+
vk,
62+
);
5063
debug!("Gnark proof is valid: {}", is_valid);
5164
is_valid
5265
}

config-files/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ batcher:
2424
max_proof_size: 67108864 # 64 MiB
2525
max_batch_size: 268435456 # 256 MiB
2626
eth_ws_reconnects: 99999999999999
27+
pre_verification_is_enabled: true
2728

2829
## Aggregator Configurations
2930
aggregator:

0 commit comments

Comments
 (0)