Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Offchain TX tested and some packing formats changed
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaylina committed Sep 15, 2019
1 parent e104875 commit e681a16
Show file tree
Hide file tree
Showing 15 changed files with 963 additions and 194 deletions.
3 changes: 1 addition & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ module.exports = {
"semi": [
"error",
"always"
],
"mocha/no-exclusive-tests": "error"
]
}
};
57 changes: 35 additions & 22 deletions circuits/balancesupdater.circom
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
In case of an offChan TX the system does not allow it.
It also checks overflow of < 2^126
It also checks overflow of < 2^192
*/

include "../node_modules/circomlib/circuits/bitify.circom";
Expand All @@ -19,9 +19,10 @@ template BalancesUpdater() {
signal input oldStAmountRecieiver;
signal input amount;
signal input loadAmount;
signal input maxFee;
signal input minFee;
signal input userFee;
signal input operatorsFee;
signal input onChain;
signal input nop;
signal input countersIn;
signal input countersBase;

Expand All @@ -30,41 +31,53 @@ template BalancesUpdater() {
signal output countersOut;
signal output update2;

signal limitsOk;
signal feeOk;
signal txOk;
signal feeApplies; // 1 If fee applies (offChain) 0 if not applies (onChain)
signal appliedFee; // amount of fee that needs to be discounted

component n2bSender = Num2Bits(127);
component n2bReceiver = Num2Bits(127);
signal limitsOk; // 1 if from is >0 and <2**192
signal feeOk; // If userFee > operatorFee
signal txOk; // If both are ok.

signal effectiveAmount1;
signal effectiveAmount2;
signal effectiveLoadAmount;

component n2bSender = Num2Bits(193);
component feeGE = GreaterEqThan(128);
component amountIsZero = IsZero();
component effectiveAmountIsZero = IsZero();

feeApplies <== (1-onChain)*(1-nop); // Fee applies only on onChainTx and is not a NOP

amountIsZero.in <== amount;
appliedFee <== operatorsFee*feeApplies;

// Only apply fee if amount >0
signal applyFee;
applyFee <== minFee*(1- amountIsZero.out);
effectiveLoadAmount <== loadAmount*onChain;
effectiveAmount1 <== amount*(1-nop);

n2bSender.in <== (1<<126) + oldStAmountSender + loadAmount - (amount + applyFee);
n2bReceiver.in <== oldStAmountRecieiver + amount;
// Check limits and fees on limits
n2bSender.in <== (1<<192) + oldStAmountSender + effectiveLoadAmount - effectiveAmount1 - appliedFee;

feeGE.in[0] <== maxFee;
feeGE.in[1] <== applyFee;
// Fee offered by the user must be greater that the operators demanded
feeGE.in[0] <== userFee;
feeGE.in[1] <== operatorsFee;

feeOk <== feeGE.out;
limitsOk <== (n2bSender.out[126])*(1-n2bReceiver.out[126]);
limitsOk <== n2bSender.out[192];

txOk <== feeOk * limitsOk;

// if not onChain and not txOk => error
(1-txOk)*(1-onChain) === 0;

effectiveAmount2 <== txOk*effectiveAmount1;

effectiveAmountIsZero.in <== effectiveAmount2;

// if !txOk then return 0;
newStAmountSender <== oldStAmountSender + loadAmount - (applyFee + amount)*txOk;
newStAmountReceiver <== oldStAmountRecieiver + amount*txOk
newStAmountSender <== oldStAmountSender + effectiveLoadAmount - effectiveAmount2 - appliedFee;
newStAmountReceiver <== oldStAmountRecieiver + effectiveAmount2

// Counters
countersOut <== countersIn + countersBase*(1- amountIsZero.out);
update2 <== txOk * (1 - amountIsZero.out);
countersOut <== countersIn + countersBase*feeApplies;
update2 <== 1-effectiveAmountIsZero.out;

}
55 changes: 26 additions & 29 deletions circuits/decodetx.circom
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ template DecodeTx(nLevels) {
signal input previousOnChain;
signal input oldOnChainHash;
signal input txData;
signal input rqTxHash;
signal input rqTxData;
signal input loadAmount;
signal input ethAddr;
signal input ax;
Expand All @@ -24,21 +24,21 @@ template DecodeTx(nLevels) {
signal output fromIdx; // 64 0..63
signal output toIdx; // 64 64..127
signal output amount; // 16 128..143
signal output coin; // 16 144..159
signal output nonce; // 48 160..207
signal output maxFee; // 16 208..223
signal output rqOffset; // 4 224..227
signal output onChain // 1 228
signal output newAccount // 1 229

signal output dataAvailabilityBits[nLevels*2+16+16];
signal output coin; // 32 144..175
signal output nonce; // 48 176..223
signal output userFee; // 16 224..239
signal output rqOffset; // 3 240..242
signal output onChain // 1 243
signal output newAccount // 1 244

signal output dataAvailabilityBits[nLevels*2+16];
signal output offChainHash; // For the signature
signal output newOnChainHash; // For the chained onchain

var i;
var IDEN3_ROLLUP_TX = 1625792389453394788515067275302403776356063435417596283072371667635754651289; // blake2b("IDEN3_ROLLUP_TX") % r

component n2bData = Num2Bits(230);
component n2bData = Num2Bits(245);
n2bData.in <== txData;

// from
Expand Down Expand Up @@ -77,8 +77,8 @@ template DecodeTx(nLevels) {

// coin
////////
component b2nCoin = Bits2Num(16);
for (i=0; i<16; i++) {
component b2nCoin = Bits2Num(32);
for (i=0; i<32; i++) {
b2nCoin.in[i] <== n2bData.out[144 + i];
}
b2nCoin.out ==> coin;
Expand All @@ -87,55 +87,52 @@ template DecodeTx(nLevels) {
////////
component b2nNonce = Bits2Num(48);
for (i=0; i<48; i++) {
b2nNonce.in[i] <== n2bData.out[160 + i];
b2nNonce.in[i] <== n2bData.out[176 + i];
}
b2nNonce.out ==> nonce;

// maxFee
// userFee
////////
component dfMaxFee = DecodeFloatBin();
component dfUserFee = DecodeFloatBin();
for (i=0; i<16; i++) {
dfMaxFee.in[i] <== n2bData.out[208 + i];
dfUserFee.in[i] <== n2bData.out[224 + i];
}
dfMaxFee.out ==> maxFee;
dfUserFee.out ==> userFee;

// rqOffset
////////
component b2nRqOffset = Bits2Num(4);
for (i=0; i<4; i++) {
b2nRqOffset.in[i] <== n2bData.out[224 + i];
component b2nRqOffset = Bits2Num(3);
for (i=0; i<3; i++) {
b2nRqOffset.in[i] <== n2bData.out[240 + i];
}
b2nRqOffset.out ==> rqOffset;

// onChain
////////
onChain <== n2bData.out[228];
onChain <== n2bData.out[243];

// newAccount
////////
newAccount <== n2bData.out[229];
newAccount <== n2bData.out[244];

// Data Availability bits
////////
for (i=0; i<nLevels; i++) {
dataAvailabilityBits[i] <== n2bData.out[i]*(1-onChain);
dataAvailabilityBits[nLevels - 1 - i] <== n2bData.out[i]*(1-onChain);
}
for (i=0; i<nLevels; i++) {
dataAvailabilityBits[nLevels + i] <== n2bData.out[64 + i]*(1-onChain);
}
for (i=0; i<16; i++) {
dataAvailabilityBits[nLevels*2 + i] <== n2bData.out[128 + i]*(1-onChain);
dataAvailabilityBits[nLevels + nLevels - 1 - i] <== n2bData.out[64 + i]*(1-onChain);
}
for (i=0; i<16; i++) {
dataAvailabilityBits[nLevels*2+16 + i] <== n2bData.out[144 + i]*(1-onChain);
dataAvailabilityBits[nLevels*2 + 16 -1 - i] <== n2bData.out[128 + i]*(1-onChain);
}

// offChainHash
//////
component hash1 = Poseidon(3, 6, 8, 57);
hash1.inputs[0] <== IDEN3_ROLLUP_TX;
hash1.inputs[1] <== txData;
hash1.inputs[2] <== rqTxHash;
hash1.inputs[2] <== rqTxData;

hash1.out ==> offChainHash;

Expand Down
4 changes: 2 additions & 2 deletions circuits/feeSelector.circom
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ template FeeSelector() {
signal input coin;
signal input feePlanCoin[16];
signal input feePlanFee[16];
signal output minFee;
signal output operatorsFee;
signal output countersBase;

component stp[16];
Expand All @@ -139,6 +139,6 @@ template FeeSelector() {
stp[i].feePlanFee <== feePlanFee[i];
}

minFee <== stp[15].currentFeeOut;
operatorsFee <== stp[15].currentFeeOut;
countersBase <== stp[15].counterBaseOut * stp[15].isSelectedOut;
}
38 changes: 19 additions & 19 deletions circuits/requiredtxverifier.circom
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ RqTxVerifier
└──┬─┬─┬──────┘
│ │ │
╲ │ │ │
TxHash -1 ╲ │ │ │
TxData -1 ╲ │ │ │
──────────▶ ╲▼ │ │
TxHash -2 ╲ │ │
TxData -2 ╲ │ │
──────────▶ ╲▼ │
TxHash -3 ╲ │
TxData -3 ╲ │
──────────▶ ╲▼
TxHash -4 ╲
TxData -4 ╲
──────────▶ ╲
TxHash +3 Mux3 ──────────┐
TxData +3 Mux3 ──────────┐
──────────▶ ╱ │
TxHash +2 ╱ │ ┌────────┐
TxData +2 ╱ │ ┌────────┐
──────────▶ ╱ │ │ │
TxHash +1 ╱ └─────────▶│ │
TxData +1 ╱ └─────────▶│ │
──────────▶ ╱ │ === │
0 ╱ │ │
──────────▶ ╱ ┌────────────────────▶│ │
╱ │ └────────┘
╱ │
rqHash
rqTxData
────────────────────┘
*/
Expand All @@ -39,21 +39,21 @@ include "../node_modules/circomlib/circuits/bitify.circom";
include "../node_modules/circomlib/circuits/mux3.circom";

template RequiredTxVerifier() {
signal input pastTxHash[4];
signal input futureTxHash[3];
signal input rqTxHash;
signal input pastTxData[4];
signal input futureTxData[3];
signal input rqTxData;
signal input rqTxOffset;

component mux = Mux3();

mux.c[0] <== 0;
mux.c[1] <== futureTxHash[0];
mux.c[2] <== futureTxHash[1];
mux.c[3] <== futureTxHash[2];
mux.c[4] <== pastTxHash[3];
mux.c[5] <== pastTxHash[2];
mux.c[6] <== pastTxHash[1];
mux.c[7] <== pastTxHash[0];
mux.c[1] <== futureTxData[0];
mux.c[2] <== futureTxData[1];
mux.c[3] <== futureTxData[2];
mux.c[4] <== pastTxData[3];
mux.c[5] <== pastTxData[2];
mux.c[6] <== pastTxData[1];
mux.c[7] <== pastTxData[0];

component n2b = Num2Bits(3);

Expand All @@ -62,5 +62,5 @@ template RequiredTxVerifier() {
n2b.out[1] ==> mux.s[1];
n2b.out[2] ==> mux.s[2];

mux.out === rqTxHash;
mux.out === rqTxData;
}
20 changes: 10 additions & 10 deletions circuits/rollup.circom
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ template Rollup(nTx, nLevels) {
signal output countersOut;

signal private input txData[nTx];
signal private input rqTxHash[nTx];
signal private input rqTxData[nTx];
signal private input s[nTx];
signal private input r8x[nTx];
signal private input r8y[nTx];
Expand Down Expand Up @@ -68,7 +68,7 @@ template Rollup(nTx, nLevels) {
}

var nDataAvailabilityBitsPerTx;
nDataAvailabilityBitsPerTx = (nLevels*2+16+16)
nDataAvailabilityBitsPerTx = (nLevels*2+16)
component offChainHasher = Sha256(nDataAvailabilityBitsPerTx*nTx);

component decodeTx[nTx]
Expand All @@ -86,12 +86,12 @@ template Rollup(nTx, nLevels) {
decodeTx[i].previousOnChain <== decodeTx[i-1].onChain;
}
decodeTx[i].txData <== txData[i];
decodeTx[i].rqTxHash <== rqTxHash[i];
decodeTx[i].rqTxData <== rqTxData[i];
decodeTx[i].loadAmount <== loadAmount[i];
decodeTx[i].ethAddr <== ethAddr[i];
decodeTx[i].ax <== ax[i];
decodeTx[i].ay <== ay[i];
for (j=0; j<nLevels*2+32; j++) {
for (j=0; j<nLevels*2+16; j++) {
offChainHasher.in[i*nDataAvailabilityBitsPerTx+j] <== decodeTx[i].dataAvailabilityBits[j];
}
}
Expand All @@ -110,14 +110,14 @@ template Rollup(nTx, nLevels) {
Tx[i].amount <== decodeTx[i].amount;
Tx[i].coin <== decodeTx[i].coin;
Tx[i].nonce <== decodeTx[i].nonce;
Tx[i].maxFee <== decodeTx[i].maxFee;
Tx[i].userFee <== decodeTx[i].userFee;
Tx[i].rqOffset <== decodeTx[i].rqOffset;
Tx[i].onChain <== decodeTx[i].onChain;
Tx[i].newAccount <== decodeTx[i].newAccount;

Tx[i].offChainHash <== decodeTx[i].offChainHash;

Tx[i].rqTxHash <== rqTxHash[i];
Tx[i].rqTxData <== rqTxData[i];
Tx[i].s <== s[i];
Tx[i].r8x <== r8x[i];
Tx[i].r8y <== r8y[i];
Expand Down Expand Up @@ -171,17 +171,17 @@ template Rollup(nTx, nLevels) {

for (j=0; j<4; j++) {
if (i-j-1 < -1/2) {
Tx[i].pastTxHash[j] <== decodeTx[i-j-1].offChainHash;
Tx[i].pastTxData[j] <== txData[i-j-1];
} else {
Tx[i].pastTxHash[j] <== 0;
Tx[i].pastTxData[j] <== 0;
}
}

for (j=0; j<3; j++) {
if (i+j+1 < nTx) {
Tx[i].futureTxHash[j] <== decodeTx[i+j+1].offChainHash;
Tx[i].futureTxData[j] <== txData[i+j+1];
} else {
Tx[i].futureTxHash[j] <== 0;
Tx[i].futureTxData[j] <== 0;
}
}
}
Expand Down
Loading

0 comments on commit e681a16

Please sign in to comment.