mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
Set EffectiveAmount and EffectiveLoadAmount of forged L1UserTxs
This commit is contained in:
@@ -53,9 +53,9 @@ func BatchNumFromBytes(b []byte) (BatchNum, error) {
|
|||||||
|
|
||||||
// BatchData contains the information of a Batch
|
// BatchData contains the information of a Batch
|
||||||
type BatchData struct {
|
type BatchData struct {
|
||||||
// L1UserTxs that were forged in the batch
|
|
||||||
L1Batch bool // TODO: Remove once Batch.ForgeL1TxsNum is a pointer
|
L1Batch bool // TODO: Remove once Batch.ForgeL1TxsNum is a pointer
|
||||||
// L1UserTxs []common.L1Tx
|
// L1UserTxs that were forged in the batch
|
||||||
|
L1UserTxs []L1Tx
|
||||||
L1CoordinatorTxs []L1Tx
|
L1CoordinatorTxs []L1Tx
|
||||||
L2Txs []L2Tx
|
L2Txs []L2Tx
|
||||||
CreatedAccounts []Account
|
CreatedAccounts []Account
|
||||||
|
|||||||
@@ -86,6 +86,4 @@ type BlockData struct {
|
|||||||
Rollup RollupData
|
Rollup RollupData
|
||||||
Auction AuctionData
|
Auction AuctionData
|
||||||
WDelayer WDelayerData
|
WDelayer WDelayerData
|
||||||
// TODO: enable when common.WithdrawalDelayerVars is Merged from Synchronizer PR
|
|
||||||
// WithdrawalDelayerVars *common.WithdrawalDelayerVars
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -567,7 +567,7 @@ func (hdb *HistoryDB) updateExitTree(d sqlx.Ext, blockNum int64,
|
|||||||
}
|
}
|
||||||
// In VALUES we set an initial row of NULLs to set the types of each
|
// In VALUES we set an initial row of NULLs to set the types of each
|
||||||
// variable passed as argument
|
// variable passed as argument
|
||||||
query := `
|
const query string = `
|
||||||
UPDATE exit_tree e SET
|
UPDATE exit_tree e SET
|
||||||
instant_withdrawn = d.instant_withdrawn,
|
instant_withdrawn = d.instant_withdrawn,
|
||||||
delayed_withdraw_request = CASE
|
delayed_withdraw_request = CASE
|
||||||
@@ -1290,7 +1290,50 @@ func (hdb *HistoryDB) SetInitialSCVars(rollup *common.RollupVariables,
|
|||||||
return tracerr.Wrap(err)
|
return tracerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return txn.Commit()
|
return tracerr.Wrap(txn.Commit())
|
||||||
|
}
|
||||||
|
|
||||||
|
// setL1UserTxEffectiveAmounts sets the EffectiveAmount and EffectiveLoadAmount
|
||||||
|
// of the given l1UserTxs (with an UPDATE)
|
||||||
|
func (hdb *HistoryDB) setL1UserTxEffectiveAmounts(d sqlx.Ext, txs []common.L1Tx) error {
|
||||||
|
type txUpdate struct {
|
||||||
|
ID common.TxID `db:"id"`
|
||||||
|
NullifiedAmount bool `db:"nullified_amount"`
|
||||||
|
NullifiedLoadAmount bool `db:"nullified_load_amount"`
|
||||||
|
}
|
||||||
|
txUpdates := make([]txUpdate, len(txs))
|
||||||
|
equal := func(a *big.Int, b *big.Int) bool {
|
||||||
|
return a.Cmp(b) == 0
|
||||||
|
}
|
||||||
|
for i := range txs {
|
||||||
|
txUpdates[i] = txUpdate{
|
||||||
|
ID: txs[i].TxID,
|
||||||
|
NullifiedAmount: !equal(txs[i].Amount, txs[i].EffectiveAmount),
|
||||||
|
NullifiedLoadAmount: !equal(txs[i].LoadAmount, txs[i].EffectiveLoadAmount),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const query string = `
|
||||||
|
UPDATE tx SET
|
||||||
|
effective_amount = CASE
|
||||||
|
WHEN tx_update.nullified_amount THEN '\x'
|
||||||
|
ELSE tx.amount
|
||||||
|
END,
|
||||||
|
effective_load_amount = CASE
|
||||||
|
WHEN tx_update.nullified_load_amount THEN '\x'
|
||||||
|
ELSE tx.load_amount
|
||||||
|
END
|
||||||
|
FROM (VALUES
|
||||||
|
(NULL::::BYTEA, NULL::::BOOL, NULL::::BOOL),
|
||||||
|
(:id, :nullified_amount, :nullified_load_amount)
|
||||||
|
) as tx_update (id, nullified_amount, nullified_load_amount)
|
||||||
|
WHERE tx.id = tx_update.id
|
||||||
|
`
|
||||||
|
if len(txs) > 0 {
|
||||||
|
if _, err := sqlx.NamedQuery(d, query, txUpdates); err != nil {
|
||||||
|
return tracerr.Wrap(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddBlockSCData stores all the information of a block retrieved by the
|
// AddBlockSCData stores all the information of a block retrieved by the
|
||||||
@@ -1364,6 +1407,15 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
// Add Batches
|
// Add Batches
|
||||||
for i := range blockData.Rollup.Batches {
|
for i := range blockData.Rollup.Batches {
|
||||||
batch := &blockData.Rollup.Batches[i]
|
batch := &blockData.Rollup.Batches[i]
|
||||||
|
|
||||||
|
// Set the EffectiveAmount and EffectiveLoadAmount of all the
|
||||||
|
// L1UserTxs that have been forged in this batch
|
||||||
|
if len(batch.L1UserTxs) > 0 {
|
||||||
|
if err = hdb.setL1UserTxEffectiveAmounts(txn, batch.L1UserTxs); err != nil {
|
||||||
|
return tracerr.Wrap(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add Batch: this will trigger an update on the DB
|
// Add Batch: this will trigger an update on the DB
|
||||||
// that will set the batch num of forged L1 txs in this batch
|
// that will set the batch num of forged L1 txs in this batch
|
||||||
if err = hdb.addBatch(txn, &batch.Batch); err != nil {
|
if err = hdb.addBatch(txn, &batch.Batch); err != nil {
|
||||||
@@ -1432,7 +1484,7 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
return tracerr.Wrap(err)
|
return tracerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return txn.Commit()
|
return tracerr.Wrap(txn.Commit())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCoordinatorAPI returns a coordinator by its bidderAddr
|
// GetCoordinatorAPI returns a coordinator by its bidderAddr
|
||||||
|
|||||||
@@ -692,6 +692,72 @@ func TestSetInitialSCVars(t *testing.T) {
|
|||||||
require.Equal(t, wDelayer, dbWDelayer)
|
require.Equal(t, wDelayer, dbWDelayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetL1UserTxEffectiveAmounts(t *testing.T) {
|
||||||
|
test.WipeDB(historyDB.DB())
|
||||||
|
|
||||||
|
set := `
|
||||||
|
Type: Blockchain
|
||||||
|
|
||||||
|
AddToken(1)
|
||||||
|
|
||||||
|
CreateAccountDeposit(1) A: 2000
|
||||||
|
CreateAccountDeposit(1) B: 500
|
||||||
|
CreateAccountDeposit(1) C: 500
|
||||||
|
|
||||||
|
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{*}
|
||||||
|
> block // blockNum=2
|
||||||
|
|
||||||
|
> batchL1 // forge defined L1UserTxs{*}
|
||||||
|
> block // blockNum=3
|
||||||
|
`
|
||||||
|
|
||||||
|
tc := til.NewContext(common.RollupConstMaxL1UserTx)
|
||||||
|
tilCfgExtra := til.ConfigExtra{
|
||||||
|
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
|
||||||
|
CoordUser: "A",
|
||||||
|
}
|
||||||
|
blocks, err := tc.GenerateBlocks(set)
|
||||||
|
require.Nil(t, err)
|
||||||
|
err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tc.FillBlocksForgedL1UserTxs(blocks)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// Add only first block so that the L1UserTxs are not marked as forged
|
||||||
|
for i := range blocks[:1] {
|
||||||
|
err = historyDB.AddBlockSCData(&blocks[i])
|
||||||
|
require.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the Effective{Amount,LoadAmount} of the L1UserTxs that are forged in the second block
|
||||||
|
l1Txs := blocks[1].Rollup.Batches[0].L1UserTxs
|
||||||
|
require.Equal(t, 3, len(l1Txs))
|
||||||
|
// Change some values to test all cases
|
||||||
|
l1Txs[1].EffectiveAmount = big.NewInt(0)
|
||||||
|
l1Txs[2].EffectiveLoadAmount = big.NewInt(0)
|
||||||
|
l1Txs[2].EffectiveAmount = big.NewInt(0)
|
||||||
|
err = historyDB.setL1UserTxEffectiveAmounts(historyDB.db, l1Txs)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dbL1Txs, err := historyDB.GetAllL1UserTxs()
|
||||||
|
require.NoError(t, err)
|
||||||
|
for _, tx := range dbL1Txs {
|
||||||
|
assert.NotNil(t, tx.EffectiveAmount)
|
||||||
|
assert.NotNil(t, tx.EffectiveLoadAmount)
|
||||||
|
switch tx.TxID {
|
||||||
|
case l1Txs[0].TxID:
|
||||||
|
assert.Equal(t, l1Txs[0].LoadAmount, tx.EffectiveLoadAmount)
|
||||||
|
assert.Equal(t, l1Txs[0].Amount, tx.EffectiveAmount)
|
||||||
|
case l1Txs[1].TxID:
|
||||||
|
assert.Equal(t, l1Txs[1].LoadAmount, tx.EffectiveLoadAmount)
|
||||||
|
assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
|
||||||
|
case l1Txs[2].TxID:
|
||||||
|
assert.Equal(t, big.NewInt(0), tx.EffectiveLoadAmount)
|
||||||
|
assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateExitTree(t *testing.T) {
|
func TestUpdateExitTree(t *testing.T) {
|
||||||
test.WipeDB(historyDB.DB())
|
test.WipeDB(historyDB.DB())
|
||||||
|
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ func (l2db *L2DB) CheckNonces(updatedAccounts []common.Account, batchNum common.
|
|||||||
return tracerr.Wrap(err)
|
return tracerr.Wrap(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return txn.Commit()
|
return tracerr.Wrap(txn.Commit())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reorg updates the state of txs that were updated in a batch that has been discarted due to a blockchain reorg.
|
// Reorg updates the state of txs that were updated in a batch that has been discarted due to a blockchain reorg.
|
||||||
@@ -312,5 +312,5 @@ func (l2db *L2DB) Purge(currentBatchNum common.BatchNum) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return tracerr.Wrap(err)
|
return tracerr.Wrap(err)
|
||||||
}
|
}
|
||||||
return txn.Commit()
|
return tracerr.Wrap(txn.Commit())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -690,6 +690,36 @@ func (tc *Context) FillBlocksL1UserTxsBatchNum(blocks []common.BlockData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FillBlocksForgedL1UserTxs fills the L1UserTxs of a batch with the L1UserTxs
|
||||||
|
// that are forged in that batch. It always sets `EffectiveAmount` = `Amount`
|
||||||
|
// and `EffectiveLoadAmount` = `LoadAmount`.
|
||||||
|
func (tc *Context) FillBlocksForgedL1UserTxs(blocks []common.BlockData) error {
|
||||||
|
for i := range blocks {
|
||||||
|
block := &blocks[i]
|
||||||
|
for j := range block.Rollup.Batches {
|
||||||
|
batch := &block.Rollup.Batches[j]
|
||||||
|
if batch.L1Batch {
|
||||||
|
batchNum := batch.Batch.BatchNum
|
||||||
|
queue := tc.Queues[int(*batch.Batch.ForgeL1TxsNum)]
|
||||||
|
batch.L1UserTxs = make([]common.L1Tx, len(queue))
|
||||||
|
for k := range queue {
|
||||||
|
tx := &batch.L1UserTxs[k]
|
||||||
|
*tx = queue[k].L1Tx
|
||||||
|
tx.EffectiveAmount = tx.Amount
|
||||||
|
tx.EffectiveLoadAmount = tx.LoadAmount
|
||||||
|
tx.BatchNum = &batchNum
|
||||||
|
_tx, err := common.NewL1Tx(tx)
|
||||||
|
if err != nil {
|
||||||
|
return tracerr.Wrap(err)
|
||||||
|
}
|
||||||
|
*tx = *_tx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// FillBlocksExtra fills extra fields not generated by til in each block, so
|
// FillBlocksExtra fills extra fields not generated by til in each block, so
|
||||||
// that the blockData is closer to what the HistoryDB stores. The filled fields are:
|
// that the blockData is closer to what the HistoryDB stores. The filled fields are:
|
||||||
// - blocks[].Rollup.Batch.EthBlockNum
|
// - blocks[].Rollup.Batch.EthBlockNum
|
||||||
|
|||||||
Reference in New Issue
Block a user