Skip to content

Commit

Permalink
fix: related round and snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
sifnoc committed Sep 11, 2023
1 parent ce908f0 commit 3d1ab95
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 105 deletions.
4 changes: 3 additions & 1 deletion backend/examples/verify_inclusion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ fn main() {
const N_BYTES: usize = 8;

let ptau_path = "./ptau/hermez-raw-11";
let asset_csv_path = "src/apis/csv/assets.csv";
let entry_csv_path = "../zk_prover/src/merkle_sum_tree/csv/entry_16.csv";

// CEX Generate the Merkle Sum Tree and then initialize the circuit.
// Note that `signature_csv` is empty because this is only needed to generate π of Solvency, which is not the case here.
let snapshot =
Snapshot::<LEVELS, N_ASSETS, N_BYTES>::new(&entry_csv_path, &ptau_path, 1).unwrap();
Snapshot::<LEVELS, N_ASSETS, N_BYTES>::new(&asset_csv_path, &entry_csv_path, &ptau_path)
.unwrap();

let inclusion_proof = snapshot.generate_proof_of_inclusion(0 as usize).unwrap();

Expand Down
3 changes: 3 additions & 0 deletions backend/src/apis/csv/assets.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
chain;asset_name;amount
ETH;ETH;556863
ETH;USDT;556863
71 changes: 66 additions & 5 deletions backend/src/apis/csv_parser.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::{error::Error, fs::File, path::Path};

use ethers::{abi::AbiEncode, types::Bytes};
use ethers::{
abi::AbiEncode,
types::{Bytes, U256},
};
use serde::Deserialize;

use crate::contracts::generated::summa_contract::AddressOwnershipProof;
use crate::contracts::generated::summa_contract::{AddressOwnershipProof, Asset};

#[derive(Debug, Deserialize)]
struct Record {
struct EntriesRecord {
chain: String,
address: String,
signature: String,
Expand All @@ -22,7 +25,7 @@ pub fn parse_signature_csv<P: AsRef<Path>>(
let mut address_ownership_proofs = Vec::<AddressOwnershipProof>::new();

for result in rdr.deserialize() {
let record: Record = result?;
let record: EntriesRecord = result?;

address_ownership_proofs.push(AddressOwnershipProof {
cex_address: record.address.to_string(),
Expand All @@ -35,12 +38,47 @@ pub fn parse_signature_csv<P: AsRef<Path>>(
Ok(address_ownership_proofs)
}

#[derive(Debug, Deserialize)]
struct AssetRecord {
chain: String,
asset_name: String,
amount: String,
}

pub fn parse_asset_csv<P: AsRef<Path>, const N_ASSETS: usize>(
path: P,
) -> Result<[Asset; N_ASSETS], Box<dyn Error>> {
let file = File::open(path)?;
let mut rdr = csv::ReaderBuilder::new().delimiter(b';').from_reader(file);

let mut assets_vec = Vec::with_capacity(N_ASSETS);

for result in rdr.deserialize() {
let record: AssetRecord = result?;

assets_vec.push(Asset {
asset_name: record.asset_name,
chain: record.chain,
amount: U256::from_dec_str(&record.amount)?,
});
}

let assets_array: [Asset; N_ASSETS] = assets_vec.try_into().map_err(|v: Vec<Asset>| {
format!(
"Number of assets in CSV does not match the number of assets in the contract! {:?}",
v
)
})?;

Ok(assets_array)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_parse_csv_to_assets() {
fn test_parse_csv_to_signature() {
let path = "src/apis/csv/signatures.csv";
let address_ownership = parse_signature_csv(path).unwrap();

Expand All @@ -54,4 +92,27 @@ mod tests {

assert_eq!(address_ownership[0], first_address_ownership);
}

#[test]
fn test_parse_csv_to_assets() {
let path = "src/apis/csv/assets.csv";
let assets = parse_asset_csv::<&str, 2>(path).unwrap();

assert_eq!(
assets[0],
Asset {
chain: "ETH".to_string(),
asset_name: "ETH".to_string(),
amount: U256::from(556863),
}
);
assert_eq!(
assets[1],
Asset {
chain: "ETH".to_string(),
asset_name: "USDT".to_string(),
amount: U256::from(556863),
}
);
}
}
81 changes: 36 additions & 45 deletions backend/src/apis/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use halo2_proofs::{
plonk::{ProvingKey, VerifyingKey},
poly::kzg::commitment::ParamsKZG,
};
use serde_json::to_string_pretty;
use snark_verifier_sdk::CircuitExt;
use std::error::Error;

use super::csv_parser::parse_asset_csv;
use crate::contracts::{generated::summa_contract::summa::Asset, signer::SummaSigner};
use summa_solvency::{
circuits::{
Expand Down Expand Up @@ -61,12 +61,13 @@ impl MstInclusionProof {

pub struct Snapshot<const LEVELS: usize, const N_ASSETS: usize, const N_BYTES: usize> {
mst: MerkleSumTree<N_ASSETS, N_BYTES>,
timestamp: usize,
assets_state: [Asset; N_ASSETS],
trusted_setup: [SetupArtifacts; 2],
}

pub struct Round<const LEVELS: usize, const N_ASSETS: usize, const N_BYTES: usize> {
snapshot: Option<Snapshot<LEVELS, N_ASSETS, N_BYTES>>,
timestamp: u64,
snapshot: Snapshot<LEVELS, N_ASSETS, N_BYTES>,
signer: SummaSigner,
}

Expand All @@ -81,38 +82,29 @@ where
chain_id: u64,
rpc_url: &str,
summa_sc_address: Address,
entry_csv_path: &str,
asset_csv_path: &str,
params_path: &str,
timestamp: u64,
) -> Result<Round<LEVELS, N_ASSETS, N_BYTES>, Box<dyn Error>> {
Ok(Round {
snapshot: None,
timestamp,
snapshot: Snapshot::<LEVELS, N_ASSETS, N_BYTES>::new(
asset_csv_path,
entry_csv_path,
params_path,
)
.unwrap(),
signer: SummaSigner::new(&vec![], signer_key, chain_id, rpc_url, summa_sc_address),
})
}

pub fn build_snapshot(&mut self, entry_csv_path: &str, params_path: &str, timestamp: usize) {
let snapshot =
Snapshot::<LEVELS, N_ASSETS, N_BYTES>::new(entry_csv_path, params_path, timestamp)
.unwrap();
self.snapshot = Some(snapshot);
pub fn get_timestamp(&self) -> u64 {
self.timestamp
}

pub async fn dispatch_solvency_proof(
&mut self,
assets: [Asset; N_ASSETS],
) -> Result<(), &'static str> {
if self.snapshot.is_none() {
return Err("snapshot is not built yet");
}
let snapshot = self.snapshot.as_ref().unwrap();

// Convert U256 to Fp for generating proof of solvency
let asset_sum: [Fp; N_ASSETS] = assets
.iter()
.map(|asset| Fp::from_raw(asset.amount.0) as Fp)
.collect::<Vec<Fp>>()
.try_into()
.unwrap();

let proof: SolvencyProof = match snapshot.generate_proof_of_solvency(asset_sum) {
pub async fn dispatch_solvency_proof(&mut self) -> Result<(), &'static str> {
let proof: SolvencyProof = match self.snapshot.generate_proof_of_solvency() {
Ok(p) => p,
Err(_) => return Err("Failed to generate proof of solvency"),
};
Expand All @@ -121,9 +113,9 @@ where
.signer
.submit_proof_of_solvency(
proof.public_inputs[0],
assets.to_vec(),
self.snapshot.assets_state.to_vec(),
proof.proof_calldata,
U256::from(snapshot.get_timestamp()),
U256::from(self.get_timestamp()),
)
.await;

Expand All @@ -134,12 +126,10 @@ where
&self,
user_index: usize,
) -> Result<MstInclusionProof, &'static str> {
let snapshot = self.snapshot.as_ref().unwrap();
if snapshot.mst.entries().len() < user_index {
return Err("user_index is out of range");
}

Ok(snapshot.generate_proof_of_inclusion(user_index).unwrap())
Ok(self
.snapshot
.generate_proof_of_inclusion(user_index)
.unwrap())
}
}

Expand All @@ -150,10 +140,11 @@ where
[usize; 2 * (1 + N_ASSETS)]: Sized,
{
pub fn new(
asset_csv_path: &str,
entry_csv_path: &str,
params_path: &str,
timestamp: usize,
) -> Result<Snapshot<LEVELS, N_ASSETS, N_BYTES>, Box<dyn std::error::Error>> {
let assets_state = parse_asset_csv::<&str, N_ASSETS>(asset_csv_path).unwrap();
let mst = MerkleSumTree::<N_ASSETS, N_BYTES>::new(entry_csv_path).unwrap();

let mst_inclusion_circuit = MstInclusionCircuit::<LEVELS, N_ASSETS, N_BYTES>::init_empty();
Expand All @@ -177,19 +168,19 @@ where

Ok(Snapshot {
mst,
timestamp,
assets_state,
trusted_setup,
})
}

pub fn get_timestamp(&self) -> usize {
self.timestamp
}

pub fn generate_proof_of_solvency(
&self,
asset_sums: [Fp; N_ASSETS],
) -> Result<SolvencyProof, &'static str> {
pub fn generate_proof_of_solvency(&self) -> Result<SolvencyProof, &'static str> {
let asset_sums = self
.assets_state
.iter()
.map(|asset| Fp::from_raw(asset.amount.0) as Fp)
.collect::<Vec<Fp>>()
.try_into()
.unwrap();
let circuit = SolvencyCircuit::<N_ASSETS, N_BYTES>::init(self.mst.clone(), asset_sums);

let calldata = gen_proof_solidity_calldata(
Expand Down
4 changes: 2 additions & 2 deletions backend/src/contracts/generated/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod summa_contract;
pub mod inclusion_verifier;
pub mod solvency_verifier;
pub mod inclusion_verifier;
pub mod summa_contract;
Loading

0 comments on commit 3d1ab95

Please sign in to comment.