mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
TxSel avoid L1CoordTx for L2Tx that have a L1UserTx in the frozen queue
For the L2Txs of TransferToEthAddr & TransferToBJJ for a not-yet existing accounts, in the TxSelector check if L2Tx receiver account will be created by a L1UserFrozenTxs (in the next batch, the current frozen queue). In that case, the L2Tx will be discarded at the current batch, even if there is an AccountCreationAuth for the account, as there is a L1UserTx in the frozen queue that will create the receiver Account. The L2Tx is discarded to avoid the Coordinator creating a new L1CoordinatorTx to create the receiver account, which will be also created in the next batch from the L1UserFrozenTx, ending with the user having 2 different accounts for the same TokenID. The double account creation is supported by the Hermez zkRollup specification, but it was decided to mitigate it at the TxSelector level for the explained cases.
This commit is contained in:
@@ -751,6 +751,24 @@ func (hdb *HistoryDB) GetUnforgedL1UserTxs(toForgeL1TxsNum int64) ([]common.L1Tx
|
||||
return db.SlicePtrsToSlice(txs).([]common.L1Tx), tracerr.Wrap(err)
|
||||
}
|
||||
|
||||
// GetUnforgedL1UserFutureTxs gets L1 User Txs to be forged after the L1Batch
|
||||
// with toForgeL1TxsNum (in one of the future batches, not in the next one).
|
||||
func (hdb *HistoryDB) GetUnforgedL1UserFutureTxs(toForgeL1TxsNum int64) ([]common.L1Tx, error) {
|
||||
var txs []*common.L1Tx
|
||||
err := meddler.QueryAll(
|
||||
hdb.dbRead, &txs, // only L1 user txs can have batch_num set to null
|
||||
`SELECT tx.id, tx.to_forge_l1_txs_num, tx.position, tx.user_origin,
|
||||
tx.from_idx, tx.from_eth_addr, tx.from_bjj, tx.to_idx, tx.token_id,
|
||||
tx.amount, NULL AS effective_amount,
|
||||
tx.deposit_amount, NULL AS effective_deposit_amount,
|
||||
tx.eth_block_num, tx.type, tx.batch_num
|
||||
FROM tx WHERE batch_num IS NULL AND to_forge_l1_txs_num > $1
|
||||
ORDER BY position;`,
|
||||
toForgeL1TxsNum,
|
||||
)
|
||||
return db.SlicePtrsToSlice(txs).([]common.L1Tx), tracerr.Wrap(err)
|
||||
}
|
||||
|
||||
// GetUnforgedL1UserTxsCount returns the count of unforged L1Txs (either in
|
||||
// open or frozen queues that are not yet forged)
|
||||
func (hdb *HistoryDB) GetUnforgedL1UserTxsCount() (int, error) {
|
||||
|
||||
@@ -699,34 +699,55 @@ func TestGetUnforgedL1UserTxs(t *testing.T) {
|
||||
CreateAccountDeposit(1) B: 5
|
||||
CreateAccountDeposit(1) C: 5
|
||||
CreateAccountDeposit(1) D: 5
|
||||
|
||||
> block
|
||||
|
||||
> batchL1
|
||||
> block
|
||||
|
||||
CreateAccountDeposit(1) E: 5
|
||||
CreateAccountDeposit(1) F: 5
|
||||
> block
|
||||
|
||||
`
|
||||
tc := til.NewContext(uint16(0), 128)
|
||||
blocks, err := tc.GenerateBlocks(set)
|
||||
require.NoError(t, err)
|
||||
// Sanity check
|
||||
require.Equal(t, 1, len(blocks))
|
||||
require.Equal(t, 3, len(blocks))
|
||||
require.Equal(t, 5, len(blocks[0].Rollup.L1UserTxs))
|
||||
|
||||
toForgeL1TxsNum := int64(1)
|
||||
|
||||
for i := range blocks {
|
||||
err = historyDB.AddBlockSCData(&blocks[i])
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
l1UserTxs, err := historyDB.GetUnforgedL1UserTxs(toForgeL1TxsNum)
|
||||
l1UserTxs, err := historyDB.GetUnforgedL1UserFutureTxs(0)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 7, len(l1UserTxs))
|
||||
|
||||
l1UserTxs, err = historyDB.GetUnforgedL1UserTxs(1)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, len(l1UserTxs))
|
||||
assert.Equal(t, blocks[0].Rollup.L1UserTxs, l1UserTxs)
|
||||
|
||||
l1UserTxs, err = historyDB.GetUnforgedL1UserFutureTxs(1)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, len(l1UserTxs))
|
||||
|
||||
count, err := historyDB.GetUnforgedL1UserTxsCount()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, count)
|
||||
assert.Equal(t, 7, count)
|
||||
|
||||
l1UserTxs, err = historyDB.GetUnforgedL1UserTxs(2)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, len(l1UserTxs))
|
||||
|
||||
l1UserTxs, err = historyDB.GetUnforgedL1UserFutureTxs(2)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(l1UserTxs))
|
||||
|
||||
// No l1UserTxs for this toForgeL1TxsNum
|
||||
l1UserTxs, err = historyDB.GetUnforgedL1UserTxs(2)
|
||||
l1UserTxs, err = historyDB.GetUnforgedL1UserTxs(3)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(l1UserTxs))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user