@ -503,48 +503,72 @@ 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 += "(?, ?),"
func ( hdb * HistoryDB ) updateExitTree ( d sqlx . Ext , blockNum int64 ,
rollupWithdrawals [ ] common . WithdrawInfo , wDelayerWithdrawals [ ] common . WDelayerTransfer ) error {
type withdrawal struct {
BatchNum int64 ` db:"batch_num" `
AccountIdx int64 ` db:"account_idx" `
InstantWithdrawn * int64 ` db:"instant_withdrawn" `
DelayedWithdrawRequest * int64 ` db:"delayed_withdraw_request" `
DelayedWithdrawn * int64 ` db:"delayed_withdrawn" `
Owner * ethCommon . Address ` db:"owner" `
Token * ethCommon . Address ` db:"token" `
}
withdrawals := make ( [ ] withdrawal , len ( rollupWithdrawals ) + len ( wDelayerWithdrawals ) )
for i := range rollupWithdrawals {
info := & rollupWithdrawals [ i ]
withdrawals [ i ] = withdrawal {
BatchNum : int64 ( info . NumExitRoot ) ,
AccountIdx : int64 ( info . Idx ) ,
}
if info . InstantWithdraw {
withdrawals [ i ] . InstantWithdrawn = & blockNum
} else {
withdrawals [ i ] . DelayedWithdrawRequest = & blockNum
withdrawals [ i ] . Owner = & info . Owner
withdrawals [ i ] . Token = & info . Token
}
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
for i := range wDelayerWithdrawals {
info := & wDelayerWithdrawals [ i ]
withdrawals [ len ( rollupWithdrawals ) + i ] = withdrawal {
DelayedWithdrawn : & blockNum ,
Owner : & info . Owner ,
Token : & info . Token ,
}
}
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 {
// In VALUES we set an initial row of NULLs to set the types of each
// variable passed as argument
query := `
UPDATE exit_tree e SET
instant_withdrawn = d . instant_withdrawn ,
delayed_withdraw_request = CASE
WHEN e . delayed_withdraw_request IS NOT NULL THEN e . delayed_withdraw_request
ELSE d . delayed_withdraw_request
END ,
delayed_withdrawn = d . delayed_withdrawn ,
owner = d . owner ,
token = d . token
FROM ( VALUES
( NULL : : : : BIGINT , NULL : : : : BIGINT , NULL : : : : BIGINT , NULL : : : : BIGINT , NULL : : : : BIGINT , NULL : : : : BYTEA , NULL : : : : BYTEA ) ,
( : batch_num ,
: account_idx ,
: instant_withdrawn ,
: delayed_withdraw_request ,
: delayed_withdrawn ,
: owner ,
: token )
) as d ( batch_num , account_idx , instant_withdrawn , delayed_withdraw_request , delayed_withdrawn , owner , token )
WHERE
( d . batch_num IS NOT NULL AND e . batch_num = d . batch_num AND e . account_idx = d . account_idx ) OR
( d . delayed_withdrawn IS NOT NULL AND e . delayed_withdrawn IS NULL AND e . owner = d . owner AND e . token = d . token )
`
if len ( withdrawals ) > 0 {
if _ , err := sqlx . NamedQuery ( d , query , withdrawals ) ; err != nil {
return err
}
}
return nil
}
@ -1210,7 +1234,7 @@ func (hdb *HistoryDB) setWDelayerVars(d meddler.DB, wDelayer *common.WDelayerVar
// exist in the smart contracts.
func ( hdb * HistoryDB ) SetInitialSCVars ( rollup * common . RollupVariables ,
auction * common . AuctionVariables , wDelayer * common . WDelayerVariables ) error {
txn , err := hdb . db . Begin ( )
txn , err := hdb . db . Beginx ( )
if err != nil {
return err
}
@ -1242,7 +1266,7 @@ func (hdb *HistoryDB) SetInitialSCVars(rollup *common.RollupVariables,
// the pagination system of the API/DB depends on this. Within blocks, all
// items should also be in the correct order (Accounts, Tokens, Txs, etc.)
func ( hdb * HistoryDB ) AddBlockSCData ( blockData * common . BlockData ) ( err error ) {
txn , err := hdb . db . Begin ( )
txn , err := hdb . db . Beginx ( )
if err != nil {
return err
}
@ -1340,28 +1364,11 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
}
}
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
}
if err := hdb . updateExitTree ( txn , blockData . Block . EthBlockNum ,
blockData . Rollup . Withdrawals , blockData . WDelayer . Withdrawals ) ; err != nil {
return err
}
// TODO: Process WDelayer withdrawals
return txn . Commit ( )
}