Skip to content

Commit

Permalink
Merge branch 'main' of github.com:hyperledger-labs/zeto into more-inputs
Browse files Browse the repository at this point in the history
Signed-off-by: Chengxuan Xing <[email protected]>
  • Loading branch information
Chengxuan committed Sep 25, 2024
2 parents ec1d4cb + 713dcce commit 2a989b6
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 46 deletions.
3 changes: 1 addition & 2 deletions go-sdk/internal/sparse-merkle-tree/smt/merkletree.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

"github.com/hyperledger-labs/zeto/go-sdk/internal/log"
"github.com/hyperledger-labs/zeto/go-sdk/internal/sparse-merkle-tree/node"
"github.com/hyperledger-labs/zeto/go-sdk/internal/sparse-merkle-tree/storage"
"github.com/hyperledger-labs/zeto/go-sdk/internal/sparse-merkle-tree/utils"
"github.com/hyperledger-labs/zeto/go-sdk/pkg/sparse-merkle-tree/core"
)
Expand All @@ -46,7 +45,7 @@ func NewMerkleTree(db core.Storage, maxLevels int) (core.SparseMerkleTree, error
mt := sparseMerkleTree{db: db, maxLevels: maxLevels}

root, err := mt.db.GetRootNodeIndex()
if err == storage.ErrNotFound {
if err == core.ErrNotFound {
mt.rootKey = node.ZERO_INDEX
err = mt.db.UpsertRootNodeIndex(mt.rootKey)
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions go-sdk/internal/sparse-merkle-tree/smt/merkletree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"fmt"
"testing"

"github.com/hyperledger-labs/zeto/go-sdk/internal/sparse-merkle-tree/storage"
"github.com/hyperledger-labs/zeto/go-sdk/pkg/sparse-merkle-tree/core"
"github.com/stretchr/testify/assert"
)
Expand All @@ -33,7 +32,7 @@ func (ms *mockStorage) GetRootNodeIndex() (core.NodeIndex, error) {
if ms.GetRootNodeIndex_customError {
return nil, fmt.Errorf("nasty error in get root")
}
return nil, storage.ErrNotFound
return nil, core.ErrNotFound
}
func (ms *mockStorage) UpsertRootNodeIndex(core.NodeIndex) error {
return fmt.Errorf("nasty error in upsert root")
Expand Down
4 changes: 2 additions & 2 deletions go-sdk/internal/sparse-merkle-tree/storage/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (s *sqlStorage) GetRootNodeIndex() (core.NodeIndex, error) {
}
err := s.p.DB().Table(core.TreeRootsTable).First(&root).Error
if err == gorm.ErrRecordNotFound {
return nil, ErrNotFound
return nil, core.ErrNotFound
} else if err != nil {
return nil, err
}
Expand Down Expand Up @@ -121,7 +121,7 @@ func getNode(batchOrDb *gorm.DB, nodesTableName string, ref core.NodeIndex) (cor
}
err := batchOrDb.Table(nodesTableName).First(&n).Error
if err == gorm.ErrRecordNotFound {
return nil, ErrNotFound
return nil, core.ErrNotFound
} else if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package storage
package core

import "errors"

Expand Down
3 changes: 2 additions & 1 deletion solidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@iden3/contracts": "^2.0.5",
"@openzeppelin/contracts": "^5.0.1",
"@openzeppelin/contracts-upgradeable": "^5.0.2",
"@openzeppelin/hardhat-upgrades": "^3.2.1"
"@openzeppelin/hardhat-upgrades": "^3.2.1",
"async-lock": "^1.4.1"
}
}
93 changes: 56 additions & 37 deletions solidity/test/gas_cost/zeto_anon_enc_nullifier_kyc_cost_analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { expect } from 'chai';
import { loadCircuit, encodeProof, newEncryptionNonce, kycHash } from 'zeto-js';
import { groth16 } from 'snarkjs';
import { stringifyBigInts } from 'maci-crypto';
import AsyncLock from 'async-lock';
const lock = new AsyncLock();
import { Merkletree, InMemoryDB, str2Bytes } from '@iden3/js-merkletree';
import {
UTXO,
Expand Down Expand Up @@ -248,7 +250,7 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin
}).timeout(6000000000000);

it(`Alice transfer ${TOTAL_AMOUNT} tokens to Bob in ${atLeastBatchedAmount} txs`, async function () {
const totalTxs = unspentAliceUTXOs.length / 2;
const totalTxs = Math.floor(unspentAliceUTXOs.length / 2);
const utxosRoot = await smtAlice.root(); // get the root before all transfer and use it for all the proofs
let promises = [];
// Alice generates inclusion proofs for the identities in the transaction
Expand Down Expand Up @@ -318,7 +320,7 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin
);

// If we reach the concurrency limit, wait for the current batch to finish
if (promises.length >= 1) {
if (promises.length >= TX_CONCURRENCY) {
await Promise.all(promises);
promises = []; // Reset promises for the next batch
}
Expand All @@ -338,43 +340,56 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin
const startingBalance = await erc20.balanceOf(Bob.ethAddress);

const root = await smtBob.root();
let promises = [];
for (let i = 0; i < unspentBobUTXOs.length; i++) {
if (unspentBobUTXOs[i].value) {
const utxoToWithdraw = unspentBobUTXOs[i];
const nullifier1 = newNullifier(utxoToWithdraw, Bob);

const proof1 = await smtBob.generateCircomVerifierProof(
utxoToWithdraw.hash,
root
);
const proof2 = await smtBob.generateCircomVerifierProof(0n, root);
const merkleProofs = [
proof1.siblings.map((s) => s.bigInt()),
proof2.siblings.map((s) => s.bigInt()),
];

const { nullifiers, outputCommitments, encodedProof } =
await prepareNullifierWithdrawProof(
Bob,
[utxoToWithdraw, ZERO_UTXO],
[nullifier1, ZERO_UTXO],
newUTXO(0, Bob),
root.bigInt(),
merkleProofs
);

// Bob withdraws UTXOs to ERC20 tokens
await doWithdraw(
zeto,
Bob.signer,
1,
nullifiers,
outputCommitments[0],
root.bigInt(),
encodedProof,
withdrawGasCostHistory
promises.push(
(async () => {
const utxoToWithdraw = unspentBobUTXOs[i];
const nullifier1 = newNullifier(utxoToWithdraw, Bob);

const proof1 = await smtBob.generateCircomVerifierProof(
utxoToWithdraw.hash,
root
);
const proof2 = await smtBob.generateCircomVerifierProof(0n, root);
const merkleProofs = [
proof1.siblings.map((s) => s.bigInt()),
proof2.siblings.map((s) => s.bigInt()),
];
const { nullifiers, outputCommitments, encodedProof } =
await prepareNullifierWithdrawProof(
Bob,
[utxoToWithdraw, ZERO_UTXO],
[nullifier1, ZERO_UTXO],
newUTXO(0, Bob),
root.bigInt(),
merkleProofs
);

// Bob withdraws UTXOs to ERC20 tokens
await doWithdraw(
zeto,
Bob.signer,
1,
nullifiers,
outputCommitments[0],
root.bigInt(),
encodedProof,
withdrawGasCostHistory
);
})()
);
}
// If we reach the concurrency limit, wait for the current batch to finish
if (promises.length >= TX_CONCURRENCY) {
await Promise.all(promises);
promises = []; // Reset promises for the next batch
}
}
// Run any remaining promises that didn’t fill the batch
if (promises.length > 0) {
await Promise.all(promises);
}
writeGasCostsToCSV(
`${reportPrefix}withdraw_gas_costs.csv`,
Expand Down Expand Up @@ -494,7 +509,10 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin
outputOwnerPublicKeys,
...encryptInputs,
};
const witness = await circuit.calculateWTNSBin(inputObj, true);
const witness = await lock.acquire('proofGen', async () => {
// this lock is added for https://github.com/hyperledger-labs/zeto/issues/80, which only happens for Transfer circuit, not deposit/mint
return circuit.calculateWTNSBin(inputObj, true);
});
const timeWithnessCalculation = Date.now() - startWitnessCalculation;

const startProofGeneration = Date.now();
Expand Down Expand Up @@ -537,7 +555,8 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin
root,
encryptionNonce,
encryptedValues,
encodedProof
encodedProof,
'0x'
);
const result: ContractTransactionReceipt | null = await tx.wait();
console.log(
Expand Down
2 changes: 1 addition & 1 deletion solidity/test/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export async function doMint(zetoTokenContract: any, minter: Signer, outputs: UT
}

export async function doDeposit(zetoTokenContract: any, depositUser: Signer, amount:any, commitment: any, proof: any, gasHistories?:number[]): Promise<ContractTransactionReceipt> {
const tx = await zetoTokenContract.connect(depositUser).deposit(amount, commitment, proof);
const tx = await zetoTokenContract.connect(depositUser).deposit(amount, commitment, proof, "0x");
const result = await tx.wait();
console.log(`Method deposit() complete. Gas used: ${result?.gasUsed}`);
if (result?.gasUsed && Array.isArray(gasHistories)) {
Expand Down

0 comments on commit 2a989b6

Please sign in to comment.