diff --git a/Circuits/OffchainWithdrawalCircuit.h b/Circuits/OffchainWithdrawalCircuit.h index 3734c91..37c0dd2 100644 --- a/Circuits/OffchainWithdrawalCircuit.h +++ b/Circuits/OffchainWithdrawalCircuit.h @@ -42,6 +42,7 @@ class OffchainWithdrawalGadget : public GadgetT AccountState accountWalletBefore; VariableT balanceF_O_before; + VariableT tradingHistoryRootF_O; MulDivGadget feeToWallet; UnsafeSubGadget feeToOperator; @@ -127,6 +128,7 @@ class OffchainWithdrawalGadget : public GadgetT // Operator balanceF_O_before(make_variable(pb, FMT(prefix, ".balanceF_O_before"))), + tradingHistoryRootF_O(make_variable(pb, FMT(prefix, ".tradingHistoryRootF_O"))), // Split the fee between wallet and operator feeToWallet(pb, constants, fFee.value(), walletSplitPercentage.value.packed, constants._100, FMT(prefix, ".feeToWallet")), @@ -178,8 +180,8 @@ class OffchainWithdrawalGadget : public GadgetT // Update Operator updateBalanceF_O(pb, operatorBalancesRoot, feeTokenID, - {balanceF_O_before, constants.emptyTradeHistory}, - {feePaymentOperator.Y, constants.emptyTradeHistory}, + {balanceF_O_before, tradingHistoryRootF_O}, + {feePaymentOperator.Y, tradingHistoryRootF_O}, FMT(prefix, ".updateBalanceF_O")), // Signature @@ -252,6 +254,7 @@ class OffchainWithdrawalGadget : public GadgetT // Operator pb.val(balanceF_O_before) = withdrawal.balanceUpdateF_O.before.balance; + pb.val(tradingHistoryRootF_O) = withdrawal.balanceUpdateF_O.before.tradingHistoryRoot; // Fee payments calculations feeToWallet.generate_r1cs_witness(); diff --git a/Circuits/OrderCancellationCircuit.h b/Circuits/OrderCancellationCircuit.h index c67852e..8bbb58a 100644 --- a/Circuits/OrderCancellationCircuit.h +++ b/Circuits/OrderCancellationCircuit.h @@ -51,6 +51,7 @@ class OrderCancellationGadget : public GadgetT VariableT balancesRoot_W_before; VariableT balanceF_W_before; VariableT nonce_W; + VariableT tradingHistoryRootF_W; VariableT balanceF_O_before; VariableT tradingHistoryRootF_O; @@ -120,6 +121,7 @@ class OrderCancellationGadget : public GadgetT balancesRoot_W_before(make_variable(pb, FMT(prefix, ".balancesRoot_W_before"))), balanceF_W_before(make_variable(pb, FMT(prefix, ".balanceF_W_before"))), nonce_W(make_variable(pb, FMT(prefix, ".nonce_W"))), + tradingHistoryRootF_W(make_variable(pb, FMT(prefix, ".tradingHistoryRootF_W"))), balanceF_O_before(make_variable(pb, FMT(prefix, ".balanceF_O_before"))), tradingHistoryRootF_O(make_variable(pb, FMT(prefix, ".tradingHistoryRootF_O"))), @@ -160,8 +162,8 @@ class OrderCancellationGadget : public GadgetT // Wallet balance updateBalanceF_W(pb, balancesRoot_W_before, feeTokenID, - {balanceF_W_before, constants.emptyTradeHistory}, - {feePaymentWallet.Y, constants.emptyTradeHistory}, + {balanceF_W_before, tradingHistoryRootF_W}, + {feePaymentWallet.Y, tradingHistoryRootF_W}, FMT(prefix, ".updateBalanceF_W")), // Wallet account updateAccount_W(pb, updateAccount_A.result(), walletAccountID, @@ -240,6 +242,7 @@ class OrderCancellationGadget : public GadgetT pb.val(balancesRoot_W_before) = cancellation.accountUpdate_W.before.balancesRoot; pb.val(balanceF_W_before) = cancellation.balanceUpdateF_W.before.balance; pb.val(nonce_W) = cancellation.accountUpdate_W.before.nonce; + pb.val(tradingHistoryRootF_W) = cancellation.balanceUpdateF_W.before.tradingHistoryRoot; pb.val(balanceF_O_before) = cancellation.balanceUpdateF_O.before.balance; pb.val(tradingHistoryRootF_O) = cancellation.balanceUpdateF_O.before.tradingHistoryRoot; diff --git a/Circuits/RingSettlementCircuit.h b/Circuits/RingSettlementCircuit.h index 92cb8de..b110998 100644 --- a/Circuits/RingSettlementCircuit.h +++ b/Circuits/RingSettlementCircuit.h @@ -115,6 +115,10 @@ class RingSettlementGadget : public GadgetT const VariableT tradingHistoryRootB_A; const VariableT tradingHistoryRootS_B; const VariableT tradingHistoryRootB_B; + const VariableT tradingHistoryRootA_M; + const VariableT tradingHistoryRootB_M; + const VariableT tradingHistoryRootO_M; + const VariableT tradingHistoryRoot_O; const VariableT balancesRootA; const VariableT balancesRootB; @@ -123,7 +127,7 @@ class RingSettlementGadget : public GadgetT VariableT blockexchangeID; const jubjub::VariablePointT publicKey; - libsnark::dual_variable_gadget minerAccountID; + libsnark::dual_variable_gadget ringMatcherAccountID; VariableArrayT tokenID; libsnark::dual_variable_gadget fee; FloatGadget fFee; @@ -134,9 +138,6 @@ class RingSettlementGadget : public GadgetT OrderGadget orderA; OrderGadget orderB; - ForceNotEqualGadget accountA_neq_ringMatcher; - ForceNotEqualGadget accountB_neq_ringMatcher; - OrderMatchingGadget orderMatching; TernaryGadget uFillS_A; @@ -201,7 +202,7 @@ class RingSettlementGadget : public GadgetT UpdateBalanceGadget updateBalanceF_O; const VariableArrayT message; - SignatureVerifier minerSignatureVerifier; + SignatureVerifier ringMatcherSignatureVerifier; SignatureVerifier dualAuthASignatureVerifier; SignatureVerifier dualAuthBSignatureVerifier; @@ -224,7 +225,7 @@ class RingSettlementGadget : public GadgetT constants(_constants), publicKey(pb, FMT(prefix, ".publicKey")), - minerAccountID(pb, NUM_BITS_ACCOUNT, FMT(prefix, ".minerAccountID")), + ringMatcherAccountID(pb, NUM_BITS_ACCOUNT, FMT(prefix, ".ringMatcherAccountID")), tokenID(make_var_array(pb, TREE_DEPTH_TOKENS, FMT(prefix, ".tokenID"))), fee(pb, NUM_BITS_AMOUNT, FMT(prefix, ".fee")), fFee(pb, constants, Float12Encoding, FMT(prefix, ".fFee")), @@ -235,9 +236,6 @@ class RingSettlementGadget : public GadgetT orderA(pb, params, constants, _exchangeID, FMT(prefix, ".orderA")), orderB(pb, params, constants, _exchangeID, FMT(prefix, ".orderB")), - accountA_neq_ringMatcher(pb, orderA.accountID.packed, minerAccountID.packed, FMT(prefix, ".accountA_neq_ringMatcher")), - accountB_neq_ringMatcher(pb, orderB.accountID.packed, minerAccountID.packed, FMT(prefix, ".accountB_neq_ringMatcher")), - // Match orders orderMatching(pb, constants, _timestamp, orderA, orderB, FMT(prefix, ".orderMatching")), @@ -291,6 +289,10 @@ class RingSettlementGadget : public GadgetT tradingHistoryRootB_A(make_variable(pb, FMT(prefix, ".tradingHistoryRootB_A"))), tradingHistoryRootS_B(make_variable(pb, FMT(prefix, ".tradingHistoryRootS_B"))), tradingHistoryRootB_B(make_variable(pb, FMT(prefix, ".tradingHistoryRootB_B"))), + tradingHistoryRootA_M(make_variable(pb, FMT(prefix, ".tradingHistoryRootA_M"))), + tradingHistoryRootB_M(make_variable(pb, FMT(prefix, ".tradingHistoryRootB_M"))), + tradingHistoryRootO_M(make_variable(pb, FMT(prefix, ".tradingHistoryRootO_M"))), + tradingHistoryRoot_O(make_variable(pb, FMT(prefix, ".tradingHistoryRoot_O"))), // Initial balances roots balancesRootA(make_variable(pb, FMT(prefix, ".balancesRootA"))), @@ -341,18 +343,18 @@ class RingSettlementGadget : public GadgetT // Update Ring-Matcher updateBalanceA_M(pb, balancesRootM, orderA.tokenB.bits, - {balanceA_M.front(), constants.emptyTradeHistory}, - {balanceA_M.back(), constants.emptyTradeHistory}, + {balanceA_M.front(), tradingHistoryRootA_M}, + {balanceA_M.back(), tradingHistoryRootA_M}, FMT(prefix, ".updateBalanceA_M")), updateBalanceB_M(pb, updateBalanceA_M.getNewRoot(), orderB.tokenB.bits, - {balanceB_M.front(), constants.emptyTradeHistory}, - {balanceB_M.back(), constants.emptyTradeHistory}, + {balanceB_M.front(), tradingHistoryRootB_M}, + {balanceB_M.back(), tradingHistoryRootB_M}, FMT(prefix, ".updateBalanceB_M")), updateBalanceO_M(pb, updateBalanceB_M.getNewRoot(), tokenID, - {balanceO_M.front(), constants.emptyTradeHistory}, - {balanceO_M.back(), constants.emptyTradeHistory}, + {balanceO_M.front(), tradingHistoryRootO_M}, + {balanceO_M.back(), tradingHistoryRootO_M}, FMT(prefix, ".updateBalanceO_M")), - updateAccount_M(pb, updateAccount_B.result(), minerAccountID.bits, + updateAccount_M(pb, updateAccount_B.result(), ringMatcherAccountID.bits, {publicKey.x, publicKey.y, nonce_before.packed, balancesRootM}, {publicKey.x, publicKey.y, nonce_after.result(), updateBalanceO_M.getNewRoot()}, FMT(prefix, ".updateAccount_M")), @@ -369,17 +371,17 @@ class RingSettlementGadget : public GadgetT // Update Operator updateBalanceF_O(pb, _operatorBalancesRoot, tokenID, - {balanceF_O.front(), constants.emptyTradeHistory}, - {balanceF_O.back(), constants.emptyTradeHistory}, + {balanceF_O.front(), tradingHistoryRoot_O}, + {balanceF_O.back(), tradingHistoryRoot_O}, FMT(prefix, ".updateBalanceF_O")), // Signatures message(flatten({orderA.getHash(), orderB.getHash(), - minerAccountID.bits, tokenID, fee.bits, + ringMatcherAccountID.bits, tokenID, fee.bits, orderA.feeBips.bits, orderB.feeBips.bits, orderA.rebateBips.bits, orderB.rebateBips.bits, nonce_before.bits, constants.padding_0})), - minerSignatureVerifier(pb, params, publicKey, message, FMT(prefix, ".minerSignatureVerifier")), + ringMatcherSignatureVerifier(pb, params, publicKey, message, FMT(prefix, ".ringMatcherSignatureVerifier")), dualAuthASignatureVerifier(pb, params, orderA.dualAuthPublicKey, message, FMT(prefix, ".dualAuthASignatureVerifier")), dualAuthBSignatureVerifier(pb, params, orderB.dualAuthPublicKey, message, FMT(prefix, ".dualAuthBSignatureVerifier")) { @@ -405,7 +407,7 @@ class RingSettlementGadget : public GadgetT { return { - minerAccountID.bits, + ringMatcherAccountID.bits, fFee.bits(), tokenID, @@ -427,8 +429,8 @@ class RingSettlementGadget : public GadgetT pb.val(publicKey.x) = ringSettlement.accountUpdate_M.before.publicKey.x; pb.val(publicKey.y) = ringSettlement.accountUpdate_M.before.publicKey.y; - minerAccountID.bits.fill_with_bits_of_field_element(pb, ringSettlement.ring.minerAccountID); - minerAccountID.generate_r1cs_witness_from_bits(); + ringMatcherAccountID.bits.fill_with_bits_of_field_element(pb, ringSettlement.ring.ringMatcherAccountID); + ringMatcherAccountID.generate_r1cs_witness_from_bits(); tokenID.fill_with_bits_of_field_element(pb, ringSettlement.ring.tokenID); fee.bits.fill_with_bits_of_field_element(pb, ringSettlement.ring.fee); fee.generate_r1cs_witness_from_bits(); @@ -449,9 +451,6 @@ class RingSettlementGadget : public GadgetT ringSettlement.balanceUpdateB_B.before, ringSettlement.tradeHistoryUpdate_B.before); - accountA_neq_ringMatcher.generate_r1cs_witness(); - accountB_neq_ringMatcher.generate_r1cs_witness(); - // Match orders orderMatching.generate_r1cs_witness(); @@ -503,6 +502,10 @@ class RingSettlementGadget : public GadgetT pb.val(tradingHistoryRootB_A) = ringSettlement.balanceUpdateB_A.before.tradingHistoryRoot; pb.val(tradingHistoryRootS_B) = ringSettlement.balanceUpdateS_B.before.tradingHistoryRoot; pb.val(tradingHistoryRootB_B) = ringSettlement.balanceUpdateB_B.before.tradingHistoryRoot; + pb.val(tradingHistoryRootA_M) = ringSettlement.balanceUpdateA_M.before.tradingHistoryRoot; + pb.val(tradingHistoryRootB_M) = ringSettlement.balanceUpdateB_M.before.tradingHistoryRoot; + pb.val(tradingHistoryRootO_M) = ringSettlement.balanceUpdateO_M.before.tradingHistoryRoot; + pb.val(tradingHistoryRoot_O) = ringSettlement.balanceUpdateF_O.before.tradingHistoryRoot; // Initial balances roots pb.val(balancesRootA) = ringSettlement.balanceUpdateS_A.rootBefore; @@ -535,7 +538,7 @@ class RingSettlementGadget : public GadgetT updateBalanceF_O.generate_r1cs_witness(ringSettlement.balanceUpdateF_O.proof); // Signatures - minerSignatureVerifier.generate_r1cs_witness(ringSettlement.ring.minerSignature); + ringMatcherSignatureVerifier.generate_r1cs_witness(ringSettlement.ring.ringMatcherSignature); dualAuthASignatureVerifier.generate_r1cs_witness(ringSettlement.ring.dualAuthASignature); dualAuthBSignatureVerifier.generate_r1cs_witness(ringSettlement.ring.dualAuthBSignature); } @@ -543,7 +546,7 @@ class RingSettlementGadget : public GadgetT void generate_r1cs_constraints() { - minerAccountID.generate_r1cs_constraints(true); + ringMatcherAccountID.generate_r1cs_constraints(true); fee.generate_r1cs_constraints(true); fFee.generate_r1cs_constraints(); ensureAccuracyFee.generate_r1cs_constraints(); @@ -553,9 +556,6 @@ class RingSettlementGadget : public GadgetT orderA.generate_r1cs_constraints(); orderB.generate_r1cs_constraints(); - accountA_neq_ringMatcher.generate_r1cs_constraints(); - accountB_neq_ringMatcher.generate_r1cs_constraints(); - // Match orders orderMatching.generate_r1cs_constraints(); @@ -612,7 +612,7 @@ class RingSettlementGadget : public GadgetT updateBalanceF_O.generate_r1cs_constraints(); // Signatures - minerSignatureVerifier.generate_r1cs_constraints(); + ringMatcherSignatureVerifier.generate_r1cs_constraints(); dualAuthASignatureVerifier.generate_r1cs_constraints(); dualAuthBSignatureVerifier.generate_r1cs_constraints(); } @@ -650,6 +650,7 @@ class RingSettlementCircuit : public GadgetT libsnark::dual_variable_gadget operatorAccountID; const jubjub::VariablePointT publicKey; const VariableT balancesRootO_before; + const VariableT nonce_O; UpdateAccountGadget* updateAccount_O; RingSettlementCircuit(ProtoboardT& pb, const std::string& prefix) : @@ -672,7 +673,8 @@ class RingSettlementCircuit : public GadgetT operatorAccountID(pb, TREE_DEPTH_ACCOUNTS, FMT(prefix, ".operatorAccountID")), publicKey(pb, FMT(prefix, ".publicKey")), - balancesRootO_before(make_variable(pb, FMT(prefix, ".balancesRootO_before"))) + balancesRootO_before(make_variable(pb, FMT(prefix, ".balancesRootO_before"))), + nonce_O(make_variable(pb, FMT(prefix, ".nonce_O"))) { this->updateAccount_P = nullptr; this->updateAccount_O = nullptr; @@ -759,8 +761,8 @@ class RingSettlementCircuit : public GadgetT // Update the operator updateAccount_O = new UpdateAccountGadget(pb, updateAccount_P->result(), operatorAccountID.bits, - {publicKey.x, publicKey.y, constants.zero, balancesRootO_before}, - {publicKey.x, publicKey.y, constants.zero, ringSettlements.back()->getNewOperatorBalancesRoot()}, + {publicKey.x, publicKey.y, nonce_O, balancesRootO_before}, + {publicKey.x, publicKey.y, nonce_O, ringSettlements.back()->getNewOperatorBalancesRoot()}, FMT(annotation_prefix, ".updateAccount_O")); updateAccount_O->generate_r1cs_constraints(); @@ -815,6 +817,7 @@ class RingSettlementCircuit : public GadgetT pb.val(publicKey.x) = block.accountUpdate_O.before.publicKey.x; pb.val(publicKey.y) = block.accountUpdate_O.before.publicKey.y; pb.val(balancesRootO_before) = block.accountUpdate_O.before.balancesRoot; + pb.val(nonce_O) = block.accountUpdate_O.before.nonce; pb.val(balancesRootP_before) = block.accountUpdate_P.before.balancesRoot; for(unsigned int i = 0; i < block.ringSettlements.size(); i++) diff --git a/Utils/Data.h b/Utils/Data.h index a038570..18fec17 100644 --- a/Utils/Data.h +++ b/Utils/Data.h @@ -204,12 +204,12 @@ class Ring Order orderA; Order orderB; - ethsnarks::FieldT minerAccountID; + ethsnarks::FieldT ringMatcherAccountID; ethsnarks::FieldT tokenID; ethsnarks::FieldT fee; ethsnarks::FieldT nonce; - Signature minerSignature; + Signature ringMatcherSignature; Signature dualAuthASignature; Signature dualAuthBSignature; }; @@ -219,12 +219,12 @@ void from_json(const json& j, Ring& ring) ring.orderA = j.at("orderA").get(); ring.orderB = j.at("orderB").get(); - ring.minerAccountID = ethsnarks::FieldT(j.at("minerAccountID")); + ring.ringMatcherAccountID = ethsnarks::FieldT(j.at("ringMatcherAccountID")); ring.tokenID = ethsnarks::FieldT(j.at("tokenID")); ring.fee = ethsnarks::FieldT(j.at("fee").get().c_str()); ring.nonce = ethsnarks::FieldT(j.at("nonce")); - ring.minerSignature = j.at("minerSignature").get(); + ring.ringMatcherSignature = j.at("ringMatcherSignature").get(); ring.dualAuthASignature = j.at("dualAuthASignature").get(); ring.dualAuthBSignature = j.at("dualAuthBSignature").get(); }