Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions aggregation_mode/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions aggregation_mode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
serde_yaml = "0.9"
alloy = { version = "1.1.1", features = ["default", "signer-keystore", "kzg"] }
lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "5f8f2cfcc8a1a22f77e8dff2d581f1166eefb80b", features = ["serde"]}
bincode = "1.3.3"
aligned-sdk = { path = "../crates/sdk/" }
db = { path = "./db" }
Expand Down
28 changes: 28 additions & 0 deletions aggregation_mode/cli/src/commands/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use clap::{self, ValueEnum};
use std::str::FromStr;

use agg_mode_sdk::types::Network;

pub fn parse_network(value: &str) -> Result<Network, String> {
Network::from_str(value).map_err(|_| format!("unsupported network supplied: {value}"))
}

#[derive(Debug, Clone, ValueEnum)]
pub enum ProvingSystemArg {
#[clap(name = "GnarkPlonkBls12_381")]
GnarkPlonkBls12_381,
#[clap(name = "GnarkPlonkBn254")]
GnarkPlonkBn254,
#[clap(name = "GnarkGroth16Bn254")]
GnarkGroth16Bn254,
#[clap(name = "SP1")]
SP1,
#[clap(name = "Risc0")]
Risc0,
#[clap(name = "CircomGroth16Bn256")]
CircomGroth16Bn256,
#[clap(name = "Mina")]
Mina,
#[clap(name = "MinaAccount")]
MinaAccount,
}
19 changes: 19 additions & 0 deletions aggregation_mode/cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
use crate::commands::{submit::SubmitCommand, verify::VerifyOnChainArgs};
use clap::{Parser, Subcommand};

mod helpers;
pub mod submit;
pub mod verify;

#[derive(Debug, Parser)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}

#[derive(Debug, Subcommand)]
pub enum Command {
#[command(subcommand)]
Submit(SubmitCommand),
#[command(name = "verify-on-chain")]
VerifyOnChain(VerifyOnChainArgs),
}
6 changes: 2 additions & 4 deletions aggregation_mode/cli/src/commands/submit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use clap::{command, Args, Subcommand};
use sp1_sdk::{SP1ProofWithPublicValues, SP1VerifyingKey};
use std::{path::PathBuf, str::FromStr};

use crate::commands::helpers::parse_network;

#[derive(Debug, Subcommand)]
pub enum SubmitCommand {
#[command(name = "sp1")]
Expand All @@ -22,10 +24,6 @@ pub struct SubmitSP1Args {
network: Network,
}

fn parse_network(value: &str) -> Result<Network, String> {
Network::from_str(value).map_err(|_| format!("unsupported network supplied: {value}"))
}

pub async fn run(args: SubmitSP1Args) {
tracing::info!("Submitting SP1 proof to {:?} ", args.network);

Expand Down
27 changes: 27 additions & 0 deletions aggregation_mode/cli/src/commands/verify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use agg_mode_sdk::types::Network;
use clap::{self, Args};
use std::path::PathBuf;

use crate::commands::helpers::{parse_network, ProvingSystemArg};

#[derive(Debug, Clone, Args)]
pub struct VerifyOnChainArgs {
#[arg(short = 'n', long = "network", default_value = "devnet", value_parser = parse_network)]
network: Network,
#[arg(long = "rpc-url")]
rpc_url: String,
#[arg(long = "beacon-url")]
beacon_url: String,
#[arg(long = "from-block")]
from_block: Option<u64>,
#[arg(long = "proving-system")]
proving_system: ProvingSystemArg,
#[arg(name = "Program verification key hash", long = "vk", required = true)]
program_vk: PathBuf,
#[arg(long = "vk")]
verifying_key_path: PathBuf,
#[arg(name = "Public input file name", long = "public-input")]
pub_input_file_name: Option<PathBuf>,
}

pub async fn run(args: VerifyOnChainArgs) {}
17 changes: 3 additions & 14 deletions aggregation_mode/cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
use agg_mode_cli::commands::{self, submit::SubmitCommand};
use clap::{Parser, Subcommand};
use agg_mode_cli::commands::{self, submit::SubmitCommand, Cli, Command};
use clap::Parser;
use tracing_subscriber::{EnvFilter, FmtSubscriber};

#[derive(Debug, Parser)]
struct Cli {
#[command(subcommand)]
command: Command,
}

#[derive(Debug, Subcommand)]
enum Command {
#[command(subcommand)]
Submit(SubmitCommand),
}

#[tokio::main]
async fn main() {
let filter = EnvFilter::new("info");
Expand All @@ -26,5 +14,6 @@ async fn main() {
Command::Submit(subcommand) => match subcommand {
SubmitCommand::SP1(args) => commands::submit::run(args).await,
},
Command::VerifyOnChain(args) => commands::verify::run(args).await,
};
}
2 changes: 1 addition & 1 deletion aggregation_mode/proof_aggregator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ tokio = { version = "1", features = ["time"]}
sha3 = "0.10.8"
reqwest = { version = "0.12" }
ciborium = "=0.2.2"
lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "5f8f2cfcc8a1a22f77e8dff2d581f1166eefb80b", features = ["serde"]}
lambdaworks-crypto = { workspace = true }
rayon = "1.10.0"
backon = "1.2.0"
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres", "uuid", "bigdecimal" ] }
Expand Down
7 changes: 5 additions & 2 deletions aggregation_mode/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ edition = "2021"

[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
alloy = { workspace = true }
sp1-sdk = { workspace = true }
lambdaworks-crypto = { workspace = true }
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3.0", features = ["env-filter"] }
bincode = "1.3.3"
reqwest = { version = "0.12", features = ["json", "multipart"] }
tokio = { version = "1", features = ["time"]}
alloy = { workspace = true }
sp1-sdk = { workspace = true }
sha3 = { version = "0.10.8" }

Large diffs are not rendered by default.

154 changes: 154 additions & 0 deletions aggregation_mode/sdk/src/beacon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use std::str::FromStr;

use alloy::{hex, signers::k256::sha2::Sha256};
use reqwest::{Client, Url};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sha3::Digest;

// See https://eips.ethereum.org/EIPS/eip-4844#parameters
pub const KZG_VERSIONED_HASH: u8 = 0x1;

pub struct BeaconClient {
beacon_client_url: String,
api_client: Client,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum BeaconAPIResponse {
Success { data: Value },
Error { code: u64, message: String },
}

#[derive(Debug, Clone)]
pub enum BeaconClientError {
Url(String),
ReqwestError(String),
APIError { code: u64, message: String },
Deserialization(String),
}

#[derive(Deserialize, Debug)]
#[allow(dead_code)]
// https://ethereum.github.io/beacon-APIs/#/Beacon/getBlobSidecars
pub struct BlobData {
pub index: String,
pub blob: String,
pub kzg_commitment: String,
pub kzg_proof: String,
pub kzg_commitment_inclusion_proof: Vec<String>,
}

#[derive(Deserialize, Debug)]
#[allow(dead_code)]
// https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeaders
pub struct BeaconBlock {
pub root: String,
pub canonical: bool,
pub header: BeaconBlockHeader,
}

#[derive(Deserialize, Debug)]

pub struct BeaconBlockHeader {
pub message: BeaconBlockMessage,
}

#[derive(Deserialize, Debug)]
#[allow(dead_code)]
pub struct BeaconBlockMessage {
pub slot: String,
pub proposer_index: String,
pub parent_root: String,
pub state_root: String,
pub body_root: String,
}

impl BeaconClient {
pub fn new(beacon_client_url: String) -> Self {
Self {
api_client: Client::new(),
beacon_client_url,
}
}

pub async fn get_block_header_from_parent_hash(
&self,
parent_block_hash: [u8; 32],
) -> Result<Option<BeaconBlock>, BeaconClientError> {
let parent_block_hash_hex = format!("0x{}", hex::encode(parent_block_hash));
let data = self
.beacon_get(&format!(
"/eth/v1/beacon/headers?parent_root={}",
parent_block_hash_hex
))
.await?;

let res = Vec::<BeaconBlock>::deserialize(data)
.map_err(|e| BeaconClientError::Deserialization(e.to_string()))?;

let block = res
.into_iter()
.find(|block| block.header.message.parent_root == parent_block_hash_hex);

Ok(block)
}

pub async fn get_blobs_from_slot(&self, slot: u64) -> Result<Vec<BlobData>, BeaconClientError> {
let data = self
.beacon_get(&format!("/eth/v1/beacon/blob_sidecars/{}", slot))
.await?;

Vec::<BlobData>::deserialize(data)
.map_err(|e| BeaconClientError::Deserialization(e.to_string()))
}

pub async fn get_blob_by_versioned_hash(
&self,
slot: u64,
blob_versioned_hash: [u8; 32],
) -> Result<Option<BlobData>, BeaconClientError> {
let res = self.get_blobs_from_slot(slot).await?;

let blob = res.into_iter().find(|blob| {
let kzg_commitment_bytes =
hex::decode(blob.kzg_commitment.replace("0x", "")).expect("A valid commitment");

let mut hasher = Sha256::new();
hasher.update(&kzg_commitment_bytes);
let mut versioned_hash: [u8; 32] = hasher.finalize().into();
versioned_hash[0] = KZG_VERSIONED_HASH;

versioned_hash == blob_versioned_hash
});

Ok(blob)
}

async fn beacon_get(&self, path: &str) -> Result<Value, BeaconClientError> {
let url = Url::from_str(&format!("{}{}", self.beacon_client_url, path))
.map_err(|e| BeaconClientError::Url(e.to_string()))?;
let req = self
.api_client
.get(url)
.header("content-type", "application/json")
.header("accept", "application/json");

let res = req
.send()
.await
.map_err(|e| BeaconClientError::ReqwestError(e.to_string()))?;
let beacon_response = res
.json()
.await
.map_err(|e| BeaconClientError::ReqwestError(e.to_string()))?;

match beacon_response {
BeaconAPIResponse::Success { data } => Ok(data),
BeaconAPIResponse::Error { code, message } => {
Err(BeaconClientError::APIError { code, message })
}
}
}
}
34 changes: 34 additions & 0 deletions aggregation_mode/sdk/src/blockchain/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
pub fn decoded_blob(blob_data: &[u8]) -> Vec<[u8; 32]> {
let mut proof_hashes = vec![];

let mut current_hash = [0u8; 32];
let mut current_hash_count = 0;
let mut total_bytes_count = 0;

while total_bytes_count < blob_data.len() {
// Every 32 bytes there is a 0x0 acting as padding, so we need to skip the byte
let is_pad = total_bytes_count % 32 == 0;
if is_pad {
total_bytes_count += 1;
continue;
}

current_hash[current_hash_count] = blob_data[total_bytes_count];

if current_hash_count + 1 == 32 {
// if the current_hash is the zero hash, then there are no more proofs in the blob
if current_hash == [0u8; 32] {
break;
}
proof_hashes.push(current_hash);
current_hash = [0u8; 32];
current_hash_count = 0;
} else {
current_hash_count += 1;
}

total_bytes_count += 1;
}

proof_hashes
}
9 changes: 9 additions & 0 deletions aggregation_mode/sdk/src/blockchain/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Modules
mod helpers;
pub mod provider;
mod types;

// Makes only the two types on this use public
pub use types::{
AggregationModeProvingSystem, AggregationModeVerificationData, ProofVerificationAggModeError,
};
Loading
Loading