mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #269 from hermeznetwork/feature/integration12
Process withdrawals in HistoryDB, test withdrawals and vars in sync
This commit is contained in:
@@ -503,6 +503,51 @@ func (hdb *HistoryDB) addExitTree(d meddler.DB, exitTree []common.ExitInfo) erro
|
||||
)
|
||||
}
|
||||
|
||||
type exitID struct {
|
||||
batchNum int64
|
||||
idx int64
|
||||
}
|
||||
|
||||
func (hdb *HistoryDB) updateExitTree(d meddler.DB, blockNum int64,
|
||||
instantWithdrawn []exitID, delayedWithdrawRequest []exitID) error {
|
||||
// helperQueryExitIDTuples is a helper function to build the query with
|
||||
// an array of tuples in the arguments side built from []exitID
|
||||
helperQueryExitIDTuples := func(queryTmpl string, blockNum int64, exits []exitID) (string, []interface{}) {
|
||||
args := make([]interface{}, len(exits)*2+1)
|
||||
holder := ""
|
||||
args[0] = blockNum
|
||||
for i, v := range exits {
|
||||
args[1+i*2+0] = v.batchNum
|
||||
args[1+i*2+1] = v.idx
|
||||
holder += "(?, ?),"
|
||||
}
|
||||
query := fmt.Sprintf(queryTmpl, holder[:len(holder)-1])
|
||||
return hdb.db.Rebind(query), args
|
||||
}
|
||||
|
||||
if len(instantWithdrawn) > 0 {
|
||||
query, args := helperQueryExitIDTuples(
|
||||
`UPDATE exit_tree SET instant_withdrawn = ? WHERE (batch_num, account_idx) IN (%s);`,
|
||||
blockNum,
|
||||
instantWithdrawn,
|
||||
)
|
||||
if _, err := hdb.db.DB.Exec(query, args...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(delayedWithdrawRequest) > 0 {
|
||||
query, args := helperQueryExitIDTuples(
|
||||
`UPDATE exit_tree SET delayed_withdraw_request = ? WHERE (batch_num, account_idx) IN (%s);`,
|
||||
blockNum,
|
||||
delayedWithdrawRequest,
|
||||
)
|
||||
if _, err := hdb.db.DB.Exec(query, args...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddToken insert a token into the DB
|
||||
func (hdb *HistoryDB) AddToken(token *common.Token) error {
|
||||
return meddler.Insert(hdb.db, "token", token)
|
||||
@@ -1305,7 +1350,27 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Process withdrawals
|
||||
if len(blockData.Rollup.Withdrawals) > 0 {
|
||||
instantWithdrawn := []exitID{}
|
||||
delayedWithdrawRequest := []exitID{}
|
||||
for _, withdraw := range blockData.Rollup.Withdrawals {
|
||||
exitID := exitID{
|
||||
batchNum: int64(withdraw.NumExitRoot),
|
||||
idx: int64(withdraw.Idx),
|
||||
}
|
||||
if withdraw.InstantWithdraw {
|
||||
instantWithdrawn = append(instantWithdrawn, exitID)
|
||||
} else {
|
||||
delayedWithdrawRequest = append(delayedWithdrawRequest, exitID)
|
||||
}
|
||||
}
|
||||
if err := hdb.updateExitTree(txn, blockData.Block.EthBlockNum,
|
||||
instantWithdrawn, delayedWithdrawRequest); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Process WDelayer withdrawals
|
||||
|
||||
return txn.Commit()
|
||||
}
|
||||
|
||||
@@ -504,6 +504,100 @@ func TestSetInitialSCVars(t *testing.T) {
|
||||
require.Equal(t, wDelayer, dbWDelayer)
|
||||
}
|
||||
|
||||
func TestUpdateExitTree(t *testing.T) {
|
||||
test.WipeDB(historyDB.DB())
|
||||
|
||||
set := `
|
||||
Type: Blockchain
|
||||
|
||||
AddToken(1)
|
||||
|
||||
CreateAccountDeposit(1) C: 2000 // Idx=256+2=258
|
||||
CreateAccountDeposit(1) D: 500 // Idx=256+3=259
|
||||
|
||||
CreateAccountCoordinator(1) A // Idx=256+0=256
|
||||
CreateAccountCoordinator(1) B // Idx=256+1=257
|
||||
|
||||
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{5}
|
||||
> batchL1 // forge defined L1UserTxs{5}, freeze L1UserTxs{nil}
|
||||
> block // blockNum=2
|
||||
|
||||
ForceExit(1) A: 100
|
||||
ForceExit(1) B: 80
|
||||
|
||||
Exit(1) C: 50 (200)
|
||||
Exit(1) D: 30 (200)
|
||||
|
||||
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{3}
|
||||
> batchL1 // forge L1UserTxs{3}, freeze defined L1UserTxs{nil}
|
||||
> block // blockNum=3
|
||||
|
||||
> block // blockNum=4 (empty block)
|
||||
`
|
||||
|
||||
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)
|
||||
|
||||
// Add all blocks except for the last one
|
||||
for i := range blocks[:len(blocks)-1] {
|
||||
err = historyDB.AddBlockSCData(&blocks[i])
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
// Add withdraws to the last block, and insert block into the DB
|
||||
block := &blocks[len(blocks)-1]
|
||||
require.Equal(t, int64(4), block.Block.EthBlockNum)
|
||||
block.Rollup.Withdrawals = append(block.Rollup.Withdrawals,
|
||||
common.WithdrawInfo{Idx: 256, NumExitRoot: 4, InstantWithdraw: true},
|
||||
common.WithdrawInfo{Idx: 257, NumExitRoot: 4, InstantWithdraw: false},
|
||||
common.WithdrawInfo{Idx: 258, NumExitRoot: 3, InstantWithdraw: true},
|
||||
common.WithdrawInfo{Idx: 259, NumExitRoot: 3, InstantWithdraw: false},
|
||||
)
|
||||
err = historyDB.addBlock(historyDB.db, &block.Block)
|
||||
require.Nil(t, err)
|
||||
|
||||
// update exit trees in DB
|
||||
instantWithdrawn := []exitID{}
|
||||
delayedWithdrawRequest := []exitID{}
|
||||
for _, withdraw := range block.Rollup.Withdrawals {
|
||||
exitID := exitID{
|
||||
batchNum: int64(withdraw.NumExitRoot),
|
||||
idx: int64(withdraw.Idx),
|
||||
}
|
||||
if withdraw.InstantWithdraw {
|
||||
instantWithdrawn = append(instantWithdrawn, exitID)
|
||||
} else {
|
||||
delayedWithdrawRequest = append(delayedWithdrawRequest, exitID)
|
||||
}
|
||||
}
|
||||
err = historyDB.updateExitTree(historyDB.db, block.Block.EthBlockNum, instantWithdrawn, delayedWithdrawRequest)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Check that exits in DB match with the expected values
|
||||
dbExits, err := historyDB.GetAllExits()
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 4, len(dbExits))
|
||||
dbExitsByIdx := make(map[common.Idx]common.ExitInfo)
|
||||
for _, dbExit := range dbExits {
|
||||
dbExitsByIdx[dbExit.AccountIdx] = dbExit
|
||||
}
|
||||
for _, withdraw := range block.Rollup.Withdrawals {
|
||||
assert.Equal(t, withdraw.NumExitRoot, dbExitsByIdx[withdraw.Idx].BatchNum)
|
||||
if withdraw.InstantWithdraw {
|
||||
assert.Equal(t, &block.Block.EthBlockNum, dbExitsByIdx[withdraw.Idx].InstantWithdrawn)
|
||||
} else {
|
||||
assert.Equal(t, &block.Block.EthBlockNum, dbExitsByIdx[withdraw.Idx].DelayedWithdrawRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setTestBlocks WARNING: this will delete the blocks and recreate them
|
||||
func setTestBlocks(from, to int64) []common.Block {
|
||||
test.WipeDB(historyDB.DB())
|
||||
|
||||
Reference in New Issue
Block a user