Browse Source

Merge pull request #316 from hermeznetwork/feature/set-effectives

Set EffectiveAmount and EffectiveLoadAmount of forged L1UserTxs
feature/sql-semaphore1
a_bennassar 4 years ago
committed by GitHub
parent
commit
7155743820
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 155 additions and 9 deletions
  1. +2
    -2
      common/batch.go
  2. +0
    -2
      common/block.go
  3. +55
    -3
      db/historydb/historydb.go
  4. +66
    -0
      db/historydb/historydb_test.go
  5. +2
    -2
      db/l2db/l2db.go
  6. +30
    -0
      test/til/txs.go

+ 2
- 2
common/batch.go

@ -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

+ 0
- 2
common/block.go

@ -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
} }

+ 55
- 3
db/historydb/historydb.go

@ -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

+ 66
- 0
db/historydb/historydb_test.go

@ -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())

+ 2
- 2
db/l2db/l2db.go

@ -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())
} }

+ 30
- 0
test/til/txs.go

@ -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

Loading…
Cancel
Save