Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 103 additions & 75 deletions indexer/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,20 +193,10 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {

const insertDepositStatement = `
INSERT INTO deposits
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, l1_block_hash, data)
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, block_hash, data)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
`

const insertWithdrawalStatement = `
INSERT INTO withdrawals
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, l1_block_hash, data)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
ON CONFLICT (tx_hash)
DO UPDATE SET l1_block_hash = $9;
`

return txn(d.db, func(tx *sql.Tx) error {
_, err := tx.Exec(
insertBlockStatement,
Expand Down Expand Up @@ -242,29 +232,6 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
}
}

if len(block.Withdrawals) == 0 {
return nil
}

for _, withdrawal := range block.Withdrawals {
_, err = tx.Exec(
insertWithdrawalStatement,
NewGUID(),
withdrawal.FromAddress.String(),
withdrawal.ToAddress.String(),
withdrawal.L1Token.String(),
withdrawal.L2Token.String(),
withdrawal.Amount.String(),
withdrawal.TxHash.String(),
withdrawal.LogIndex,
block.Hash.String(),
withdrawal.Data,
)
if err != nil {
return err
}
}

return nil
})
}
Expand All @@ -282,9 +249,9 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {

const insertWithdrawalStatement = `
INSERT INTO withdrawals
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, l2_block_hash, data)
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, block_hash, data, br_withdrawal_hash)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
`
return txn(d.db, func(tx *sql.Tx) error {
_, err := tx.Exec(
Expand Down Expand Up @@ -315,6 +282,37 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
withdrawal.LogIndex,
block.Hash.String(),
withdrawal.Data,
nullableHash(withdrawal.BedrockHash),
)
if err != nil {
return err
}
}

return nil
})
}

// AddStateBatch inserts the state batches into the known state batches
// database.
func (d *Database) AddStateBatch(batches []StateBatch) error {
const insertStateBatchStatement = `
INSERT INTO state_batches
(index, root, size, prev_total, extra_data, block_hash)
VALUES
($1, $2, $3, $4, $5, $6)
`

return txn(d.db, func(tx *sql.Tx) error {
for _, sb := range batches {
_, err := tx.Exec(
insertStateBatchStatement,
sb.Index.Uint64(),
sb.Root.String(),
sb.Size.Uint64(),
sb.PrevTotal.Uint64(),
sb.ExtraData,
sb.BlockHash.String(),
)
if err != nil {
return err
Expand All @@ -336,7 +334,7 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
l1_tokens.name, l1_tokens.symbol, l1_tokens.decimals,
l1_blocks.number, l1_blocks.timestamp
FROM deposits
INNER JOIN l1_blocks ON deposits.l1_block_hash=l1_blocks.hash
INNER JOIN l1_blocks ON deposits.block_hash=l1_blocks.hash
INNER JOIN l1_tokens ON deposits.l1_token=l1_tokens.address
WHERE deposits.from_address = $1 ORDER BY l1_blocks.timestamp LIMIT $2 OFFSET $3;
`
Expand Down Expand Up @@ -375,7 +373,7 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
SELECT
count(*)
FROM deposits
INNER JOIN l1_blocks ON deposits.l1_block_hash=l1_blocks.hash
INNER JOIN l1_blocks ON deposits.block_hash=l1_blocks.hash
INNER JOIN l1_tokens ON deposits.l1_token=l1_tokens.address
WHERE deposits.from_address = $1;
`
Expand All @@ -401,68 +399,79 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
}, nil
}

// GetWithdrawalStatus returns the finalization status corresponding to the
// given withdrawal transaction hash.
func (d *Database) GetWithdrawalStatus(hash common.Hash) (*WithdrawalJSON, error) {
const selectWithdrawalStatement = `
// GetWithdrawalBatch returns the StateBatch corresponding to the given
// withdrawal transaction hash.
func (d *Database) GetWithdrawalBatch(hash common.Hash) (*StateBatchJSON, error) {
const selectWithdrawalBatchStatement = `
SELECT
withdrawals.guid, withdrawals.from_address, withdrawals.to_address,
withdrawals.amount, withdrawals.tx_hash, withdrawals.data,
withdrawals.l1_token, withdrawals.l2_token,
l2_tokens.name, l2_tokens.symbol, l2_tokens.decimals,
l1_blocks.number, l1_blocks.timestamp,
l2_blocks.number, l2_blocks.timestamp
FROM withdrawals
INNER JOIN l1_blocks ON withdrawals.l1_block_hash=l1_blocks.hash
INNER JOIN l2_blocks ON withdrawals.l2_block_hash=l2_blocks.hash
INNER JOIN l2_tokens ON withdrawals.l2_token=l2_tokens.address
WHERE withdrawals.tx_hash = $1;
state_batches.index, state_batches.root, state_batches.size, state_batches.prev_total, state_batches.extra_data, state_batches.block_hash,
l1_blocks.number, l1_blocks.timestamp
FROM state_batches
INNER JOIN l1_blocks ON state_batches.block_hash = l1_blocks.hash
WHERE size + prev_total >= (
SELECT
number
FROM
withdrawals
INNER JOIN l2_blocks ON withdrawals.block_hash = l2_blocks.hash where tx_hash=$1
) ORDER BY "index" LIMIT 1;
`

var withdrawal *WithdrawalJSON
var batch *StateBatchJSON
err := txn(d.db, func(tx *sql.Tx) error {
row := tx.QueryRow(selectWithdrawalStatement, hash.String())
row := tx.QueryRow(selectWithdrawalBatchStatement, hash.String())
if row.Err() != nil {
return row.Err()
}

var l2Token Token
if err := row.Scan(
&withdrawal.GUID, &withdrawal.FromAddress, &withdrawal.ToAddress,
&withdrawal.Amount, &withdrawal.TxHash, &withdrawal.Data,
&withdrawal.L1Token, &l2Token.Address,
&l2Token.Name, &l2Token.Symbol, &l2Token.Decimals,
&withdrawal.L1BlockNumber, &withdrawal.L1BlockTimestamp,
&withdrawal.L2BlockNumber, &withdrawal.L2BlockTimestamp,
); err != nil {
var index, size, prevTotal, blockNumber, blockTimestamp uint64
var root, blockHash string
var extraData []byte
err := row.Scan(&index, &root, &size, &prevTotal, &extraData, &blockHash,
&blockNumber, &blockTimestamp)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
batch = nil
return nil
}
return err
}
withdrawal.L2Token = &l2Token

batch = &StateBatchJSON{
Index: index,
Root: root,
Size: size,
PrevTotal: prevTotal,
ExtraData: extraData,
BlockHash: blockHash,
BlockNumber: blockNumber,
BlockTimestamp: blockTimestamp,
}

return nil
})
if err != nil {
return nil, err
}

return withdrawal, nil
return batch, nil
}

// GetWithdrawalsByAddress returns the list of Withdrawals indexed for the given
// address paginated by the given params.
func (d *Database) GetWithdrawalsByAddress(address common.Address, page PaginationParam) (*PaginatedWithdrawals, error) {
const selectWithdrawalsStatement = `
selectWithdrawalsStatement := fmt.Sprintf(`
SELECT
withdrawals.guid, withdrawals.from_address, withdrawals.to_address,
withdrawals.amount, withdrawals.tx_hash, withdrawals.data,
withdrawals.l1_token, withdrawals.l2_token,
l2_tokens.name, l2_tokens.symbol, l2_tokens.decimals,
l2_blocks.number, l2_blocks.timestamp
l2_blocks.number, l2_blocks.timestamp, withdrawals.br_withdrawal_hash
FROM withdrawals
INNER JOIN l2_blocks ON withdrawals.l2_block_hash=l2_blocks.hash
INNER JOIN l2_blocks ON withdrawals.block_hash=l2_blocks.hash
INNER JOIN l2_tokens ON withdrawals.l2_token=l2_tokens.address
WHERE withdrawals.from_address = $1 ORDER BY l2_blocks.timestamp LIMIT $2 OFFSET $3;
`
WHERE withdrawals.from_address = $1 %s ORDER BY l2_blocks.timestamp LIMIT $2 OFFSET $3;
`, FinalizationStateAny.SQL())
var withdrawals []WithdrawalJSON

err := txn(d.db, func(tx *sql.Tx) error {
Expand All @@ -475,16 +484,21 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
for rows.Next() {
var withdrawal WithdrawalJSON
var l2Token Token
var wdHash sql.NullString
if err := rows.Scan(
&withdrawal.GUID, &withdrawal.FromAddress, &withdrawal.ToAddress,
&withdrawal.Amount, &withdrawal.TxHash, &withdrawal.Data,
&withdrawal.L1Token, &l2Token.Address,
&l2Token.Name, &l2Token.Symbol, &l2Token.Decimals,
&withdrawal.L2BlockNumber, &withdrawal.L2BlockTimestamp,
&withdrawal.BlockNumber, &withdrawal.BlockTimestamp,
&wdHash,
); err != nil {
return err
}
withdrawal.L2Token = &l2Token
if wdHash.Valid {
withdrawal.BedrockWithdrawalHash = &wdHash.String
}
withdrawals = append(withdrawals, withdrawal)
}

Expand All @@ -495,11 +509,16 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
return nil, err
}

for i := range withdrawals {
batch, _ := d.GetWithdrawalBatch(common.HexToHash(withdrawals[i].TxHash))
withdrawals[i].Batch = batch
}

const selectWithdrawalCountStatement = `
SELECT
count(*)
FROM withdrawals
INNER JOIN l2_blocks ON withdrawals.l2_block_hash=l2_blocks.hash
INNER JOIN l2_blocks ON withdrawals.block_hash=l2_blocks.hash
INNER JOIN l2_tokens ON withdrawals.l2_token=l2_tokens.address
WHERE withdrawals.from_address = $1;
`
Expand Down Expand Up @@ -647,9 +666,9 @@ func (d *Database) GetIndexedL1BlockByHash(hash common.Hash) (*IndexedL1Block, e
}

const getAirdropQuery = `
SELECT
SELECT
address, voter_amount, multisig_signer_amount, gitcoin_amount,
active_bridged_amount, op_user_amount, op_repeat_user_amount,
active_bridged_amount, op_user_amount, op_repeat_user_amount,
bonus_amount, total_amount
FROM airdrops
WHERE address = $1
Expand Down Expand Up @@ -681,3 +700,12 @@ func (d *Database) GetAirdrop(address common.Address) (*Airdrop, error) {
}
return airdrop, nil
}

func nullableHash(in *common.Hash) *string {
if in == nil {
return nil
}

out := in.String()
return &out
}
6 changes: 4 additions & 2 deletions indexer/db/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package db

import "github.com/ethereum/go-ethereum/common"

var ETHL1Address common.Address

// ETHL1Token is a placeholder token for differentiating ETH transactions from
// ERC20 transactions on L1.
var ETHL1Token = &Token{
Address: "0x0000000000000000000000000000000000000000",
Address: ETHL1Address.String(),
Name: "Ethereum",
Symbol: "ETH",
Decimals: 18,
Expand All @@ -18,7 +20,7 @@ var ETHL2Address = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD00
// ETHL2Token is a placeholder token for differentiating ETH transactions from
// ERC20 transactions on L2.
var ETHL2Token = &Token{
Address: "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000",
Address: ETHL2Address.String(),
Name: "Ethereum",
Symbol: "ETH",
Decimals: 18,
Expand Down
12 changes: 5 additions & 7 deletions indexer/db/l1block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import (

// IndexedL1Block contains the L1 block including the deposits in it.
type IndexedL1Block struct {
Hash common.Hash
ParentHash common.Hash
Number uint64
Timestamp uint64
Deposits []Deposit
Withdrawals []Withdrawal
Hash common.Hash
ParentHash common.Hash
Number uint64
Timestamp uint64
Deposits []Deposit
}

// String returns the block hash for the indexed l1 block.
Expand All @@ -25,7 +24,6 @@ type IndexedL2Block struct {
ParentHash common.Hash
Number uint64
Timestamp uint64
Deposits []Deposit
Withdrawals []Withdrawal
}

Expand Down
Loading