Browse Source

Separate builds for prod & tests for faster tests

pull/2/head
arnaucube 3 years ago
parent
commit
9776f46e4b
15 changed files with 88 additions and 21 deletions
  1. +1
    -1
      .github/workflows/tests.yml
  2. +1
    -0
      README.md
  3. +1
    -1
      circuits/deposit.circom
  4. +2
    -0
      circuits/main/deposit.circom
  5. +3
    -0
      circuits/main/withdraw.circom
  6. +1
    -1
      circuits/withdraw.circom
  7. +2
    -2
      compile-circuits.sh
  8. +2
    -2
      migrations/2_deploy_contracts.js
  9. +55
    -0
      test-compile-circuits.sh
  10. +2
    -2
      test/circuits/deposit.test.ts
  11. +3
    -0
      test/circuits/main/deposit.circom
  12. +3
    -0
      test/circuits/main/withdraw.circom
  13. +2
    -2
      test/circuits/withdraw.test.ts
  14. +9
    -10
      test/contracts/miksi.test.ts
  15. +1
    -0
      truffle-config.js

+ 1
- 1
.github/workflows/tests.yml

@ -20,6 +20,6 @@ jobs:
run: npm install
- name: Execute tests
run: |
sh ./compile-circuits.sh
sh ./test-compile-circuits.sh
npm run test-circuits
npm run test-sc

+ 1
- 0
README.md

@ -3,6 +3,7 @@
*From Esperanto, **miksi** (miks·i): to mingle, to blend, to mix, to shuffle*
Ethereum mixer where all the computation & constructions are done offchain and then proved inside a zkSNARK to the Smart Contract (for the *deposit* and for the *withdraw*).
This means that the client builds a MerkleTree and makes all the needed computation, and then generates a zk-proof where proves that all the offchain computation is done following all the rules (no leaf deletion, only one leaf addition, correct leaf format).
This allows to use only `~325.000 gas` for the *deposit*, and `~308.000 gas` for the withdraw.

+ 1
- 1
circuits/deposit.circom

@ -107,4 +107,4 @@ template Deposit(nLevels) {
smtNew.value <== hash.out;
}
component main = Deposit(17); // 16 real levels (due circom leaf protection)
/* component main = Deposit(17); // 16 real levels (due circom leaf protection) */

+ 2
- 0
circuits/main/deposit.circom

@ -0,0 +1,2 @@
include "../deposit.circom";
component main = Deposit(17); // 16 real levels (due circom leaf protection)

+ 3
- 0
circuits/main/withdraw.circom

@ -0,0 +1,3 @@
include "../withdraw.circom";
component main = Withdraw(17); // 16 real levels (due circom leaf protection)

+ 1
- 1
circuits/withdraw.circom

@ -62,4 +62,4 @@ template Withdraw(nLevels) {
smtV.value <== hash.out;
}
component main = Withdraw(17); // 16 real levels (due circom leaf protection)
/* component main = Withdraw(17); // 16 real levels (due circom leaf protection) */

+ 2
- 2
compile-circuits.sh

@ -6,9 +6,9 @@ mkdir build
cd build
compile_and_ts() {
echo $(date +"%T") "circom ../circuits/$CIRCUIT.circom --r1cs --wasm --sym"
echo $(date +"%T") "circom ../circuits/main/$CIRCUIT.circom --r1cs --wasm --sym"
itime="$(date -u +%s)"
../node_modules/.bin/circom ../circuits/$CIRCUIT.circom --r1cs --wasm --sym
../node_modules/.bin/circom ../circuits/main/$CIRCUIT.circom --r1cs --wasm --sym
ftime="$(date -u +%s)"
echo " ($(($(date -u +%s)-$itime))s)"

+ 2
- 2
migrations/2_deploy_contracts.js

@ -1,5 +1,5 @@
const DepositVerifier = artifacts.require("../contracts/DepositVerifier");
const WithdrawVerifier = artifacts.require("../contracts/WithdrawVerifier");
const DepositVerifier = artifacts.require("../test/build/DepositVerifier");
const WithdrawVerifier = artifacts.require("../test/build/WithdrawVerifier");
module.exports = function(deployer) {
deployer.deploy(DepositVerifier);

+ 55
- 0
test-compile-circuits.sh

@ -0,0 +1,55 @@
#!/bin/sh
# This file compiles the circuits to generate the test files
# npm install
cd test
rm -r build
mkdir build
cd build
compile_and_ts() {
echo $(date +"%T") "circom ../circuits/main/$CIRCUIT.circom --r1cs --wasm --sym"
itime="$(date -u +%s)"
../../node_modules/.bin/circom ../circuits/main/$CIRCUIT.circom --r1cs --wasm --sym
ftime="$(date -u +%s)"
echo " ($(($(date -u +%s)-$itime))s)"
echo $(date +"%T") "snarkjs info -r $CIRCUIT.r1cs"
../../node_modules/.bin/snarkjs info -r $CIRCUIT.r1cs
echo $(date +"%T") "snarkjs setup"
itime="$(date -u +%s)"
../../node_modules/.bin/snarkjs setup -r $CIRCUIT.r1cs --pk $CIRCUIT-proving_key.json --vk $CIRCUIT-verification_key.json
echo " ($(($(date -u +%s)-$itime))s)"
echo $(date +"%T") "trusted setup generated"
# sed -i 's/null/["0","0","0"]/g' proving_key.json
echo $(date +"%T") "snarkjs generateverifier"
itime="$(date -u +%s)"
../../node_modules/.bin/snarkjs generateverifier --vk $CIRCUIT-verification_key.json -v $CIRCUIT-verifier.sol
echo " ($(($(date -u +%s)-$itime))s)"
echo $(date +"%T") "generateverifier generated"
sed -i "s/solidity ^0.5.0/solidity ^0.6.0/g" ${CIRCUIT}-verifier.sol
sed -i "s/gas/gas()/g" ${CIRCUIT}-verifier.sol
sed -i "s/return the sum/return r the sum/g" ${CIRCUIT}-verifier.sol
sed -i "s/return the product/return r the product/g" ${CIRCUIT}-verifier.sol
sed -i "s/contract Verifier/contract ${CONTRACT}Verifier/g" ${CIRCUIT}-verifier.sol
sed -i "s/Pairing/${CONTRACT}Pairing/g" ${CIRCUIT}-verifier.sol
# cp ${CIRCUIT}-verifier.sol ../contracts/
node ../../node_modules/wasmsnark/tools/buildpkey.js -i ${CIRCUIT}-proving_key.json -o ${CIRCUIT}-proving_key.bin
}
CIRCUIT="deposit"
CONTRACT="Deposit"
compile_and_ts
CIRCUIT="withdraw"
CONTRACT="Withdraw"
compile_and_ts
cp ../../contracts/Miksi.sol ./Miksi.sol
cp -r ../../contracts/helpers ./helpers

+ 2
- 2
test/circuits/deposit.test.ts

@ -13,11 +13,11 @@ describe("deposit test", function () {
it("Test Deposit", async () => {
const circuit = await tester(
path.join(__dirname, "../../circuits", "deposit.circom"),
path.join(__dirname, "main", "deposit.circom"),
{reduceConstraints: false}
);
const nLevels = 17;
const nLevels = 4;
const secret = "1234567890";
const coinCode = "0";

+ 3
- 0
test/circuits/main/deposit.circom

@ -0,0 +1,3 @@
include "../../../circuits/deposit.circom";
component main = Deposit(4);

+ 3
- 0
test/circuits/main/withdraw.circom

@ -0,0 +1,3 @@
include "../../../circuits/withdraw.circom";
component main = Withdraw(4);

+ 2
- 2
test/circuits/withdraw.test.ts

@ -13,11 +13,11 @@ describe("withdraw test", function () {
it("Test Withdraw", async () => {
const circuit = await tester(
path.join(__dirname, "../../circuits", "withdraw.circom"),
path.join(__dirname, "main", "withdraw.circom"),
{reduceConstraints: false}
);
const nLevels = 17;
const nLevels = 4;
const secret = "1234567890";
const coinCode = "0";

+ 9
- 10
test/contracts/miksi.test.ts

@ -1,6 +1,6 @@
const DepositVerifier = artifacts.require("../../contracts/DepositVerifier");
const WithdrawVerifier = artifacts.require("../../contracts/WithdrawVerifier");
const Miksi = artifacts.require("../../contracts/Miksi.sol");
const DepositVerifier = artifacts.require("../build/DepositVerifier");
const WithdrawVerifier = artifacts.require("../build/WithdrawVerifier");
const Miksi = artifacts.require("../build/Miksi.sol");
const chai = require("chai");
const expect = chai.expect;
@ -16,7 +16,7 @@ const smt = require("circomlib").smt;
let insVerifier;
let insMiksi;
const nLevels = 17;
const nLevels = 4;
const secret = ["1234567890", "987654321", "123"];
const coinCode = "0"; // refearing to ETH
@ -105,7 +105,6 @@ contract("miksi", (accounts) => {
});
it("Calculate witness and generate the zkProof", async () => {
this.timeout(10000000);
await genZKProof(0, addr2, "1");
await genZKProof(1, addr4, "2");
await genZKProof(2, addr4, "3");
@ -193,7 +192,7 @@ async function makeDeposit(u, addr) {
};
// calculate witness
const wasm = await fs.promises.readFile("./build/deposit.wasm");
const wasm = await fs.promises.readFile("./test/build/deposit.wasm");
const input = unstringifyBigInts({
"coinCode": coinCode,
"amount": amount,
@ -215,14 +214,14 @@ async function makeDeposit(u, addr) {
const witness = unstringifyBigInts(stringifyBigInts(w));
// generate zkproof of commitment using snarkjs (as is a test)
const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./build/deposit-proving_key.json", "utf8")));
const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./test/build/deposit-proving_key.json", "utf8")));
// console.log("Generate zkSNARK proof");
const res = groth.genProof(provingKey, witness);
proof[u] = res.proof;
publicSignals[u] = res.publicSignals;
const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./build/deposit-verification_key.json", "utf8")));
const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./test/build/deposit-verification_key.json", "utf8")));
let pubI = unstringifyBigInts([coinCode, amount, rootOld[u].toString(), rootNew[u].toString(), commitment[u], currKey]);
let validCheck = groth.isValid(verificationKey, proof[u], pubI);
assert(validCheck);
@ -250,7 +249,7 @@ async function genZKProof(u, addr, k) {
// console.log("siblings", siblings);
// calculate witness
const wasm = await fs.promises.readFile("./build/withdraw.wasm");
const wasm = await fs.promises.readFile("./test/build/withdraw.wasm");
const input = unstringifyBigInts({
"coinCode": coinCode,
"amount": amount,
@ -268,7 +267,7 @@ async function genZKProof(u, addr, k) {
const witness = unstringifyBigInts(stringifyBigInts(w));
// generate zkproof of commitment using snarkjs (as is a test)
const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./build/withdraw-proving_key.json", "utf8")));
const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./test/build/withdraw-proving_key.json", "utf8")));
// console.log("Generate zkSNARK proof");
const res = groth.genProof(provingKey, witness);

+ 1
- 0
truffle-config.js

@ -18,6 +18,7 @@ module.exports = {
enableTimeouts: false,
before_timeout: 1000000000,
test_timeout: 1000000000,
contracts_directory: "./test/build",
compilers: {
solc: {
version: "0.6.0"

Loading…
Cancel
Save