Browse Source

Update ZKInputs to incl Accumulated Fees of val 0

Fixes the case where there is a PoolTxs of type Exit with fee 0 for a
TokenID. Before this commit the Coordinator was not sending the
accumulated fee (which has value 0) to the Coordinator account for that
TokenID, with this commit the Coordinator always sends the accumulated
fee even when the value is 0 to match the hermez circom circuits
behaviour.

Also added a test to check the values and that also sends the proof to a
real proof server to check that can generate a valid proof.
feature/sql-semaphore1
arnaucube 3 years ago
parent
commit
e55ce04bbd
2 changed files with 113 additions and 29 deletions
  1. +86
    -1
      test/zkproof/flows_test.go
  2. +27
    -28
      txprocessor/txprocessor.go

+ 86
- 1
test/zkproof/flows_test.go

@ -111,7 +111,7 @@ func initTxSelector(t *testing.T, chainID uint16, hermezContractAddr ethCommon.A
return txsel, l2DB, syncStateDB
}
func TestTxSelectorBatchBuilderZKInputs(t *testing.T) {
func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
tc := til.NewContext(ChainID, common.RollupConstMaxL1UserTx)
// generate test transactions, the L1CoordinatorTxs generated by Til
// will be ignored at this test, as will be the TxSelector who
@ -253,3 +253,88 @@ func TestTxSelectorBatchBuilderZKInputs(t *testing.T) {
err = l2DBTxSel.UpdateTxsInfo(discardedL2Txs)
require.NoError(t, err)
}
// TestZKInputsExitWithFee0 checks the case where there is a PoolTxs of type
// Exit with fee 0 for a TokenID that the Coordinator does not have it
// registered yet
func TestZKInputsExitWithFee0(t *testing.T) {
tc := til.NewContext(ChainID, common.RollupConstMaxL1UserTx)
var set = `
Type: Blockchain
AddToken(1)
CreateAccountDeposit(1) A: 1000
CreateAccountDeposit(1) B: 1000
CreateAccountDeposit(1) C: 1000
> batchL1
> batchL1
CreateAccountCoordinator(1) Coord
> batch
> block
`
blocks, err := tc.GenerateBlocks(set)
require.NoError(t, err)
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
txsel, l2DBTxSel, syncStateDB := initTxSelector(t, ChainID, hermezContractAddr, tc.Users["Coord"])
bbDir, err := ioutil.TempDir("", "tmpBatchBuilderDB")
require.NoError(t, err)
bb, err := batchbuilder.NewBatchBuilder(bbDir, syncStateDB, 0, NLevels)
require.NoError(t, err)
// restart nonces of TilContext, as will be set by generating directly
// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
tc.RestartNonces()
// add tokens to HistoryDB to avoid breaking FK constrains
addTokens(t, tc, l2DBTxSel.DB())
selectionConfig := &txselector.SelectionConfig{
MaxL1UserTxs: 100,
TxProcessorConfig: txprocConfig,
}
configBatch := &batchbuilder.ConfigBatch{
TxProcessorConfig: txprocConfig,
}
// batch2
// TxSelector select the transactions for the next Batch
l1UserTxs := til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err := bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "8737171572459172806192626402462788826264011087579491137542380589998149683116", bb.LocalStateDB().MT.Root().BigInt().String())
h, err := zki.HashGlobalData()
require.NoError(t, err)
assert.Equal(t, "9971598169768987067017223790214537222850903267980994716992761290793474746117", h.String())
sendProofAndCheckResp(t, zki)
// batch3
batchPoolL2 := `
Type: PoolL2
PoolExit(1) A: 100 (0)`
l2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
require.NoError(t, err)
addL2Txs(t, l2DBTxSel, l2Txs) // Add L2s to TxSelector.L2DB
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, nil)
require.NoError(t, err)
assert.Equal(t, 1, len(coordIdxs))
assert.Equal(t, 0, len(oL1UserTxs))
assert.Equal(t, 1, len(oL1CoordTxs))
assert.Equal(t, 1, len(oL2Txs))
assert.Equal(t, 0, len(discardedL2Txs))
// BatchBuilder build Batch
zki, err = bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "18306761925365215381387147754881756804475668085493847010988306480531520370130", bb.LocalStateDB().MT.Root().BigInt().String())
h, err = zki.HashGlobalData()
require.NoError(t, err)
assert.Equal(t, "7992262236065691439683036344554725221924027193771770363772735722054938818364", h.String())
assert.Equal(t, common.EthAddrToBigInt(tc.Users["Coord"].Addr), zki.EthAddr3[0])
assert.Equal(t, "0", zki.EthAddr3[1].String())
sendProofAndCheckResp(t, zki)
}

+ 27
- 28
txprocessor/txprocessor.go

@ -360,35 +360,34 @@ func (tp *TxProcessor) ProcessTxs(coordIdxs []common.Idx, l1usertxs, l1coordinat
for _, idx := range coordIdxs {
accumulatedFee := tp.AccumulatedFees[idx]
cmp := accumulatedFee.Cmp(big.NewInt(0))
if cmp == 1 { // accumulatedFee>0
// send the fee to the Idx of the Coordinator for the TokenID
accCoord, err := tp.s.GetAccount(idx)
if err != nil {
log.Errorw("Can not distribute accumulated fees to coordinator account: No coord Idx to receive fee", "idx", idx)
return nil, tracerr.Wrap(err)
}
if tp.zki != nil {
tp.zki.TokenID3[iFee] = accCoord.TokenID.BigInt()
tp.zki.Nonce3[iFee] = accCoord.Nonce.BigInt()
coordBJJSign, coordBJJY := babyjub.UnpackSignY(accCoord.BJJ)
if coordBJJSign {
tp.zki.Sign3[iFee] = big.NewInt(1)
}
tp.zki.Ay3[iFee] = coordBJJY
tp.zki.Balance3[iFee] = accCoord.Balance
tp.zki.EthAddr3[iFee] = common.EthAddrToBigInt(accCoord.EthAddr)
}
accCoord.Balance = new(big.Int).Add(accCoord.Balance, accumulatedFee)
pFee, err := tp.s.UpdateAccount(idx, accCoord)
if err != nil {
log.Error(err)
return nil, tracerr.Wrap(err)
}
if tp.zki != nil {
tp.zki.Siblings3[iFee] = siblingsToZKInputFormat(pFee.Siblings)
tp.zki.ISStateRootFee[iFee] = tp.s.MT.Root().BigInt()
// send the fee to the Idx of the Coordinator for the TokenID
// (even if the AccumulatedFee==0, as is how the zk circuit
// works)
accCoord, err := tp.s.GetAccount(idx)
if err != nil {
log.Errorw("Can not distribute accumulated fees to coordinator account: No coord Idx to receive fee", "idx", idx)
return nil, tracerr.Wrap(err)
}
if tp.zki != nil {
tp.zki.TokenID3[iFee] = accCoord.TokenID.BigInt()
tp.zki.Nonce3[iFee] = accCoord.Nonce.BigInt()
coordBJJSign, coordBJJY := babyjub.UnpackSignY(accCoord.BJJ)
if coordBJJSign {
tp.zki.Sign3[iFee] = big.NewInt(1)
}
tp.zki.Ay3[iFee] = coordBJJY
tp.zki.Balance3[iFee] = accCoord.Balance
tp.zki.EthAddr3[iFee] = common.EthAddrToBigInt(accCoord.EthAddr)
}
accCoord.Balance = new(big.Int).Add(accCoord.Balance, accumulatedFee)
pFee, err := tp.s.UpdateAccount(idx, accCoord)
if err != nil {
log.Error(err)
return nil, tracerr.Wrap(err)
}
if tp.zki != nil {
tp.zki.Siblings3[iFee] = siblingsToZKInputFormat(pFee.Siblings)
tp.zki.ISStateRootFee[iFee] = tp.s.MT.Root().BigInt()
}
iFee++
}

Loading…
Cancel
Save