Skip to content

Commit

Permalink
Mst efficiency improvement (summa-dev#188)
Browse files Browse the repository at this point in the history
* feat: tree building rules

* feat: add `get_middle_node_hash_preimage` and `get_middle_node_hash_preimage` methods

* feat: update `generate_proof`

* fix: `generate_proof`

* fix: modify middle nodes hashing logic in circuit

* feat: update `MerkleProof`

* feat: add further constraint on `MstInclusionCircuit`

* feat: rm `test_balance_not_in_range`

* refactor: update `MerkleProof`

* chore: fix `backend`

* test: fix `backend`

* fix: testing

* fix: modify `MstInclusionCircuit` struct

* Revert "fix: modify `MstInclusionCircuit` struct"

This reverts commit e3ba8e6.

* chore: update `benches`

* fix: move poseidon hasher APIs to `Node`

* chore: add guide on `MerkleProof `

* chore: update `where` clause in backend

* chore: update comments

* chore: move `generate_leaf_hash` outside of `zk_prover`

* chore: add `ethers` legacy feature

* chore: update verifier contract

* fix: removed minting erc20 on the backend test

* chore: rm unused imports

* feat: remove `Node::leaf()`

* feat: rm `Node::middle()`

* Revert "feat: remove `Node::leaf()`"

This reverts commit ae539a2.

* chore: DRY code

---------

Co-authored-by: sifnoc <[email protected]>
  • Loading branch information
enricobottazzi and sifnoc authored Nov 28, 2023
1 parent 2bb8bff commit a734d94
Show file tree
Hide file tree
Showing 32 changed files with 2,605 additions and 2,448 deletions.
1 change: 1 addition & 0 deletions backend/Cargo.lock

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

3 changes: 2 additions & 1 deletion backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ futures = "0.3.28"
num-bigint = "0.4.3"
serde = { version = "1.0.166", features = ["derive"] }
snark-verifier-sdk = { git = "https://github.com/privacy-scaling-explorations/snark-verifier", version = "0.1.1" }
ethers = { version = "2.0.7", default-features = false, features = ["ethers-solc","legacy"] }
ethers = { version = "2.0.7", default-features = false, features = ["ethers-solc", "legacy"] }
reqwest = { version = "0.11", features = ["json"] }
serde_json = "1.0.64"
tokio = { version = "1.7.1", features = ["full"] }
base64 = "0.13"
bincode = "1.3.3"
num-traits = "0.2.14"

[build-dependencies]
ethers = { version = "2.0.7", default-features = false, features = ["ethers-solc", "legacy"] }
2 changes: 1 addition & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ We have provided a bash script to automate the process of updating the verifier
Ensure you have the necessary permissions to execute the script.

```
backend $ chmod +x scripts/update_verifier_contract.sh
backend $ scripts/update_verifier_contract.sh
```

## Summa solvency flow example
Expand Down
7 changes: 4 additions & 3 deletions backend/examples/summa_solvency_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ use serde_json::{from_reader, to_string_pretty};
use summa_backend::{
apis::{
address_ownership::AddressOwnership,
leaf_hash_from_inputs,
round::{MstInclusionProof, Round},
},
contracts::signer::{AddressInput, SummaSigner},
tests::initialize_test_env,
};
use summa_solvency::merkle_sum_tree::{utils::generate_leaf_hash, MerkleSumTree};
use summa_solvency::merkle_sum_tree::MerkleSumTree;

const N_ASSETS: usize = 2;
const USER_INDEX: usize = 0;
Expand Down Expand Up @@ -103,12 +104,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
// It's assumed that both `user_name` and `balances` are provided by the CEX.
// The `balances` represent the user's balances on the CEX at `snapshot_time`.
let user_name = "dxGaEAii".to_string();
let balances = vec![11888, 41163];
let balances = vec!["11888".to_string(), "41163".to_string()];

let leaf_hash = public_inputs[0];
assert_eq!(
leaf_hash,
generate_leaf_hash::<N_ASSETS>(user_name.clone(), balances.clone())
leaf_hash_from_inputs::<N_ASSETS>(user_name.clone(), balances.clone())
);

// Get `mst_root` from contract. the `mst_root` is disptached by CEX with specific time `snapshot_time`.
Expand Down
9 changes: 7 additions & 2 deletions backend/scripts/update_verifier_contract.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ echo "1. Building verifier contracts"
cd ../zk_prover
cargo run --release --example gen_inclusion_verifier

# Generate Commitment for Merkle Sum Tree
echo "2. Generate Commitment for Merkle Sum Tree"
cd ../zk_prover
cargo run --release --example gen_commitment

# Deploy contracts to local environment
echo "2. Deploying contracts to local environment"
echo "3. Deploying contracts to local environment"
cd ../contracts
npm install
npx hardhat node &
Expand All @@ -16,7 +21,7 @@ sleep 5
npx hardhat run scripts/deploy.ts --network localhost

# Generate interface files for Backend
echo "3. Generating interface files for Backend"
echo "4. Generating interface files for Backend"
cd ../backend
cargo build

Expand Down
22 changes: 22 additions & 0 deletions backend/src/apis/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
pub mod address_ownership;
pub mod csv_parser;
pub mod round;

use ethers::types::U256;
use num_bigint::BigUint;
use num_traits::Num;
use summa_solvency::merkle_sum_tree::Entry;

pub fn leaf_hash_from_inputs<const N_ASSETS: usize>(username: String, balances: Vec<String>) -> U256
where
[usize; N_ASSETS + 1]: Sized,
{
// Convert balances to BigUint
let balances: Vec<BigUint> = balances
.iter()
.map(|balance| BigUint::from_str_radix(balance, 10).unwrap())
.collect();

let entry: Entry<N_ASSETS> = Entry::new(username, balances.try_into().unwrap()).unwrap();

// Convert Fp to U256
let hash_str = format!("{:?}", entry.compute_leaf().hash);
U256::from_str_radix(&hash_str, 16).unwrap()
}
23 changes: 15 additions & 8 deletions backend/src/apis/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ impl<const LEVELS: usize, const N_ASSETS: usize, const N_BYTES: usize>
Round<'_, LEVELS, N_ASSETS, N_BYTES>
where
[usize; N_ASSETS + 1]: Sized,
[usize; 2 * (1 + N_ASSETS)]: Sized,
[usize; N_ASSETS + 2]: Sized,
{
pub fn new<'a>(
signer: &'a SummaSigner,
mst: Box<dyn Tree<N_ASSETS, N_BYTES>>,
params_path: &str,
timestamp: u64,
) -> Result<Round<'a, LEVELS, N_ASSETS, N_BYTES>, Box<dyn Error>> {
) -> Result<Round<'a, LEVELS, N_ASSETS, N_BYTES>, Box<dyn Error>>
where
[(); N_ASSETS + 2]: Sized,
{
Ok(Round {
timestamp,
snapshot: Snapshot::<LEVELS, N_ASSETS, N_BYTES>::new(mst, params_path).unwrap(),
Expand Down Expand Up @@ -109,7 +112,10 @@ where
pub fn get_proof_of_inclusion(
&self,
user_index: usize,
) -> Result<MstInclusionProof, &'static str> {
) -> Result<MstInclusionProof, &'static str>
where
[(); N_ASSETS + 2]: Sized,
{
Ok(self
.snapshot
.generate_proof_of_inclusion(user_index)
Expand All @@ -121,7 +127,7 @@ impl<const LEVELS: usize, const N_ASSETS: usize, const N_BYTES: usize>
Snapshot<LEVELS, N_ASSETS, N_BYTES>
where
[usize; N_ASSETS + 1]: Sized,
[usize; 2 * (1 + N_ASSETS)]: Sized,
[usize; N_ASSETS + 2]: Sized,
{
pub fn new(
mst: Box<dyn Tree<N_ASSETS, N_BYTES>>,
Expand All @@ -146,11 +152,12 @@ where
pub fn generate_proof_of_inclusion(
&self,
user_index: usize,
) -> Result<MstInclusionProof, &'static str> {
) -> Result<MstInclusionProof, &'static str>
where
[(); N_ASSETS + 2]: Sized,
{
let merkle_proof = self.mst.generate_proof(user_index).unwrap();
let user_entry = self.mst.get_entry(user_index).clone();
let circuit =
MstInclusionCircuit::<LEVELS, N_ASSETS, N_BYTES>::init(merkle_proof, user_entry);
let circuit = MstInclusionCircuit::<LEVELS, N_ASSETS, N_BYTES>::init(merkle_proof);

// Currently, default manner of generating a inclusion proof for solidity-verifier.
let calldata = gen_proof_solidity_calldata(
Expand Down
2 changes: 1 addition & 1 deletion backend/src/contracts/abi/InclusionVerifier.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/src/contracts/deployments.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"31337":{"address":"0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9"}}
{"31337":{"address":"0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"}}
Loading

0 comments on commit a734d94

Please sign in to comment.