Skip to content

Commit b7c5b6d

Browse files
committed
feat: move sdk from crates dir to aggregation mode dir
1 parent ed0e22c commit b7c5b6d

File tree

12 files changed

+613
-4
lines changed

12 files changed

+613
-4
lines changed

aggregation_mode/Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aggregation_mode/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ serde = { version = "1.0.203", features = ["derive"] }
1111
serde_json = "1.0.117"
1212
serde_yaml = "0.9"
1313
alloy = { version = "1.1.1", features = ["default", "signer-keystore", "kzg"] }
14+
lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "5f8f2cfcc8a1a22f77e8dff2d581f1166eefb80b", features = ["serde"]}
1415
bincode = "1.3.3"
1516
aligned-sdk = { path = "../crates/sdk/" }
1617
db = { path = "./db" }

aggregation_mode/proof_aggregator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ tokio = { version = "1", features = ["time"]}
1919
sha3 = "0.10.8"
2020
reqwest = { version = "0.12" }
2121
ciborium = "=0.2.2"
22-
lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "5f8f2cfcc8a1a22f77e8dff2d581f1166eefb80b", features = ["serde"]}
22+
lambdaworks-crypto = { workspace = true }
2323
rayon = "1.10.0"
2424
backon = "1.2.0"
2525
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres", "uuid", "bigdecimal" ] }

aggregation_mode/sdk/Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ edition = "2021"
55

66
[dependencies]
77
serde = { workspace = true }
8+
serde_json = { workspace = true }
9+
alloy = { workspace = true }
10+
sp1-sdk = { workspace = true }
11+
lambdaworks-crypto = { workspace = true }
812
tracing = { version = "0.1", features = ["log"] }
913
tracing-subscriber = { version = "0.3.0", features = ["env-filter"] }
1014
bincode = "1.3.3"
1115
reqwest = { version = "0.12", features = ["json", "multipart"] }
1216
tokio = { version = "1", features = ["time"]}
13-
alloy = { workspace = true }
14-
sp1-sdk = { workspace = true }
17+
sha3 = { version = "0.10.8" }

aggregation_mode/sdk/abi/AlignedProofAggregationService.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

aggregation_mode/sdk/src/beacon.rs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
use std::str::FromStr;
2+
3+
use alloy::{hex, signers::k256::sha2::Sha256};
4+
use reqwest::{Client, Url};
5+
use serde::{Deserialize, Serialize};
6+
use serde_json::Value;
7+
use sha3::Digest;
8+
9+
// See https://eips.ethereum.org/EIPS/eip-4844#parameters
10+
pub const KZG_VERSIONED_HASH: u8 = 0x1;
11+
12+
pub struct BeaconClient {
13+
beacon_client_url: String,
14+
api_client: Client,
15+
}
16+
17+
#[derive(Debug, Serialize, Deserialize)]
18+
#[serde(untagged)]
19+
enum BeaconAPIResponse {
20+
Success { data: Value },
21+
Error { code: u64, message: String },
22+
}
23+
24+
#[derive(Debug, Clone)]
25+
pub enum BeaconClientError {
26+
Url(String),
27+
ReqwestError(String),
28+
APIError { code: u64, message: String },
29+
Deserialization(String),
30+
}
31+
32+
#[derive(Deserialize, Debug)]
33+
#[allow(dead_code)]
34+
// https://ethereum.github.io/beacon-APIs/#/Beacon/getBlobSidecars
35+
pub struct BlobData {
36+
pub index: String,
37+
pub blob: String,
38+
pub kzg_commitment: String,
39+
pub kzg_proof: String,
40+
pub kzg_commitment_inclusion_proof: Vec<String>,
41+
}
42+
43+
#[derive(Deserialize, Debug)]
44+
#[allow(dead_code)]
45+
// https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeaders
46+
pub struct BeaconBlock {
47+
pub root: String,
48+
pub canonical: bool,
49+
pub header: BeaconBlockHeader,
50+
}
51+
52+
#[derive(Deserialize, Debug)]
53+
54+
pub struct BeaconBlockHeader {
55+
pub message: BeaconBlockMessage,
56+
}
57+
58+
#[derive(Deserialize, Debug)]
59+
#[allow(dead_code)]
60+
pub struct BeaconBlockMessage {
61+
pub slot: String,
62+
pub proposer_index: String,
63+
pub parent_root: String,
64+
pub state_root: String,
65+
pub body_root: String,
66+
}
67+
68+
impl BeaconClient {
69+
pub fn new(beacon_client_url: String) -> Self {
70+
Self {
71+
api_client: Client::new(),
72+
beacon_client_url,
73+
}
74+
}
75+
76+
pub async fn get_block_header_from_parent_hash(
77+
&self,
78+
parent_block_hash: [u8; 32],
79+
) -> Result<Option<BeaconBlock>, BeaconClientError> {
80+
let parent_block_hash_hex = format!("0x{}", hex::encode(parent_block_hash));
81+
let data = self
82+
.beacon_get(&format!(
83+
"/eth/v1/beacon/headers?parent_root={}",
84+
parent_block_hash_hex
85+
))
86+
.await?;
87+
88+
let res = Vec::<BeaconBlock>::deserialize(data)
89+
.map_err(|e| BeaconClientError::Deserialization(e.to_string()))?;
90+
91+
let block = res
92+
.into_iter()
93+
.find(|block| block.header.message.parent_root == parent_block_hash_hex);
94+
95+
Ok(block)
96+
}
97+
98+
pub async fn get_blobs_from_slot(&self, slot: u64) -> Result<Vec<BlobData>, BeaconClientError> {
99+
let data = self
100+
.beacon_get(&format!("/eth/v1/beacon/blob_sidecars/{}", slot))
101+
.await?;
102+
103+
Vec::<BlobData>::deserialize(data)
104+
.map_err(|e| BeaconClientError::Deserialization(e.to_string()))
105+
}
106+
107+
pub async fn get_blob_by_versioned_hash(
108+
&self,
109+
slot: u64,
110+
blob_versioned_hash: [u8; 32],
111+
) -> Result<Option<BlobData>, BeaconClientError> {
112+
let res = self.get_blobs_from_slot(slot).await?;
113+
114+
let blob = res.into_iter().find(|blob| {
115+
let kzg_commitment_bytes =
116+
hex::decode(blob.kzg_commitment.replace("0x", "")).expect("A valid commitment");
117+
118+
let mut hasher = Sha256::new();
119+
hasher.update(&kzg_commitment_bytes);
120+
let mut versioned_hash: [u8; 32] = hasher.finalize().into();
121+
versioned_hash[0] = KZG_VERSIONED_HASH;
122+
123+
versioned_hash == blob_versioned_hash
124+
});
125+
126+
Ok(blob)
127+
}
128+
129+
async fn beacon_get(&self, path: &str) -> Result<Value, BeaconClientError> {
130+
let url = Url::from_str(&format!("{}{}", self.beacon_client_url, path))
131+
.map_err(|e| BeaconClientError::Url(e.to_string()))?;
132+
let req = self
133+
.api_client
134+
.get(url)
135+
.header("content-type", "application/json")
136+
.header("accept", "application/json");
137+
138+
let res = req
139+
.send()
140+
.await
141+
.map_err(|e| BeaconClientError::ReqwestError(e.to_string()))?;
142+
let beacon_response = res
143+
.json()
144+
.await
145+
.map_err(|e| BeaconClientError::ReqwestError(e.to_string()))?;
146+
147+
match beacon_response {
148+
BeaconAPIResponse::Success { data } => Ok(data),
149+
BeaconAPIResponse::Error { code, message } => {
150+
Err(BeaconClientError::APIError { code, message })
151+
}
152+
}
153+
}
154+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
pub fn decoded_blob(blob_data: &[u8]) -> Vec<[u8; 32]> {
2+
let mut proof_hashes = vec![];
3+
4+
let mut current_hash = [0u8; 32];
5+
let mut current_hash_count = 0;
6+
let mut total_bytes_count = 0;
7+
8+
while total_bytes_count < blob_data.len() {
9+
// Every 32 bytes there is a 0x0 acting as padding, so we need to skip the byte
10+
let is_pad = total_bytes_count % 32 == 0;
11+
if is_pad {
12+
total_bytes_count += 1;
13+
continue;
14+
}
15+
16+
current_hash[current_hash_count] = blob_data[total_bytes_count];
17+
18+
if current_hash_count + 1 == 32 {
19+
// if the current_hash is the zero hash, then there are no more proofs in the blob
20+
if current_hash == [0u8; 32] {
21+
break;
22+
}
23+
proof_hashes.push(current_hash);
24+
current_hash = [0u8; 32];
25+
current_hash_count = 0;
26+
} else {
27+
current_hash_count += 1;
28+
}
29+
30+
total_bytes_count += 1;
31+
}
32+
33+
proof_hashes
34+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Modules
2+
mod helpers;
3+
pub mod provider;
4+
mod types;
5+
6+
// Makes only the two types on this use public
7+
pub use types::{
8+
AggregationModeProvingSystem, AggregationModeVerificationData, ProofVerificationAggModeError,
9+
};

0 commit comments

Comments
 (0)