Files
scroll/database/orm/l1_block.go
2023-06-07 23:07:14 +08:00

151 lines
4.3 KiB
Go

package orm
import (
"context"
"database/sql"
"errors"
"fmt"
"strings"
"scroll-tech/common/types"
"github.com/jmoiron/sqlx"
"github.com/scroll-tech/go-ethereum/log"
)
type l1BlockOrm struct {
db *sqlx.DB
}
var _ L1BlockOrm = (*l1BlockOrm)(nil)
// NewL1BlockOrm create an l1BlockOrm instance
func NewL1BlockOrm(db *sqlx.DB) L1BlockOrm {
return &l1BlockOrm{db: db}
}
func (l *l1BlockOrm) GetL1BlockInfos(fields map[string]interface{}, args ...string) ([]*types.L1BlockInfo, error) {
query := "SELECT * FROM l1_block WHERE 1 = 1 "
for key := range fields {
query += fmt.Sprintf("AND %s=:%s ", key, key)
}
query = strings.Join(append([]string{query}, args...), " ")
query += " ORDER BY number ASC"
db := l.db
rows, err := db.NamedQuery(db.Rebind(query), fields)
if err != nil {
return nil, err
}
defer func() { _ = rows.Close() }()
var blocks []*types.L1BlockInfo
for rows.Next() {
block := &types.L1BlockInfo{}
if err = rows.StructScan(block); err != nil {
break
}
blocks = append(blocks, block)
}
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, err
}
return blocks, nil
}
func (l *l1BlockOrm) InsertL1Blocks(ctx context.Context, blocks []*types.L1BlockInfo) error {
if len(blocks) == 0 {
return nil
}
blockMaps := make([]map[string]interface{}, len(blocks))
for i, block := range blocks {
blockMaps[i] = map[string]interface{}{
"number": block.Number,
"hash": block.Hash,
"header_rlp": block.HeaderRLP,
"base_fee": block.BaseFee,
}
}
_, err := l.db.NamedExec(`INSERT INTO public.l1_block (number, hash, header_rlp, base_fee) VALUES (:number, :hash, :header_rlp, :base_fee);`, blockMaps)
if err != nil {
log.Error("failed to insert L1 Blocks", "err", err)
}
return err
}
func (l *l1BlockOrm) DeleteHeaderRLPByBlockHash(ctx context.Context, blockHash string) error {
if _, err := l.db.Exec(l.db.Rebind("update l1_block set header_rlp = ? where hash = ?;"), "", blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) UpdateImportTxHash(ctx context.Context, blockHash, txHash string) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update l1_block set import_tx_hash = ? where hash = ?;"), txHash, blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) UpdateL1BlockStatus(ctx context.Context, blockHash string, status types.L1BlockStatus) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update l1_block set block_status = ? where hash = ?;"), status, blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) UpdateL1BlockStatusAndImportTxHash(ctx context.Context, blockHash string, status types.L1BlockStatus, txHash string) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update l1_block set block_status = ?, import_tx_hash = ? where hash = ?;"), status, txHash, blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) UpdateL1OracleTxHash(ctx context.Context, blockHash, txHash string) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update l1_block set oracle_tx_hash = ? where hash = ?;"), txHash, blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) UpdateL1GasOracleStatus(ctx context.Context, blockHash string, status types.GasOracleStatus) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update l1_block set oracle_status = ? where hash = ?;"), status, blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) UpdateL1GasOracleStatusAndOracleTxHash(ctx context.Context, blockHash string, status types.GasOracleStatus, txHash string) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update l1_block set oracle_status = ?, oracle_tx_hash = ? where hash = ?;"), status, txHash, blockHash); err != nil {
return err
}
return nil
}
func (l *l1BlockOrm) GetLatestL1BlockHeight() (uint64, error) {
row := l.db.QueryRow("SELECT COALESCE(MAX(number), 0) FROM l1_block;")
var height uint64
if err := row.Scan(&height); err != nil {
return 0, err
}
return height, nil
}
func (l *l1BlockOrm) GetLatestImportedL1Block() (*types.L1BlockInfo, error) {
row := l.db.QueryRowx(`SELECT * FROM l1_block WHERE block_status = $1 ORDER BY index DESC;`, types.L1BlockImported)
block := &types.L1BlockInfo{}
if err := row.StructScan(block); err != nil {
return nil, err
}
return block, nil
}