Commit 1dd6b9a5 authored by Hamdi Allam's avatar Hamdi Allam

core/types -> database model conversion functions. Getters for...

core/types -> database model conversion functions. Getters for Deposit/Withdrawals based on message nonce as well as the latest nonce
parent d80c145e
...@@ -5,6 +5,8 @@ import ( ...@@ -5,6 +5,8 @@ import (
"errors" "errors"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
...@@ -21,6 +23,15 @@ type BlockHeader struct { ...@@ -21,6 +23,15 @@ type BlockHeader struct {
Timestamp uint64 Timestamp uint64
} }
func BlockHeaderFromHeader(header *types.Header) BlockHeader {
return BlockHeader{
Hash: header.Hash(),
ParentHash: header.ParentHash,
Number: U256{Int: header.Number},
Timestamp: header.Time,
}
}
type L1BlockHeader struct { type L1BlockHeader struct {
BlockHeader BlockHeader
} }
......
...@@ -2,6 +2,7 @@ package database ...@@ -2,6 +2,7 @@ package database
import ( import (
"errors" "errors"
"math/big"
"gorm.io/gorm" "gorm.io/gorm"
...@@ -30,7 +31,16 @@ type TokenPair struct { ...@@ -30,7 +31,16 @@ type TokenPair struct {
type Deposit struct { type Deposit struct {
GUID uuid.UUID `gorm:"primaryKey"` GUID uuid.UUID `gorm:"primaryKey"`
InitiatedL1EventGUID string InitiatedL1EventGUID uuid.UUID
FinalizedL2EventGUID uuid.UUID `gorm:"default:null"`
// Since we're only currently indexing a single StandardBridge,
// the message nonce serves as a unique identifier for this
// deposit. Once this generalizes to more than 1 deployed
// bridge, we need to include the `CrossDomainMessenger` address
// such that the (messenger_addr, nonce) is the unique identifer
// for a bridge msg
SentMessageNonce U256
Tx Transaction `gorm:"embedded"` Tx Transaction `gorm:"embedded"`
TokenPair TokenPair `gorm:"embedded"` TokenPair TokenPair `gorm:"embedded"`
...@@ -43,11 +53,19 @@ type DepositWithTransactionHash struct { ...@@ -43,11 +53,19 @@ type DepositWithTransactionHash struct {
type Withdrawal struct { type Withdrawal struct {
GUID uuid.UUID `gorm:"primaryKey"` GUID uuid.UUID `gorm:"primaryKey"`
InitiatedL2EventGUID string InitiatedL2EventGUID uuid.UUID
// Since we're only currently indexing a single StandardBridge,
// the message nonce serves as a unique identifier for this
// withdrawal. Once this generalizes to more than 1 deployed
// bridge, we need to include the `CrossDomainMessenger` address
// such that the (messenger_addr, nonce) is the unique identifer
// for a bridge msg
SentMessageNonce U256
WithdrawalHash common.Hash `gorm:"serializer:json"` WithdrawalHash common.Hash `gorm:"serializer:json"`
ProvenL1EventGUID *string ProvenL1EventGUID uuid.UUID `gorm:"default:null"`
FinalizedL1EventGUID *string FinalizedL1EventGUID uuid.UUID `gorm:"default:null"`
Tx Transaction `gorm:"embedded"` Tx Transaction `gorm:"embedded"`
TokenPair TokenPair `gorm:"embedded"` TokenPair TokenPair `gorm:"embedded"`
...@@ -63,16 +81,23 @@ type WithdrawalWithTransactionHashes struct { ...@@ -63,16 +81,23 @@ type WithdrawalWithTransactionHashes struct {
type BridgeView interface { type BridgeView interface {
DepositsByAddress(address common.Address) ([]*DepositWithTransactionHash, error) DepositsByAddress(address common.Address) ([]*DepositWithTransactionHash, error)
DepositByMessageNonce(*big.Int) (*Deposit, error)
LatestDepositMessageNonce() (*big.Int, error)
WithdrawalsByAddress(address common.Address) ([]*WithdrawalWithTransactionHashes, error) WithdrawalsByAddress(address common.Address) ([]*WithdrawalWithTransactionHashes, error)
WithdrawalByMessageNonce(*big.Int) (*Withdrawal, error)
LatestWithdrawalMessageNonce() (*big.Int, error)
} }
type BridgeDB interface { type BridgeDB interface {
BridgeView BridgeView
StoreDeposits([]*Deposit) error StoreDeposits([]*Deposit) error
MarkFinalizedDepositEvent(uuid.UUID, uuid.UUID) error
StoreWithdrawals([]*Withdrawal) error StoreWithdrawals([]*Withdrawal) error
MarkProvenWithdrawalEvent(string, string) error MarkProvenWithdrawalEvent(uuid.UUID, uuid.UUID) error
MarkFinalizedWithdrawalEvent(string, string) error MarkFinalizedWithdrawalEvent(uuid.UUID, uuid.UUID) error
} }
/** /**
...@@ -114,6 +139,46 @@ func (db *bridgeDB) DepositsByAddress(address common.Address) ([]*DepositWithTra ...@@ -114,6 +139,46 @@ func (db *bridgeDB) DepositsByAddress(address common.Address) ([]*DepositWithTra
return deposits, nil return deposits, nil
} }
func (db *bridgeDB) DepositByMessageNonce(nonce *big.Int) (*Deposit, error) {
var deposit Deposit
result := db.gorm.First(&deposit, "sent_message_nonce = ?", U256{Int: nonce})
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return &deposit, nil
}
func (db *bridgeDB) LatestDepositMessageNonce() (*big.Int, error) {
var deposit Deposit
result := db.gorm.Order("sent_message_nonce DESC").Take(&deposit)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return deposit.SentMessageNonce.Int, nil
}
func (db *bridgeDB) MarkFinalizedDepositEvent(guid, finalizationEventGUID uuid.UUID) error {
var deposit Deposit
result := db.gorm.First(&deposit, "guid = ?", guid)
if result.Error != nil {
return result.Error
}
deposit.FinalizedL2EventGUID = finalizationEventGUID
result = db.gorm.Save(&deposit)
return result.Error
}
// Withdrawals // Withdrawals
func (db *bridgeDB) StoreWithdrawals(withdrawals []*Withdrawal) error { func (db *bridgeDB) StoreWithdrawals(withdrawals []*Withdrawal) error {
...@@ -121,26 +186,26 @@ func (db *bridgeDB) StoreWithdrawals(withdrawals []*Withdrawal) error { ...@@ -121,26 +186,26 @@ func (db *bridgeDB) StoreWithdrawals(withdrawals []*Withdrawal) error {
return result.Error return result.Error
} }
func (db *bridgeDB) MarkProvenWithdrawalEvent(guid, provenL1EventGuid string) error { func (db *bridgeDB) MarkProvenWithdrawalEvent(guid, provenL1EventGuid uuid.UUID) error {
var withdrawal Withdrawal var withdrawal Withdrawal
result := db.gorm.First(&withdrawal, "guid = ?", guid) result := db.gorm.First(&withdrawal, "guid = ?", guid)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
withdrawal.ProvenL1EventGUID = &provenL1EventGuid withdrawal.ProvenL1EventGUID = provenL1EventGuid
result = db.gorm.Save(&withdrawal) result = db.gorm.Save(&withdrawal)
return result.Error return result.Error
} }
func (db *bridgeDB) MarkFinalizedWithdrawalEvent(guid, finalizedL1EventGuid string) error { func (db *bridgeDB) MarkFinalizedWithdrawalEvent(guid, finalizedL1EventGuid uuid.UUID) error {
var withdrawal Withdrawal var withdrawal Withdrawal
result := db.gorm.First(&withdrawal, "guid = ?", guid) result := db.gorm.First(&withdrawal, "guid = ?", guid)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
withdrawal.FinalizedL1EventGUID = &finalizedL1EventGuid withdrawal.FinalizedL1EventGUID = finalizedL1EventGuid
result = db.gorm.Save(&withdrawal) result = db.gorm.Save(&withdrawal)
return result.Error return result.Error
} }
...@@ -167,3 +232,31 @@ func (db *bridgeDB) WithdrawalsByAddress(address common.Address) ([]*WithdrawalW ...@@ -167,3 +232,31 @@ func (db *bridgeDB) WithdrawalsByAddress(address common.Address) ([]*WithdrawalW
return withdrawals, nil return withdrawals, nil
} }
func (db *bridgeDB) WithdrawalByMessageNonce(nonce *big.Int) (*Withdrawal, error) {
var withdrawal Withdrawal
result := db.gorm.First(&withdrawal, "sent_message_nonce = ?", U256{Int: nonce})
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return &withdrawal, nil
}
func (db *bridgeDB) LatestWithdrawalMessageNonce() (*big.Int, error) {
var withdrawal Withdrawal
result := db.gorm.Order("sent_message_nonce DESC").Take(&withdrawal)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return withdrawal.SentMessageNonce.Int, nil
}
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/google/uuid" "github.com/google/uuid"
) )
...@@ -22,6 +23,20 @@ type ContractEvent struct { ...@@ -22,6 +23,20 @@ type ContractEvent struct {
Timestamp uint64 Timestamp uint64
} }
func ContractEventFromLog(log *types.Log, timestamp uint64) ContractEvent {
return ContractEvent{
GUID: uuid.New(),
BlockHash: log.BlockHash,
TransactionHash: log.TxHash,
EventSignature: log.Topics[0],
LogIndex: uint64(log.Index),
Timestamp: timestamp,
}
}
type L1ContractEvent struct { type L1ContractEvent struct {
ContractEvent `gorm:"embedded"` ContractEvent `gorm:"embedded"`
} }
......
...@@ -10,14 +10,15 @@ CREATE TABLE IF NOT EXISTS l1_block_headers ( ...@@ -10,14 +10,15 @@ CREATE TABLE IF NOT EXISTS l1_block_headers (
hash VARCHAR NOT NULL PRIMARY KEY, hash VARCHAR NOT NULL PRIMARY KEY,
parent_hash VARCHAR NOT NULL, parent_hash VARCHAR NOT NULL,
number UINT256, number UINT256,
timestamp INTEGER NOT NULL timestamp INTEGER NOT NULL CHECK (timestamp > 0)
); );
CREATE TABLE IF NOT EXISTS l2_block_headers ( CREATE TABLE IF NOT EXISTS l2_block_headers (
hash VARCHAR NOT NULL PRIMARY KEY, -- Block header
parent_hash VARCHAR NOT NULL, hash VARCHAR NOT NULL PRIMARY KEY,
number UINT256, parent_hash VARCHAR NOT NULL,
timestamp INTEGER NOT NULL number UINT256,
timestamp INTEGER NOT NULL CHECK (timestamp > 0),
); );
/** /**
...@@ -30,7 +31,7 @@ CREATE TABLE IF NOT EXISTS l1_contract_events ( ...@@ -30,7 +31,7 @@ CREATE TABLE IF NOT EXISTS l1_contract_events (
transaction_hash VARCHAR NOT NULL, transaction_hash VARCHAR NOT NULL,
event_signature VARCHAR NOT NULL, event_signature VARCHAR NOT NULL,
log_index INTEGER NOT NULL, log_index INTEGER NOT NULL,
timestamp INTEGER NOT NULL timestamp INTEGER NOT NULL CHECK (timestamp > 0)
); );
CREATE TABLE IF NOT EXISTS l2_contract_events ( CREATE TABLE IF NOT EXISTS l2_contract_events (
...@@ -39,7 +40,7 @@ CREATE TABLE IF NOT EXISTS l2_contract_events ( ...@@ -39,7 +40,7 @@ CREATE TABLE IF NOT EXISTS l2_contract_events (
transaction_hash VARCHAR NOT NULL, transaction_hash VARCHAR NOT NULL,
event_signature VARCHAR NOT NULL, event_signature VARCHAR NOT NULL,
log_index INTEGER NOT NULL, log_index INTEGER NOT NULL,
timestamp INTEGER NOT NULL timestamp INTEGER NOT NULL CHECK (timestamp > 0)
); );
-- Tables that index finalization markers for L2 blocks. -- Tables that index finalization markers for L2 blocks.
...@@ -69,6 +70,10 @@ CREATE TABLE IF NOT EXISTS deposits ( ...@@ -69,6 +70,10 @@ CREATE TABLE IF NOT EXISTS deposits (
-- Event causing the deposit -- Event causing the deposit
initiated_l1_event_guid VARCHAR NOT NULL REFERENCES l1_contract_events(guid), initiated_l1_event_guid VARCHAR NOT NULL REFERENCES l1_contract_events(guid),
sent_message_nonce UINT256 NOT NULL UNIQUE,
-- Finalization marker for the deposit
finalized_l2_event_guid VARCHAR REFERENCES l2_contract_events(guid),
-- Deposit information (do we need indexes on from/to?) -- Deposit information (do we need indexes on from/to?)
from_address VARCHAR NOT NULL, from_address VARCHAR NOT NULL,
...@@ -78,7 +83,7 @@ CREATE TABLE IF NOT EXISTS deposits ( ...@@ -78,7 +83,7 @@ CREATE TABLE IF NOT EXISTS deposits (
l2_token_address VARCHAR NOT NULL, l2_token_address VARCHAR NOT NULL,
amount UINT256, amount UINT256,
data VARCHAR NOT NULL, data VARCHAR NOT NULL,
timestamp INTEGER NOT NULL timestamp INTEGER NOT NULL CHECK (timestamp > 0)
); );
CREATE TABLE IF NOT EXISTS withdrawals ( CREATE TABLE IF NOT EXISTS withdrawals (
...@@ -86,6 +91,7 @@ CREATE TABLE IF NOT EXISTS withdrawals ( ...@@ -86,6 +91,7 @@ CREATE TABLE IF NOT EXISTS withdrawals (
-- Event causing this withdrawal -- Event causing this withdrawal
initiated_l2_event_guid VARCHAR NOT NULL REFERENCES l2_contract_events(guid), initiated_l2_event_guid VARCHAR NOT NULL REFERENCES l2_contract_events(guid),
sent_message_nonce UINT256 NOT NULL UNIQUE,
-- Multistep (bedrock) process of a withdrawal -- Multistep (bedrock) process of a withdrawal
withdrawal_hash VARCHAR NOT NULL, withdrawal_hash VARCHAR NOT NULL,
...@@ -101,5 +107,5 @@ CREATE TABLE IF NOT EXISTS withdrawals ( ...@@ -101,5 +107,5 @@ CREATE TABLE IF NOT EXISTS withdrawals (
l2_token_address VARCHAR NOT NULL, l2_token_address VARCHAR NOT NULL,
amount UINT256, amount UINT256,
data VARCHAR NOT NULL, data VARCHAR NOT NULL,
timestamp INTEGER NOT NULL timestamp INTEGER NOT NULL CHECK (timestamp > 0)
); );
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