Skip to content

Commit 292ca25

Browse files
committed
fix: beacon client matching blob versioned hash
1 parent 2cc2d0f commit 292ca25

4 files changed

Lines changed: 42 additions & 59 deletions

File tree

batcher/aligned-sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ hex = "0.4.3"
2525
ciborium = "=0.2.2"
2626
serde_repr = "0.1.19"
2727
dialoguer = "0.11.0"
28-
reqwest = { version = "0.12" }
28+
reqwest = { version = "0.12", features = ["json"] }
Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
use crate::{
22
beacon::{BeaconClient, BeaconClientError},
3-
core::types::{Network, ProvingSystemId, VerificationData},
4-
eth::aligned_proof_agg_service::aligned_proof_aggregation_service,
3+
core::types::Network,
54
};
65
use ethers::{
76
providers::{Http, Middleware, Provider},
87
types::Filter,
98
};
10-
use sha3::{Digest, Keccak256};
119

10+
#[derive(Debug)]
1211
pub enum ProofVerificationAggModeError {
1312
ProvingSystemNotSupportedInAggMode,
1413
EthereumProviderError(String),
@@ -18,58 +17,40 @@ pub enum ProofVerificationAggModeError {
1817
/// Given aligned verification data, it verifies if the proof was verified in the last aggregated proof
1918
/// Currently, this in Beta mode so there isn't a way to know exactly to which proof it belongs
2019
/// So currently we check if included in the last one and verify the merkle root commitment
20+
/// The step by step verification consists of:
21+
/// 1. Query the blob versioned hash of latest event from aligned proof aggregation service contract
22+
/// 2. Get the beacon block via the block parent beacon root
23+
/// 3. Fetch the blobs for that slot
24+
/// 4. Filter the blob with the blob versioned hash
25+
/// 5. Decode the blobs proofs
26+
/// 6. Find if the proofs hash is inside the blob proofs
27+
/// 7. Construct merkle root and verify it matches the one in the contract
2128
pub async fn is_proof_verified_in_aggregation_mode(
22-
aligned_verification_data: &VerificationData,
29+
proof_hash: String,
2330
network: Network,
2431
eth_rpc_url: String,
2532
beacon_client_url: String,
2633
from_block: u64,
2734
) -> Result<bool, ProofVerificationAggModeError> {
28-
let supported = match aligned_verification_data.proving_system {
29-
ProvingSystemId::SP1 => true,
30-
_ => false,
31-
};
32-
33-
if !supported {
34-
return Err(ProofVerificationAggModeError::ProvingSystemNotSupportedInAggMode);
35-
}
36-
3735
// TODO: check if the from_block is past 18 days as the blob_data won't be available anymore
3836

39-
let proof_hash: [u8; 32] = match aligned_verification_data.proving_system {
40-
ProvingSystemId::SP1 => {
41-
let mut hasher = Keccak256::new();
42-
let vk = aligned_verification_data.verification_key.clone().unwrap();
43-
let public_inputs = aligned_verification_data.pub_input.clone().unwrap();
44-
hasher.update(&vk);
45-
hasher.update(&public_inputs);
46-
hasher.finalize().into()
47-
}
48-
// we already filter the supported ones
49-
_ => unreachable!(),
50-
};
51-
52-
/// We have to
53-
/// 1. Query the blob versioned hash of latest event from aligned proof aggregation service contract
54-
/// 2. Get the beacon block via the block parent beacon root
55-
/// 3. Fetch the blobs for that slot
56-
/// 4. Filter the blob with the blob versioned hash
57-
/// 5. Decode the blobs proofs
58-
/// 6. Find if the proofs hash is inside the blob proofs
59-
/// 7. Construct merkle root and verify it matches the one in the contract
6037
let eth_rpc_provider = Provider::<Http>::try_from(eth_rpc_url)
6138
.map_err(|e| ProofVerificationAggModeError::EthereumProviderError(e.to_string()))?;
6239

6340
let filter = Filter::new()
41+
.address(network.get_aligned_proof_agg_service_address())
6442
.event("AggregatedProofVerified(bytes32,bytes32)")
6543
.from_block(from_block);
6644

67-
let mut to_check: Vec<(String, String, u64)> = vec![];
45+
let mut to_check: Vec<([u8; 32], [u8; 32], u64)> = vec![];
6846

6947
let logs = eth_rpc_provider.get_logs(&filter).await.unwrap();
7048
for log in logs {
71-
let blob_versioned_hash = String::from_utf8(log.data[0..66].to_vec()).unwrap();
72-
let merkle_root = String::from_utf8(log.topics.get(1).unwrap().0.to_vec()).unwrap();
49+
let blob_versioned_hash: [u8; 32] = log.data[0..32]
50+
.try_into()
51+
.expect("Data has incorrect length");
52+
let merkle_root = log.topics.get(1).expect("to decode merkle root in index").0;
53+
7354
to_check.push((
7455
blob_versioned_hash,
7556
merkle_root,
@@ -88,22 +69,25 @@ pub async fn is_proof_verified_in_aggregation_mode(
8869
.unwrap();
8970
let beacon_parent_root = block.parent_beacon_block_root.unwrap();
9071

91-
let block = beacon_client
72+
let beacon_block = beacon_client
9273
.get_block_header_from_parent_hash(beacon_parent_root.0)
9374
.await
9475
.map_err(ProofVerificationAggModeError::BeaconClient)?
9576
.unwrap();
9677

9778
let blob = beacon_client
98-
.get_blob_by_versioned_hash(block.header.message.slot, blob_versioned_hash.clone())
79+
.get_blob_by_versioned_hash(
80+
beacon_block.header.message.slot.parse().expect("a number"),
81+
blob_versioned_hash,
82+
)
9983
.await
10084
.map_err(ProofVerificationAggModeError::BeaconClient)?
10185
.unwrap();
10286

10387
let proof_hashes = decoded_blob(blob.blob.into());
10488

10589
// decoded blob and get all leaves and see if it the has is inside
106-
if proof_hashes.contains(&blob_versioned_hash) {
90+
if proof_hashes.contains(&[0u8; 32]) {
10791
return Ok(verify_merkle_root(proof_hashes, merkle_root));
10892
} else {
10993
continue;
@@ -113,12 +97,12 @@ pub async fn is_proof_verified_in_aggregation_mode(
11397
Ok(false)
11498
}
11599

116-
fn decoded_blob(blob_data: Vec<u8>) -> Vec<String> {
100+
fn decoded_blob(blob_data: Vec<u8>) -> Vec<[u8; 32]> {
117101
let proof_hashes = vec![];
118102

119103
proof_hashes
120104
}
121105

122-
fn verify_merkle_root(proof_hashes: Vec<String>, merkle_root: String) -> bool {
106+
fn verify_merkle_root(proof_hashes: Vec<[u8; 32]>, merkle_root: [u8; 32]) -> bool {
123107
true
124108
}

batcher/aligned-sdk/src/beacon.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub struct BeaconClient {
1414

1515
#[derive(Debug, Serialize, Deserialize)]
1616
#[serde(untagged)]
17-
enum BeaconResponse {
17+
enum BeaconAPIResponse {
1818
Success { data: Value },
1919
Error { code: u64, message: String },
2020
}
@@ -42,7 +42,7 @@ impl GetBlobResponse {
4242

4343
#[derive(Deserialize, Debug)]
4444
pub struct BlobData {
45-
pub index: u64,
45+
pub index: String,
4646
pub blob: String,
4747
pub kzg_commitment: String,
4848
pub kzg_proof: String,
@@ -76,7 +76,7 @@ pub struct BeaconBlockHeader {
7676

7777
#[derive(Deserialize, Debug)]
7878
pub struct BeaconBlockMessage {
79-
pub slot: u64,
79+
pub slot: String,
8080
pub proposer_index: String,
8181
pub parent_root: String,
8282
pub state_root: String,
@@ -128,18 +128,20 @@ impl BeaconClient {
128128
pub async fn get_blob_by_versioned_hash(
129129
&self,
130130
slot: u64,
131-
blob_versioned_hash_hex: String,
131+
blob_versioned_hash: [u8; 32],
132132
) -> Result<Option<BlobData>, BeaconClientError> {
133133
let res = self.get_blobs_from_slot(slot).await?;
134134

135135
let blob = res.blobs.into_iter().find(|blob| {
136+
let kzg_commitment_bytes =
137+
hex::decode(blob.kzg_commitment.replace("0x", "")).expect("A valid commitment");
138+
136139
let mut hasher = Sha256::new();
137-
hasher.update(blob.kzg_commitment.clone());
138-
let mut hash: [u8; 32] = hasher.finalize().into();
139-
hash[0] = KZG_VERSIONED_HASH;
140-
let versioned_hash = format!("0x{}", hex::encode(hash));
140+
hasher.update(&kzg_commitment_bytes);
141+
let mut versioned_hash: [u8; 32] = hasher.finalize().into();
142+
versioned_hash[0] = KZG_VERSIONED_HASH;
141143

142-
versioned_hash == blob_versioned_hash_hex
144+
versioned_hash == blob_versioned_hash
143145
});
144146

145147
Ok(blob)
@@ -155,14 +157,11 @@ impl BeaconClient {
155157
.header("accept", "application/json");
156158

157159
let res = req.send().await.map_err(BeaconClientError::ReqwestError)?;
158-
let beacon_response = res
159-
.json::<BeaconResponse>()
160-
.await
161-
.map_err(BeaconClientError::ReqwestError)?;
160+
let beacon_response = res.json().await.map_err(BeaconClientError::ReqwestError)?;
162161

163162
match beacon_response {
164-
BeaconResponse::Success { data } => Ok(data),
165-
BeaconResponse::Error { code, message } => {
163+
BeaconAPIResponse::Success { data } => Ok(data),
164+
BeaconAPIResponse::Error { code, message } => {
166165
Err(BeaconClientError::APIError { code, message })
167166
}
168167
}

batcher/aligned-sdk/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ pub mod eth {
1717
pub mod batcher_payment_service;
1818
}
1919

20-
mod agg_mode;
20+
pub mod agg_mode;
2121
mod beacon;
2222
pub mod sdk;

0 commit comments

Comments
 (0)