Skip to content

Commit 27a9c6a

Browse files
uri-99IAvecilla
andauthored
feat: aligned verification data stored locally stores cbor and json (#1264)
Co-authored-by: Nacho Avecilla <[email protected]>
1 parent 364cb49 commit 27a9c6a

File tree

6 files changed

+132
-33
lines changed

6 files changed

+132
-33
lines changed

batcher/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

batcher/aligned-sdk/src/core/errors.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub enum AlignedError {
1616
NonceError(NonceError),
1717
ChainIdError(ChainIdError),
1818
MaxFeeEstimateError(MaxFeeEstimateError),
19+
FileError(FileError),
1920
}
2021

2122
impl From<SubmitError> for AlignedError {
@@ -48,6 +49,12 @@ impl From<MaxFeeEstimateError> for AlignedError {
4849
}
4950
}
5051

52+
impl From<FileError> for AlignedError {
53+
fn from(e: FileError) -> Self {
54+
AlignedError::FileError(e)
55+
}
56+
}
57+
5158
impl fmt::Display for AlignedError {
5259
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5360
match self {
@@ -56,6 +63,7 @@ impl fmt::Display for AlignedError {
5663
AlignedError::NonceError(e) => write!(f, "Nonce error: {}", e),
5764
AlignedError::ChainIdError(e) => write!(f, "Chain ID error: {}", e),
5865
AlignedError::MaxFeeEstimateError(e) => write!(f, "Max fee estimate error: {}", e),
66+
AlignedError::FileError(e) => write!(f, "File error: {}", e),
5967
}
6068
}
6169
}
@@ -321,3 +329,30 @@ pub enum BalanceError {
321329
EthereumProviderError(String),
322330
EthereumCallError(String),
323331
}
332+
333+
#[derive(Debug)]
334+
pub enum FileError {
335+
IoError(PathBuf, io::Error),
336+
SerializationError(SerializationError),
337+
}
338+
339+
impl From<SerializationError> for FileError {
340+
fn from(e: SerializationError) -> Self {
341+
FileError::SerializationError(e)
342+
}
343+
}
344+
345+
impl From<io::Error> for FileError {
346+
fn from(e: io::Error) -> Self {
347+
FileError::IoError(PathBuf::new(), e)
348+
}
349+
}
350+
351+
impl fmt::Display for FileError {
352+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
353+
match self {
354+
FileError::IoError(path, e) => write!(f, "IO error: {}: {}", path.display(), e),
355+
FileError::SerializationError(e) => write!(f, "Serialization error: {}", e),
356+
}
357+
}
358+
}

batcher/aligned-sdk/src/sdk.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
batch::await_batch_verification,
44
messaging::{receive, send_messages, ResponseStream},
55
protocol::check_protocol_version,
6+
serialization::cbor_serialize,
67
},
78
core::{
89
constants::{
@@ -34,13 +35,18 @@ use std::{str::FromStr, sync::Arc};
3435
use tokio::{net::TcpStream, sync::Mutex};
3536
use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream};
3637

37-
use log::debug;
38+
use log::{debug, info};
3839

3940
use futures_util::{
4041
stream::{SplitSink, SplitStream},
4142
StreamExt, TryStreamExt,
4243
};
4344

45+
use std::fs::File;
46+
use std::io::Write;
47+
use std::path::PathBuf;
48+
49+
use serde_json::json;
4450
/// Submits multiple proofs to the batcher to be verified in Aligned and waits for the verification on-chain.
4551
/// # Arguments
4652
/// * `batcher_url` - The url of the batcher to which the proof will be submitted.
@@ -655,6 +661,91 @@ pub async fn get_balance_in_aligned(
655661
}
656662
}
657663

664+
/// Saves AlignedVerificationData in a file.
665+
/// # Arguments
666+
/// * `batch_inclusion_data_directory_path` - The path of the directory where the data will be saved.
667+
/// * `aligned_verification_data` - The aligned verification data to be saved.
668+
/// # Returns
669+
/// * Ok if the data is saved successfully.
670+
/// # Errors
671+
/// * `FileError` if there is an error writing the data to the file.
672+
pub fn save_response(
673+
batch_inclusion_data_directory_path: PathBuf,
674+
aligned_verification_data: &AlignedVerificationData,
675+
) -> Result<(), errors::FileError> {
676+
save_response_cbor(
677+
batch_inclusion_data_directory_path.clone(),
678+
&aligned_verification_data.clone(),
679+
)?;
680+
save_response_json(
681+
batch_inclusion_data_directory_path,
682+
aligned_verification_data,
683+
)
684+
}
685+
fn save_response_cbor(
686+
batch_inclusion_data_directory_path: PathBuf,
687+
aligned_verification_data: &AlignedVerificationData,
688+
) -> Result<(), errors::FileError> {
689+
let batch_merkle_root = &hex::encode(aligned_verification_data.batch_merkle_root)[..8];
690+
let batch_inclusion_data_file_name = batch_merkle_root.to_owned()
691+
+ "_"
692+
+ &aligned_verification_data.index_in_batch.to_string()
693+
+ ".cbor";
694+
695+
let batch_inclusion_data_path =
696+
batch_inclusion_data_directory_path.join(batch_inclusion_data_file_name);
697+
698+
let data = cbor_serialize(&aligned_verification_data)?;
699+
700+
let mut file = File::create(&batch_inclusion_data_path)?;
701+
file.write_all(data.as_slice())?;
702+
info!(
703+
"Batch inclusion data written into {}",
704+
batch_inclusion_data_path.display()
705+
);
706+
707+
Ok(())
708+
}
709+
fn save_response_json(
710+
batch_inclusion_data_directory_path: PathBuf,
711+
aligned_verification_data: &AlignedVerificationData,
712+
) -> Result<(), errors::FileError> {
713+
let batch_merkle_root = &hex::encode(aligned_verification_data.batch_merkle_root)[..8];
714+
let batch_inclusion_data_file_name = batch_merkle_root.to_owned()
715+
+ "_"
716+
+ &aligned_verification_data.index_in_batch.to_string()
717+
+ ".json";
718+
719+
let batch_inclusion_data_path =
720+
batch_inclusion_data_directory_path.join(batch_inclusion_data_file_name);
721+
722+
let merkle_proof = aligned_verification_data
723+
.batch_inclusion_proof
724+
.merkle_path
725+
.iter()
726+
.map(hex::encode)
727+
.collect::<Vec<String>>()
728+
.join("");
729+
let data = json!({
730+
"proof_commitment": hex::encode(aligned_verification_data.verification_data_commitment.proof_commitment),
731+
"pub_input_commitment": hex::encode(aligned_verification_data.verification_data_commitment.pub_input_commitment),
732+
"program_id_commitment": hex::encode(aligned_verification_data.verification_data_commitment.proving_system_aux_data_commitment),
733+
"proof_generator_addr": hex::encode(aligned_verification_data.verification_data_commitment.proof_generator_addr),
734+
"batch_merkle_root": hex::encode(aligned_verification_data.batch_merkle_root),
735+
"verification_data_batch_index": aligned_verification_data.index_in_batch,
736+
"merkle_proof": merkle_proof,
737+
});
738+
let mut file = File::create(&batch_inclusion_data_path)?;
739+
file.write_all(serde_json::to_string_pretty(&data).unwrap().as_bytes())?;
740+
741+
info!(
742+
"Batch inclusion data written into {}",
743+
batch_inclusion_data_path.display()
744+
);
745+
746+
Ok(())
747+
}
748+
658749
#[cfg(test)]
659750
mod test {
660751
//Public constants for convenience

batcher/aligned/src/main.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ use std::path::PathBuf;
77
use std::str::FromStr;
88

99
use aligned_sdk::communication::serialization::cbor_deserialize;
10-
use aligned_sdk::communication::serialization::cbor_serialize;
1110
use aligned_sdk::core::{
1211
errors::{AlignedError, SubmitError},
1312
types::{AlignedVerificationData, Network, ProvingSystemId, VerificationData},
1413
};
1514
use aligned_sdk::sdk::get_chain_id;
1615
use aligned_sdk::sdk::get_next_nonce;
1716
use aligned_sdk::sdk::{deposit_to_aligned, get_balance_in_aligned};
18-
use aligned_sdk::sdk::{get_vk_commitment, is_proof_verified, submit_multiple};
17+
use aligned_sdk::sdk::{get_vk_commitment, is_proof_verified, save_response, submit_multiple};
1918
use clap::Parser;
2019
use clap::Subcommand;
2120
use clap::ValueEnum;
@@ -610,33 +609,6 @@ async fn get_nonce(
610609
Ok(nonce)
611610
}
612611

613-
fn save_response(
614-
batch_inclusion_data_directory_path: PathBuf,
615-
aligned_verification_data: &AlignedVerificationData,
616-
) -> Result<(), SubmitError> {
617-
let batch_merkle_root = &hex::encode(aligned_verification_data.batch_merkle_root)[..8];
618-
let batch_inclusion_data_file_name = batch_merkle_root.to_owned()
619-
+ "_"
620-
+ &aligned_verification_data.index_in_batch.to_string()
621-
+ ".json";
622-
623-
let batch_inclusion_data_path =
624-
batch_inclusion_data_directory_path.join(batch_inclusion_data_file_name);
625-
626-
let data = cbor_serialize(&aligned_verification_data)?;
627-
628-
let mut file = File::create(&batch_inclusion_data_path)
629-
.map_err(|e| SubmitError::IoError(batch_inclusion_data_path.clone(), e))?;
630-
file.write_all(data.as_slice())
631-
.map_err(|e| SubmitError::IoError(batch_inclusion_data_path.clone(), e))?;
632-
info!(
633-
"Batch inclusion data written into {}",
634-
batch_inclusion_data_path.display()
635-
);
636-
637-
Ok(())
638-
}
639-
640612
pub async fn get_user_balance(
641613
provider: Provider<Http>,
642614
contract_address: Address,

explorer/lib/explorer_web/live/utils.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ defmodule Utils do
186186
def calculate_proof_hashes(deserialized_batch) do
187187
deserialized_batch
188188
|> Enum.map(fn s3_object ->
189-
:crypto.hash(:sha3_256, s3_object["proof"])
189+
ExKeccak.hash_256(:erlang.list_to_binary(s3_object["proof"]))
190190
end)
191191
end
192192

telemetry_api/mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ defmodule TelemetryApi.MixProject do
5757
{:ethers, "~> 0.4.4"},
5858
{:opentelemetry, "~> 1.3"},
5959
{:opentelemetry_api, "~> 1.2"},
60-
{:opentelemetry_exporter, "~> 1.6"}
60+
{:opentelemetry_exporter, "~> 1.6"},
61+
{:ex_keccak, "~> 0.7.5"}
6162
]
6263
end
6364

0 commit comments

Comments
 (0)