Skip to content

Commit

Permalink
feat: Tree trait (summa-dev#179)
Browse files Browse the repository at this point in the history
* chore: add audit comments (summa-dev#168)

* Refactor backend by following internal audit comments (summa-dev#173)

* feat: create bash script for updating verifier interface files in backend

* fix: error propagation with try operator; remove unnecessaries

* refactor: changed data type in 'MstInclusionProof'

* fix: generate solvency verifier contract

* chore: remove left over

* chore: update README

* fix: remove left over; assert term

* fix: update README; small fixes

* feat: Signer accepts address or file path for init

* feat: added mutex lock to signer; used it as ref

* fix: mutex deadlock in signer

* chore: minor updates

* feat: `Tree` trait

* fix: move `verify_proof` logic to `Tree` trait

* feat: added method implementation to `Tree` trait and moved outside of utils

* refactor: signer spawn provider internally; updated comments

* fix: round now use Tree trait

* refactor: Round needs MST and Assets instead of csv files path

* fix: rollback applying csv_parser for AddressOwnership and Assets in Snapshot

* fix: Solvency::init fn accept type that has Tree trait

* fix: updates for summa solvency contract v1.1

* chore: rename `compute_leaves` api

* fix: Rounds accept 'Tree' trait object

* chore: removed and updated comments

* chore: removed env variables 'SIGNATURE_VERIFICATION_MESSAGE'

---------

Co-authored-by: JinHwan <[email protected]>
Co-authored-by: sifnoc <[email protected]>
  • Loading branch information
3 people authored Nov 10, 2023
1 parent 19dcb54 commit 978a645
Show file tree
Hide file tree
Showing 38 changed files with 8,866 additions and 47,904 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ jobs:
uses: foundry-rs/foundry-toolchain@v1

- name: Test backend
env:
SIGNATURE_VERIFICATION_MESSAGE: "Summa proof of solvency for CryptoExchange"
run: |
cd backend
cargo test --release -- --nocapture
Expand Down
2 changes: 1 addition & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ To build the binary executable and test it

```
cargo build
SIGNATURE_VERIFICATION_MESSAGE="Summa proof of solvency for CryptoExchange" cargo test --release -- --nocapture
cargo test --release -- --nocapture
```

## Important Notices
Expand Down
5 changes: 0 additions & 5 deletions backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ fn main() {
"Summa",
"Summa",
),
(
"src/contracts/generated/solvency_verifier.rs",
"SolvencyVerifier",
"SolvencyVerifier",
),
(
"src/contracts/generated/inclusion_verifier.rs",
"InclusionVerifier",
Expand Down
65 changes: 35 additions & 30 deletions backend/examples/summa_solvency_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,41 @@ use summa_backend::{
address_ownership::AddressOwnership,
round::{MstInclusionProof, Round},
},
contracts::signer::AddressInput,
contracts::signer::{AddressInput, SummaSigner},
tests::initialize_test_env,
};
use summa_solvency::merkle_sum_tree::utils::generate_leaf_hash;
use summa_solvency::merkle_sum_tree::{utils::generate_leaf_hash, MerkleSumTree};

const N_ASSETS: usize = 2;
const USER_INDEX: usize = 0;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Initialize test environment without `address_ownership` instance from `initialize_test_env` function.
let (anvil, _, _, _, summa_contract) = initialize_test_env().await;
let (anvil, _, _, _, summa_contract) = initialize_test_env(None).await;

// 1. Submit ownership proof
//
// Each CEX prepares its own `signature` CSV file.
let signature_csv_path = "src/apis/csv/signatures.csv";

// Using AddressInput::Address to directly provide the summa_contract's address.
// For deployed contracts, if the address is stored in a config file,
// you can alternatively use AddressInput::Path to specify the file's path.
let mut address_ownership_client = AddressOwnership::new(
// The signer instance would be shared with `address_ownership` and `round` instances
//
// Using `AddressInput::Address`` to directly provide the summa_contract's address.
//
// If the address of a deployed contract is stored in a configuration file,
// you can use `AddressInput::Path` to provide the path to that file.
//
// For example, if the contract address is in "backend/src/contracts/deployments.json" located
// you would use `AddressInput::Path` as follows:`AddressInput::Path("backend/src/contracts/deployments.json".to_string())`.
//
let signer = SummaSigner::new(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
anvil.chain_id(),
anvil.endpoint().as_str(),
AddressInput::Address(summa_contract.address()),
signature_csv_path,
)
.unwrap();
.await?;

// Each CEX prepares its own `signature` CSV file.
let signature_csv_path = "src/apis/csv/signatures.csv";
let mut address_ownership_client = AddressOwnership::new(&signer, signature_csv_path).unwrap();

// Dispatch the proof of address ownership.
// the `dispatch_proof_of_address_ownership` function sends a transaction to the Summa contract.
Expand All @@ -47,30 +53,29 @@ async fn main() -> Result<(), Box<dyn Error>> {

println!("1. Ownership proofs are submitted successfully!");

// 2. Submit solvency proof
// 2. Submit Commitment
//
// Initialize the `Round` instance to submit the proof of solvency.
let asset_csv = "src/apis/csv/assets.csv";
let entry_csv = "../zk_prover/src/merkle_sum_tree/csv/entry_16.csv";
// Initialize the `Round` instance to submit the liability commitment.
let params_path = "ptau/hermez-raw-11";
let assets_csv_path = "src/apis/csv/assets.csv";
let entry_csv = "../zk_prover/src/merkle_sum_tree/csv/entry_16.csv";
let mst = MerkleSumTree::new(entry_csv).unwrap();

// Using the `round` instance, the solvency proof is dispatched to the Summa contract with the `dispatch_solvency_proof` method.
// Using the `round` instance, the commitment is dispatched to the Summa contract with the `dispatch_commitment` method.
let timestamp = 1u64;
let mut round = Round::<4, 2, 14>::new(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", // anvil account [0]
anvil.chain_id(),
anvil.endpoint().as_str(),
AddressInput::Address(summa_contract.address()),
entry_csv,
asset_csv,
&signer,
Box::new(mst),
assets_csv_path,
params_path,
1,
timestamp,
)
.unwrap();

// Sends the solvency proof, which should ideally complete without errors.
round.dispatch_solvency_proof().await?;
// Sends the commitment, which should ideally complete without errors.
round.dispatch_commitment().await?;

println!("2. Solvency proof is submitted successfully!");
println!("2. Commitment is submitted successfully!");

// 3. Generate Inclusion Proof
//
Expand Down Expand Up @@ -115,10 +120,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
);

// Get `mst_root` from contract. the `mst_root` is disptached by CEX with specific time `snapshot_time`.
let mst_root = summa_contract.mst_roots(snapshot_time).call().await?;
let commitment = summa_contract.commitments(snapshot_time).call().await?;

// Match the `mst_root` with the `root_hash` derived from the proof.
assert_eq!(mst_root, public_inputs[1]);
assert_eq!(commitment, public_inputs[1]);

// Validate the inclusion proof using the contract verifier.
let proof = inclusion_proof.get_proof();
Expand Down
1 change: 0 additions & 1 deletion backend/scripts/update_verifier_contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ set -e
echo "1. Building verifier contracts"
cd ../zk_prover
cargo run --release --example gen_inclusion_verifier
cargo run --release --example gen_solvency_verifier

# Deploy contracts to local environment
echo "2. Deploying contracts to local environment"
Expand Down
22 changes: 8 additions & 14 deletions backend/src/apis/address_ownership.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
use crate::contracts::{
generated::summa_contract::AddressOwnershipProof,
signer::{AddressInput, SummaSigner},
};
use crate::contracts::{generated::summa_contract::AddressOwnershipProof, signer::SummaSigner};
use std::{error::Error, result::Result};

use super::csv_parser::parse_signature_csv;

pub struct AddressOwnership {
pub struct AddressOwnership<'a> {
address_ownership_proofs: Vec<AddressOwnershipProof>,
signer: SummaSigner,
signer: &'a SummaSigner,
}

impl AddressOwnership {
pub fn new(
signer_key: &str,
chain_id: u64,
rpc_url: &str,
summa_address_input: AddressInput,
impl AddressOwnership<'_> {
pub fn new<'a>(
signer: &'a SummaSigner,
signature_csv_path: &str,
) -> Result<AddressOwnership, Box<dyn Error>> {
) -> Result<AddressOwnership<'a>, Box<dyn Error>> {
let address_ownership_proofs = parse_signature_csv(signature_csv_path)?;

Ok(AddressOwnership {
address_ownership_proofs,
signer: SummaSigner::new(signer_key, chain_id, rpc_url, summa_address_input),
signer,
})
}

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

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

use crate::contracts::generated::summa_contract::{AddressOwnershipProof, Asset};
Expand Down Expand Up @@ -53,7 +50,6 @@ pub fn parse_signature_csv<P: AsRef<Path>>(
struct AssetRecord {
chain: String,
asset_name: String,
amount: String,
}

pub fn parse_asset_csv<P: AsRef<Path>, const N_ASSETS: usize>(
Expand All @@ -70,7 +66,6 @@ pub fn parse_asset_csv<P: AsRef<Path>, const N_ASSETS: usize>(
assets_vec.push(Asset {
asset_name: record.asset_name,
chain: record.chain,
amount: U256::from_dec_str(&record.amount)?,
});
}

Expand Down Expand Up @@ -114,15 +109,13 @@ mod tests {
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),
}
);
}
Expand Down
Loading

0 comments on commit 978a645

Please sign in to comment.