Skip to content

Commit 260fa07

Browse files
committed
refactor: error handling and comments
1 parent 8c62555 commit 260fa07

3 files changed

Lines changed: 72 additions & 56 deletions

File tree

batcher/aligned-sdk/src/agg_mode.rs

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,96 +13,105 @@ pub enum ProofVerificationAggModeError {
1313
ProvingSystemNotSupportedInAggMode,
1414
EthereumProviderError(String),
1515
BeaconClient(BeaconClientError),
16+
UnmatchedBlobAndEventMerkleRoot,
17+
ProofNotFoundInLogs,
18+
EventDecoding,
1619
}
1720

18-
/// Given aligned verification data, it verifies if the proof was verified in the last aggregated proof
19-
/// Currently, this in Beta mode so there isn't a way to know exactly to which proof it belongs
20-
/// So currently we check if included in the last one and verify the merkle root commitment
21-
/// The step by step verification consists of:
22-
/// 1. Query the blob versioned hash of latest event from aligned proof aggregation service contract
23-
/// 2. Get the beacon block via the block parent beacon root
24-
/// 3. Fetch the blobs for that slot
25-
/// 4. Filter the blob with the blob versioned hash
26-
/// 5. Decode the blobs proofs
27-
/// 6. Find if the proofs hash is inside the blob proofs
28-
/// 7. Construct merkle root and verify it matches the one in the contract
21+
/// Given aligned verification data, this function checks whether a proof was included
22+
/// in the most recent aggregated proof and verifies the corresponding Merkle root commitment.
23+
///
24+
/// Note: This functionality is currently in Beta. As a result, we cannot determine with certainty
25+
/// which specific aggregation a proof belongs to. Instead, we optimistically check the latest one.
26+
///
27+
/// ⚠️ The `from` block used in the verification process must not be older than 18 days,
28+
/// as blobs expire after that period and will no longer be retrievable.
29+
///
30+
/// The step-by-step verification process includes:
31+
/// 1. Querying the blob versioned hash from the latest event emitted by the aligned proof aggregation service contract
32+
/// 2. Retrieving the corresponding beacon block using the block’s parent beacon root
33+
/// 3. Fetching the blobs associated with that slot
34+
/// 4. Filtering the blob that matches the queried blob versioned hash
35+
/// 5. Decoding the blob to extract the proofs
36+
/// 6. Checking if the given proof hash exists within the blob’s proofs
37+
/// 7. Reconstructing the Merkle root and verifying it against the commitment stored in the contract
2938
pub async fn is_proof_verified_in_aggregation_mode(
30-
proof_hash: String,
39+
proof_hash: [u8; 32],
3140
network: Network,
3241
eth_rpc_url: String,
3342
beacon_client_url: String,
3443
from_block: u64,
35-
) -> Result<bool, ProofVerificationAggModeError> {
36-
// TODO: check if the from_block is past 18 days as the blob_data won't be available anymore
37-
44+
) -> Result<[u8; 32], ProofVerificationAggModeError> {
3845
let eth_rpc_provider = Provider::<Http>::try_from(eth_rpc_url)
3946
.map_err(|e| ProofVerificationAggModeError::EthereumProviderError(e.to_string()))?;
47+
let beacon_client = BeaconClient::new(beacon_client_url);
4048

4149
let filter = Filter::new()
4250
.address(network.get_aligned_proof_agg_service_address())
4351
.event("AggregatedProofVerified(bytes32,bytes32)")
4452
.from_block(from_block);
4553

46-
let mut to_check: Vec<([u8; 32], [u8; 32], u64)> = vec![];
47-
4854
let logs = eth_rpc_provider.get_logs(&filter).await.unwrap();
4955
for log in logs {
5056
let blob_versioned_hash: [u8; 32] = log.data[0..32]
5157
.try_into()
52-
.expect("Data has incorrect length");
53-
let merkle_root = log.topics.get(1).expect("to decode merkle root in index").0;
54-
55-
to_check.push((
56-
blob_versioned_hash,
57-
merkle_root,
58-
log.block_number.unwrap().0[0],
59-
));
60-
}
61-
62-
let beacon_client = BeaconClient::new(beacon_client_url);
58+
.map_err(|_| ProofVerificationAggModeError::EventDecoding)?;
59+
let merkle_root = log.topics[1].0;
60+
let Some(block_number) = log.block_number else {
61+
continue;
62+
};
6363

64-
// Start checking each log and blob versioned hash
65-
for (blob_versioned_hash, merkle_root, block_number) in to_check {
66-
let block = eth_rpc_provider
67-
.get_block(block_number)
64+
let Some(block) = eth_rpc_provider
65+
.get_block(block_number.as_u64())
6866
.await
69-
.unwrap()
70-
.unwrap();
71-
let beacon_parent_root = block.parent_beacon_block_root.unwrap();
67+
.map_err(|e| ProofVerificationAggModeError::EthereumProviderError(e.to_string()))?
68+
else {
69+
continue;
70+
};
7271

73-
let beacon_block = beacon_client
72+
let Some(beacon_parent_root) = block.parent_beacon_block_root else {
73+
continue;
74+
};
75+
76+
let Some(beacon_block) = beacon_client
7477
.get_block_header_from_parent_hash(beacon_parent_root.0)
7578
.await
7679
.map_err(ProofVerificationAggModeError::BeaconClient)?
77-
.unwrap();
80+
else {
81+
continue;
82+
};
7883

79-
let blob = beacon_client
84+
let Some(blob) = beacon_client
8085
.get_blob_by_versioned_hash(
81-
beacon_block.header.message.slot.parse().expect("a number"),
86+
beacon_block
87+
.header
88+
.message
89+
.slot
90+
.parse()
91+
.expect("Slot to be parsable number"),
8292
blob_versioned_hash,
8393
)
8494
.await
8595
.map_err(ProofVerificationAggModeError::BeaconClient)?
86-
.unwrap();
96+
else {
97+
continue;
98+
};
8799

88100
let blob_data = hex::decode(blob.blob.replace("0x", "")).expect("A valid hex encoded data");
89-
90101
let proof_hashes = decoded_blob(blob_data);
91102

92-
// decoded blob and get all leaves and see if it the has is inside
93-
let proof_hash_bytes: [u8; 32] = hex::decode(proof_hash.replace("0x", ""))
94-
.unwrap()
95-
.try_into()
96-
.unwrap();
97-
98-
if proof_hashes.contains(&proof_hash_bytes) {
99-
return Ok(verify_blob_merkle_root(proof_hashes, merkle_root));
103+
if proof_hashes.contains(&proof_hash) {
104+
if verify_blob_merkle_root(proof_hashes, merkle_root) {
105+
return Ok(merkle_root);
106+
} else {
107+
return Err(ProofVerificationAggModeError::UnmatchedBlobAndEventMerkleRoot);
108+
}
100109
} else {
101110
continue;
102111
}
103112
}
104113

105-
Ok(false)
114+
return Err(ProofVerificationAggModeError::ProofNotFoundInLogs);
106115
}
107116

108117
fn decoded_blob(blob_data: Vec<u8>) -> Vec<[u8; 32]> {

batcher/aligned-sdk/src/beacon.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl GetBlobResponse {
4141
}
4242

4343
#[derive(Deserialize, Debug)]
44+
#[allow(dead_code)]
4445
pub struct BlobData {
4546
pub index: String,
4647
pub blob: String,
@@ -63,6 +64,7 @@ impl GetBlockHeadersResponse {
6364
}
6465

6566
#[derive(Deserialize, Debug)]
67+
#[allow(dead_code)]
6668
pub struct BeaconBlock {
6769
pub root: String,
6870
pub canonical: bool,
@@ -75,6 +77,7 @@ pub struct BeaconBlockHeader {
7577
}
7678

7779
#[derive(Deserialize, Debug)]
80+
#[allow(dead_code)]
7881
pub struct BeaconBlockMessage {
7982
pub slot: String,
8083
pub proposer_index: String,

batcher/aligned/src/main.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,13 @@ async fn main() -> Result<(), AlignedError> {
759759
return Ok(());
760760
}
761761
AlignedCommands::VerifyProofInAggMode(args) => {
762+
let proof_hash_bytes: [u8; 32] = hex::decode(args.proof_hash.replace("0x", ""))
763+
.expect("Proof to be a valid hex encoded hash")
764+
.try_into()
765+
.expect("Proof be raw bytes to be of len 32");
766+
762767
match agg_mode::is_proof_verified_in_aggregation_mode(
763-
args.proof_hash,
768+
proof_hash_bytes,
764769
args.network.into(),
765770
args.eth_rpc_url,
766771
args.beacon_client_url,
@@ -769,11 +774,10 @@ async fn main() -> Result<(), AlignedError> {
769774
.await
770775
{
771776
Ok(res) => {
772-
if res {
773-
info!("Proof verified on proof {}", "");
774-
} else {
775-
error!("Proof verification failed!")
776-
}
777+
info!(
778+
"Your proof has been verified in the aggregated proof with merkle root 0x{}",
779+
hex::encode(res)
780+
);
777781
}
778782
Err(e) => error!("Error while trying to verify proof {:?}", e),
779783
}

0 commit comments

Comments
 (0)