Commit 9e1b6fe8 authored by clabby's avatar clabby

Two step withdrawal indexer updates

parent c129ec6a
......@@ -198,7 +198,12 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
`
const updateWithdrawalStatement = `
const updateProvenWithdrawalStatement = `
UPDATE withdrawals SET (br_withdrawal_proven_tx_hash, br_withdrawal_proven_log_index) = ($1, $2)
WHERE br_withdrawal_hash = $3
`
const updateFinalizedWithdrawalStatement = `
UPDATE withdrawals SET (br_withdrawal_finalized_tx_hash, br_withdrawal_finalized_log_index, br_withdrawal_finalized_success) = ($1, $2, $3)
WHERE br_withdrawal_hash = $4
`
......@@ -236,10 +241,24 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
}
}
if len(block.ProvenWithdrawals) > 0 {
for _, wd := range block.ProvenWithdrawals {
_, err = tx.Exec(
updateProvenWithdrawalStatement,
wd.TxHash.String(),
wd.LogIndex,
wd.WithdrawalHash.String(),
)
if err != nil {
return err
}
}
}
if len(block.FinalizedWithdrawals) > 0 {
for _, wd := range block.FinalizedWithdrawals {
_, err = tx.Exec(
updateWithdrawalStatement,
updateFinalizedWithdrawalStatement,
wd.TxHash.String(),
wd.LogIndex,
wd.Success,
......@@ -486,6 +505,7 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
withdrawals.l1_token, withdrawals.l2_token,
l2_tokens.name, l2_tokens.symbol, l2_tokens.decimals,
l2_blocks.number, l2_blocks.timestamp, withdrawals.br_withdrawal_hash,
withdrawals.br_withdrawal_proven_tx_hash, withdrawals.br_withdrawal_proven_log_index,
withdrawals.br_withdrawal_finalized_tx_hash, withdrawals.br_withdrawal_finalized_log_index,
withdrawals.br_withdrawal_finalized_success
FROM withdrawals
......@@ -506,6 +526,8 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
var withdrawal WithdrawalJSON
var l2Token Token
var wdHash sql.NullString
var proveTxHash sql.NullString
var proveLogIndex sql.NullInt32
var finTxHash sql.NullString
var finLogIndex sql.NullInt32
var finSuccess sql.NullBool
......@@ -515,7 +537,8 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
&withdrawal.L1Token, &l2Token.Address,
&l2Token.Name, &l2Token.Symbol, &l2Token.Decimals,
&withdrawal.BlockNumber, &withdrawal.BlockTimestamp,
&wdHash, &finTxHash, &finLogIndex, &finSuccess,
&wdHash, &proveTxHash, &proveLogIndex,
&finTxHash, &finLogIndex, &finSuccess,
); err != nil {
return err
}
......@@ -523,6 +546,13 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
if wdHash.Valid {
withdrawal.BedrockWithdrawalHash = &wdHash.String
}
if proveTxHash.Valid {
withdrawal.BedrockProvenTxHash = &proveTxHash.String
}
if proveLogIndex.Valid {
idx := int(proveLogIndex.Int32)
withdrawal.BedrockProvenLogIndex = &idx
}
if finTxHash.Valid {
withdrawal.BedrockFinalizedTxHash = &finTxHash.String
}
......
......@@ -11,6 +11,7 @@ type IndexedL1Block struct {
Number uint64
Timestamp uint64
Deposits []Deposit
ProvenWithdrawals []ProvenWithdrawal
FinalizedWithdrawals []FinalizedWithdrawal
}
......
......@@ -124,6 +124,8 @@ CREATE TABLE IF NOT EXISTS airdrops (
const updateWithdrawalsTable = `
ALTER TABLE withdrawals ADD COLUMN IF NOT EXISTS br_withdrawal_hash VARCHAR NULL;
ALTER TABLE withdrawals ADD COLUMN IF NOT EXISTS br_withdrawal_proven_tx_hash VARCHAR NULL;
ALTER TABLE withdrawals ADD COLUMN IF NOT EXISTS br_withdrawal_proven_log_index INTEGER NULL;
ALTER TABLE withdrawals ADD COLUMN IF NOT EXISTS br_withdrawal_finalized_tx_hash VARCHAR NULL;
ALTER TABLE withdrawals ADD COLUMN IF NOT EXISTS br_withdrawal_finalized_log_index INTEGER NULL;
ALTER TABLE withdrawals ADD COLUMN IF NOT EXISTS br_withdrawal_finalized_success BOOLEAN NULL;
......
......@@ -40,6 +40,8 @@ type WithdrawalJSON struct {
TxHash string `json:"transactionHash"`
Batch *StateBatchJSON `json:"batch"`
BedrockWithdrawalHash *string `json:"bedrockWithdrawalHash"`
BedrockProvenTxHash *string `json:"bedrockProvenTxHash"`
BedrockProvenLogIndex *int `json:"bedrockProvenLogIndex"`
BedrockFinalizedTxHash *string `json:"bedrockFinalizedTxHash"`
BedrockFinalizedLogIndex *int `json:"bedrockFinalizedLogIndex"`
BedrockFinalizedSuccess *bool `json:"bedrockFinalizedSuccess"`
......@@ -75,6 +77,14 @@ func (f FinalizationState) SQL() string {
return ""
}
type ProvenWithdrawal struct {
From common.Address
To common.Address
WithdrawalHash common.Hash
TxHash common.Hash
LogIndex uint
}
type FinalizedWithdrawal struct {
WithdrawalHash common.Hash
TxHash common.Hash
......
......@@ -21,8 +21,12 @@ type DepositsMap map[common.Hash][]db.Deposit
// on block hashes.
type InitiatedWithdrawalMap map[common.Hash][]db.Withdrawal
// ProvenWithdrawalsMap is a collection of proven withdrawal
// objects keyed on block hashses
type ProvenWithdrawalsMap map[common.Hash][]db.ProvenWithdrawal
// FinalizedWithdrawalsMap is a collection of finalized withdrawal
// objected keyed on block hashes.
// objects keyed on block hashes.
type FinalizedWithdrawalsMap map[common.Hash][]db.FinalizedWithdrawal
type Bridge interface {
......
......@@ -29,6 +29,40 @@ func (p *Portal) Address() common.Address {
return p.address
}
func (p *Portal) GetProvenWithdrawalsByBlockRange(ctx context.Context, start, end uint64) (ProvenWithdrawalsMap, error) {
wdsByBlockHash := make(ProvenWithdrawalsMap)
opts := &bind.FilterOpts{
Context: ctx,
Start: start,
End: &end,
}
var iter *bindings.OptimismPortalWithdrawalProvenIterator
err := backoff.Do(3, backoff.Exponential(), func() error {
var err error
iter, err = p.contract.FilterWithdrawalProven(opts, nil, nil, nil)
return err
})
if err != nil {
return nil, err
}
defer iter.Close()
for iter.Next() {
wdsByBlockHash[iter.Event.Raw.BlockHash] = append(
wdsByBlockHash[iter.Event.Raw.BlockHash], db.ProvenWithdrawal{
WithdrawalHash: iter.Event.WithdrawalHash,
From: iter.Event.From,
To: iter.Event.To,
TxHash: iter.Event.Raw.TxHash,
LogIndex: iter.Event.Raw.Index,
},
)
}
return wdsByBlockHash, iter.Error()
}
func (p *Portal) GetFinalizedWithdrawalsByBlockRange(ctx context.Context, start, end uint64) (FinalizedWithdrawalsMap, error) {
wdsByBlockHash := make(FinalizedWithdrawalsMap)
opts := &bind.FilterOpts{
......
......@@ -246,6 +246,7 @@ func (s *Service) Update(newHeader *types.Header) error {
}()
bridgeDepositsCh := make(chan bridge.DepositsMap, len(s.bridges))
provenWithdrawalsCh := make(chan bridge.ProvenWithdrawalsMap, 1)
finalizedWithdrawalsCh := make(chan bridge.FinalizedWithdrawalsMap, 1)
errCh := make(chan error, len(s.bridges)+1)
......@@ -259,6 +260,14 @@ func (s *Service) Update(newHeader *types.Header) error {
bridgeDepositsCh <- deposits
}(bridgeImpl)
}
go func() {
provenWithdrawals, err := s.portal.GetProvenWithdrawalsByBlockRange(s.ctx, startHeight, endHeight)
if err != nil {
errCh <- err
return
}
provenWithdrawalsCh <- provenWithdrawals
}()
go func() {
finalizedWithdrawals, err := s.portal.GetFinalizedWithdrawalsByBlockRange(s.ctx, startHeight, endHeight)
if err != nil {
......@@ -291,6 +300,7 @@ func (s *Service) Update(newHeader *types.Header) error {
}
}
provenWithdrawalsByBlockHash := <-provenWithdrawalsCh
finalizedWithdrawalsByBlockHash := <-finalizedWithdrawalsCh
var stateBatches map[common.Hash][]db.StateBatch
......@@ -307,11 +317,12 @@ func (s *Service) Update(newHeader *types.Header) error {
number := header.Number.Uint64()
deposits := depositsByBlockHash[blockHash]
batches := stateBatches[blockHash]
provenWds := provenWithdrawalsByBlockHash[blockHash]
finalizedWds := finalizedWithdrawalsByBlockHash[blockHash]
// Always record block data in the last block
// in the list of headers
if len(deposits) == 0 && len(batches) == 0 && len(finalizedWds) == 0 && i != len(headers)-1 {
if len(deposits) == 0 && len(batches) == 0 && len(provenWds) == 0 && len(finalizedWds) == 0 && i != len(headers)-1 {
continue
}
......@@ -321,6 +332,7 @@ func (s *Service) Update(newHeader *types.Header) error {
Number: number,
Timestamp: header.Time,
Deposits: deposits,
ProvenWithdrawals: provenWds,
FinalizedWithdrawals: finalizedWds,
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment