Commit 3531c1d9 authored by Hamdi Allam's avatar Hamdi Allam

contract event filter & rlp log clarify

parent 3af1cc0f
...@@ -2,6 +2,7 @@ package database ...@@ -2,6 +2,7 @@ package database
import ( import (
"errors" "errors"
"math/big"
"gorm.io/gorm" "gorm.io/gorm"
...@@ -16,15 +17,19 @@ import ( ...@@ -16,15 +17,19 @@ import (
*/ */
type ContractEvent struct { type ContractEvent struct {
GUID uuid.UUID `gorm:"primaryKey"` GUID uuid.UUID `gorm:"primaryKey"`
// Some useful derived fields
BlockHash common.Hash `gorm:"serializer:json"` BlockHash common.Hash `gorm:"serializer:json"`
ContractAddress common.Address `gorm:"serializer:json"` ContractAddress common.Address `gorm:"serializer:json"`
TransactionHash common.Hash `gorm:"serializer:json"` TransactionHash common.Hash `gorm:"serializer:json"`
LogIndex uint64
EventSignature common.Hash `gorm:"serializer:json"` EventSignature common.Hash `gorm:"serializer:json"`
LogIndex uint64
Timestamp uint64 Timestamp uint64
// NOTE: NOT ALL THE DERIVED FIELDS ON `types.Log` ARE
// AVAILABLE. ONLY THE ONES LISTED ABOVE.
GethLog *types.Log `gorm:"serializer:rlp;column:rlp_bytes"` GethLog *types.Log `gorm:"serializer:rlp;column:rlp_bytes"`
} }
...@@ -38,8 +43,8 @@ func ContractEventFromGethLog(log *types.Log, timestamp uint64) ContractEvent { ...@@ -38,8 +43,8 @@ func ContractEventFromGethLog(log *types.Log, timestamp uint64) ContractEvent {
GUID: uuid.New(), GUID: uuid.New(),
BlockHash: log.BlockHash, BlockHash: log.BlockHash,
ContractAddress: log.Address,
TransactionHash: log.TxHash, TransactionHash: log.TxHash,
ContractAddress: log.Address,
EventSignature: eventSig, EventSignature: eventSig,
LogIndex: uint64(log.Index), LogIndex: uint64(log.Index),
...@@ -50,6 +55,15 @@ func ContractEventFromGethLog(log *types.Log, timestamp uint64) ContractEvent { ...@@ -50,6 +55,15 @@ func ContractEventFromGethLog(log *types.Log, timestamp uint64) ContractEvent {
} }
} }
func (c *ContractEvent) AfterFind(tx *gorm.DB) error {
// Fill in some of the derived fields that are not
// populated when decoding the GethLog from RLP
c.GethLog.BlockHash = c.BlockHash
c.GethLog.TxHash = c.TransactionHash
c.GethLog.Index = uint(c.LogIndex)
return nil
}
type L1ContractEvent struct { type L1ContractEvent struct {
ContractEvent `gorm:"embedded"` ContractEvent `gorm:"embedded"`
} }
...@@ -61,9 +75,11 @@ type L2ContractEvent struct { ...@@ -61,9 +75,11 @@ type L2ContractEvent struct {
type ContractEventsView interface { type ContractEventsView interface {
L1ContractEvent(uuid.UUID) (*L1ContractEvent, error) L1ContractEvent(uuid.UUID) (*L1ContractEvent, error)
L1ContractEventByTxLogIndex(common.Hash, uint64) (*L1ContractEvent, error) L1ContractEventByTxLogIndex(common.Hash, uint64) (*L1ContractEvent, error)
L1ContractEventsWithFilter(ContractEvent, *big.Int, *big.Int) ([]L1ContractEvent, error)
L2ContractEvent(uuid.UUID) (*L2ContractEvent, error) L2ContractEvent(uuid.UUID) (*L2ContractEvent, error)
L2ContractEventByTxLogIndex(common.Hash, uint64) (*L2ContractEvent, error) L2ContractEventByTxLogIndex(common.Hash, uint64) (*L2ContractEvent, error)
L2ContractEventsWithFilter(ContractEvent, *big.Int, *big.Int) ([]L2ContractEvent, error)
} }
type ContractEventsDB interface { type ContractEventsDB interface {
...@@ -120,6 +136,30 @@ func (db *contractEventsDB) L1ContractEventByTxLogIndex(txHash common.Hash, logI ...@@ -120,6 +136,30 @@ func (db *contractEventsDB) L1ContractEventByTxLogIndex(txHash common.Hash, logI
return &l1ContractEvent, nil return &l1ContractEvent, nil
} }
func (db *contractEventsDB) L1ContractEventsWithFilter(filter ContractEvent, fromHeight, toHeight *big.Int) ([]L1ContractEvent, error) {
if fromHeight == nil {
fromHeight = big.NewInt(0)
}
query := db.gorm.Table("l1_contract_events").Where(&filter)
query = query.Joins("INNER JOIN l1_block_headers ON l1_contract_events.block_hash = l1_block_headers.hash")
query = query.Where("l1_block_headers.number >= ? AND l1_block_headers.number <= ?", fromHeight, toHeight)
query = query.Order("l1_block_headers.number ASC").Select("l1_contract_events.*")
// NOTE: We use `Find` here instead of `Scan` since `Scan` doesn't not support
// model hooks like `ContractEvent#AfterFind`. Functionally they are the same
var events []L1ContractEvent
result := query.Find(&events)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return events, nil
}
// L2 // L2
func (db *contractEventsDB) StoreL2ContractEvents(events []*L2ContractEvent) error { func (db *contractEventsDB) StoreL2ContractEvents(events []*L2ContractEvent) error {
...@@ -154,3 +194,27 @@ func (db *contractEventsDB) L2ContractEventByTxLogIndex(txHash common.Hash, logI ...@@ -154,3 +194,27 @@ func (db *contractEventsDB) L2ContractEventByTxLogIndex(txHash common.Hash, logI
return &l2ContractEvent, nil return &l2ContractEvent, nil
} }
func (db *contractEventsDB) L2ContractEventsWithFilter(filter ContractEvent, fromHeight, toHeight *big.Int) ([]L2ContractEvent, error) {
if fromHeight == nil {
fromHeight = big.NewInt(0)
}
query := db.gorm.Table("l2_contract_events").Where(&filter)
query = query.Joins("INNER JOIN l2_block_headers ON l2_contract_events.block_hash = l2_block_headers.hash")
query = query.Where("l2_block_headers.number >= ? AND l2_block_headers.number <= ?", fromHeight, toHeight)
query = query.Order("l2_block_headers.number ASC").Select("l2_contract_events.*")
// NOTE: We use `Find` here instead of `Scan` since `Scan` doesn't not support
// model hooks like `ContractEvent#AfterFind`. Functionally they are the same
var events []L2ContractEvent
result := query.Find(&events)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return events, nil
}
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