Skip to content

Commit

Permalink
temp commit
Browse files Browse the repository at this point in the history
  • Loading branch information
colinlyguo committed Dec 5, 2023
1 parent f7652c3 commit d1ea327
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 129 deletions.
6 changes: 3 additions & 3 deletions bridge-history-api/cmd/cross_msg_fetcher/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/urfave/cli/v2"

"bridge-history-api/config"
"bridge-history-api/crossmessage/controller/messagefetcher"
"bridge-history-api/crossmessage/controller/eventfetcher"
"bridge-history-api/utils"
)

Expand Down Expand Up @@ -65,13 +65,13 @@ func action(ctx *cli.Context) error {
log.Crit("failed to connect to db", "config file", cfgFile, "error", err)
}

l1MessageFetcher, err := messagefetcher.NewL1MessageFetcher(subCtx, cfg.L1, db, l1Client)
l1MessageFetcher, err := eventfetcher.NewL1MessageFetcher(subCtx, cfg.L1, db, l1Client)
if err != nil {
log.Crit("failed to create l1 cross message fetcher", "error", err)
}
go l1MessageFetcher.Start()

l2MessageFetcher, err := messagefetcher.NewL2MessageFetcher(subCtx, cfg.L2, db, l2Client)
l2MessageFetcher, err := eventfetcher.NewL2MessageFetcher(subCtx, cfg.L2, db, l2Client)
if err != nil {
log.Crit("failed to create l2 cross message fetcher", "error", err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package messagefetcher
package eventfetcher

import (
"context"
Expand All @@ -25,6 +25,7 @@ type L1MessageFetcher struct {
cfg *config.LayerConfig
db *gorm.DB
crossMessageOrm *orm.CrossMessage
batchEventOrm *orm.BatchEvent
client *ethclient.Client
addressList []common.Address
}
Expand Down Expand Up @@ -63,6 +64,7 @@ func NewL1MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.
cfg: cfg,
db: db,
crossMessageOrm: orm.NewCrossMessage(db),
batchEventOrm: orm.NewBatchEvent(db),
client: client,
addressList: addressList,
}, nil
Expand Down Expand Up @@ -212,9 +214,8 @@ func (c *L1MessageFetcher) doFetchAndSaveEvents(ctx context.Context, from uint64
log.Error("failed to update l1 relayed messages of l2 withdrawals", "from", from, "to", to, "err", txErr)
return txErr
}
// should wait the l2 data ready. seperate it in another thread.
if txErr := c.crossMessageOrm.UpdateBatchIndexOfL2Withdrawals(ctx, l1BatchEvents, tx); txErr != nil {
log.Error("failed to update batch index of l2 withdrawals", "from", from, "to", to, "err", txErr)
if txErr := c.batchEventOrm.InsertOrUpdateBatchEvents(ctx, l1BatchEvents, tx); txErr != nil {
log.Error("failed to insert or update batch events", "from", from, "to", to, "err", txErr)
return txErr
}
if txErr := c.crossMessageOrm.UpdateL1MessageQueueEventsInfo(ctx, l1MessageQueueEvents, tx); txErr != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package messagefetcher
package eventfetcher

import (
"context"
Expand Down
23 changes: 13 additions & 10 deletions bridge-history-api/crossmessage/logic/event_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,15 @@ func ParseL1BatchEventLogs(ctx context.Context, logs []types.Log, blockTimestamp
log.Warn("Failed to get commit Batch tx receipt or the tx is still pending", "err", err)
return nil, err
}
index, startBlock, endBlock, err := utils.GetBatchRangeFromCalldata(commitTx.Data())
startBlock, endBlock, err := utils.GetBatchRangeFromCalldata(commitTx.Data())
if err != nil {
log.Warn("Failed to get batch range from calldata", "hash", commitTx.Hash().String(), "height", vlog.BlockNumber)
return nil, err
}
l1BatchEvents = append(l1BatchEvents, &orm.BatchEvent{
Type: orm.BatchEventTypeCommitBatch,
BatchIndex: index,
BatchStatus: int(orm.BatchStatusTypeCommitted),
BatchIndex: event.BatchIndex.Uint64(),
BatchHash: event.BatchHash.String(),
StartBlockNumber: startBlock,
EndBlockNumber: endBlock,
})
Expand All @@ -213,8 +214,9 @@ func ParseL1BatchEventLogs(ctx context.Context, logs []types.Log, blockTimestamp
return nil, err
}
l1BatchEvents = append(l1BatchEvents, &orm.BatchEvent{
Type: orm.BatchEventTypeRevertBatch,
BatchIndex: event.BatchIndex.Uint64(),
BatchStatus: int(orm.BatchStatusTypeReverted),
BatchIndex: event.BatchIndex.Uint64(),
BatchHash: event.BatchHash.String(),
})
case backendabi.L1FinalizeBatchEventSig:
event := backendabi.L1FinalizeBatchEvent{}
Expand All @@ -223,8 +225,9 @@ func ParseL1BatchEventLogs(ctx context.Context, logs []types.Log, blockTimestamp
return nil, err
}
l1BatchEvents = append(l1BatchEvents, &orm.BatchEvent{
Type: orm.BatchEventTypeFinalizeBatch,
BatchIndex: event.BatchIndex.Uint64(),
BatchStatus: int(orm.BatchStatusTypeFinalized),
BatchIndex: event.BatchIndex.Uint64(),
BatchHash: event.BatchHash.String(),
})
}
}
Expand All @@ -246,7 +249,7 @@ func ParseL1MessageQueueEventLogs(ctx context.Context, logs []types.Log, blockTi
// 2. Update tx hash of replay message.
// The MessageHash is computed by hashing the Data field from the event, which is _xDomainCalldata.
l1MessageQueueEvents = append(l1MessageQueueEvents, &orm.MessageQueueEvent{
Type: orm.MessageQueueEventTypeQueueTransaction,
EventType: orm.MessageQueueEventTypeQueueTransaction,
MessageHash: common.BytesToHash(crypto.Keccak256(event.Data)),
QueueIndex: event.QueueIndex,
TxHash: vlog.TxHash,
Expand All @@ -260,7 +263,7 @@ func ParseL1MessageQueueEventLogs(ctx context.Context, logs []types.Log, blockTi
skippedIndices := getSkippedQueueIndices(event.StartIndex.Uint64(), event.SkippedBitmap)
for _, index := range skippedIndices {
l1MessageQueueEvents = append(l1MessageQueueEvents, &orm.MessageQueueEvent{
Type: orm.MessageQueueEventTypeDequeueTransaction,
EventType: orm.MessageQueueEventTypeDequeueTransaction,
QueueIndex: index,
})
}
Expand All @@ -271,7 +274,7 @@ func ParseL1MessageQueueEventLogs(ctx context.Context, logs []types.Log, blockTi
return nil, err
}
l1MessageQueueEvents = append(l1MessageQueueEvents, &orm.MessageQueueEvent{
Type: orm.MessageQueueEventTypeDropTransaction,
EventType: orm.MessageQueueEventTypeDropTransaction,
QueueIndex: event.Index.Uint64(),
})
}
Expand Down
60 changes: 38 additions & 22 deletions bridge-history-api/internal/logic/history_logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package logic

import (
"context"
"log"
"strconv"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -14,11 +15,15 @@ import (
// HistoryLogic services.
type HistoryLogic struct {
crossMessageOrm *orm.CrossMessage
batchEventOrm *orm.BatchEvent
}

// NewHistoryLogic returns bridge history services.
func NewHistoryLogic(db *gorm.DB) *HistoryLogic {
logic := &HistoryLogic{crossMessageOrm: orm.NewCrossMessage(db)}
logic := &HistoryLogic{
crossMessageOrm: orm.NewCrossMessage(db),
batchEventOrm: orm.NewBatchEvent(db),
}
return logic
}

Expand Down Expand Up @@ -71,6 +76,7 @@ func (h *HistoryLogic) GetTxsByHashes(ctx context.Context, txHashes []string) ([
for _, message := range messages {
txHistories = append(txHistories, getTxHistoryInfo(message))
}
h.updateBatchIndexAndRollupStatus(ctx, txHistories)
return txHistories, nil
}

Expand All @@ -87,33 +93,43 @@ func getTxHistoryInfo(message *orm.CrossMessage) *types.TxHistoryInfo {
if txHistory.IsL1 {
txHistory.Hash = message.L1TxHash
txHistory.BlockNumber = message.L1BlockNumber
txHistory.FinalizeTx = &types.Finalized{
Hash: message.L2TxHash,
BlockNumber: message.L2BlockNumber,
}
} else {
txHistory.Hash = message.L2TxHash
txHistory.BlockNumber = message.L2BlockNumber
}
if orm.RollupStatusType(message.RollupStatus) == orm.RollupStatusTypeFinalized {
if txHistory.IsL1 {
txHistory.FinalizeTx = &types.Finalized{
Hash: message.L2TxHash,
BlockNumber: message.L2BlockNumber,
IsFinalized: true,
}
} else {
txHistory.FinalizeTx = &types.Finalized{
Hash: message.L1TxHash,
BlockNumber: message.L1BlockNumber,
IsFinalized: orm.RollupStatusType(message.RollupStatus) == orm.RollupStatusTypeFinalized,
}
txHistory.FinalizeTx = &types.Finalized{
Hash: message.L1TxHash,
BlockNumber: message.L1BlockNumber,
}
txHistory.ClaimInfo = &types.UserClaimInfo{
From: message.MessageFrom,
To: message.MessageTo,
Value: message.MessageValue,
Nonce: strconv.FormatUint(message.MessageNonce, 10),
Message: message.MessageData,
Proof: common.Bytes2Hex(message.MerkleProof),
BatchIndex: strconv.FormatUint(message.BatchIndex, 10),
From: message.MessageFrom,
To: message.MessageTo,
Value: message.MessageValue,
Nonce: strconv.FormatUint(message.MessageNonce, 10),
Message: message.MessageData,
Proof: common.Bytes2Hex(message.MerkleProof),
}
}
return txHistory
}

func (h *HistoryLogic) updateBatchIndexAndRollupStatus(ctx context.Context, txHistories []*types.TxHistoryInfo) {
for _, txHistory := range txHistories {
// Only update L2 transactions.
if !txHistory.IsL1 {
batch, err := h.batchEventOrm.GetBatchByBlock(ctx, txHistory.BlockNumber)
if err != nil {
log.Printf("Failed to get batch by block number, block number: %d, error: %v", txHistory.BlockNumber, err)
continue
}

if batch != nil {
txHistory.ClaimInfo.BatchIndex = strconv.FormatUint(batch.BatchIndex, 10)
txHistory.ClaimInfo.Claimable = true
}
}
}
}
2 changes: 1 addition & 1 deletion bridge-history-api/internal/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func Route(router *gin.Engine, conf *config.Config, reg prometheus.Registerer) {
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowMethods: []string{"GET", "POST"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
Expand Down
1 change: 1 addition & 0 deletions bridge-history-api/internal/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type UserClaimInfo struct {
Message string `json:"message"`
Proof string `json:"proof"`
BatchIndex string `json:"batch_index"`
Claimable bool `json:"claimable"`
}

// TxHistoryInfo the schema of tx history infos
Expand Down
107 changes: 107 additions & 0 deletions bridge-history-api/orm/batch_event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package orm

import (
"context"
"fmt"
"time"

"gorm.io/gorm"
)

// RollupStatusType represents the status of a rollup.
type RollupStatusType int

// Constants for RollupStatusType.
const (
RollupStatusTypeUncommitted RollupStatusType = iota
RollupStatusTypeCommitted
RollupStatusTypeFinalized // only batch finalized status is used.
)

// BatchStatusType represents the type of batch status.
type BatchStatusType int

// Constants for BatchStatusType.
const (
BatchStatusTypeUnknown BatchStatusType = iota
BatchStatusTypeCommitted
BatchStatusTypeReverted
BatchStatusTypeFinalized
)

// BatchEvent represents a batch event.
type BatchEvent struct {
db *gorm.DB `gorm:"column:-"`

ID uint64 `json:"id" gorm:"column:id;primary_key"`
BatchStatus int `json:"batch_status" gorm:"column:batch_status"`
BatchIndex uint64 `json:"batch_index" gorm:"column:batch_index"`
BatchHash string `json:"batch_hash" gorm:"column:batch_hash"`
StartBlockNumber uint64 `json:"start_block_number" gorm:"column:start_block_number"`
EndBlockNumber uint64 `json:"end_block_number" gorm:"column:end_block_number"`
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
DeletedAt *time.Time `json:"deleted_at" gorm:"column:deleted_at"`
}

// TableName returns the table name for the BatchEvent model.
func (*BatchEvent) TableName() string {
return "batch_event"
}

// NewBatchEvent returns a new instance of BatchEvent.
func NewBatchEvent(db *gorm.DB) *BatchEvent {
return &BatchEvent{db: db}
}

// GetBatchByBlock retrieves the batch that contains the given block number.
func (c *BatchEvent) GetBatchByBlock(ctx context.Context, blockNumber uint64) (*BatchEvent, error) {
var batchEvent BatchEvent
db := c.db.WithContext(ctx)
db = db.Model(&BatchEvent{})
db = db.Where("start_block_number <= ? AND end_block_number >= ?", blockNumber, blockNumber)
if err := db.First(&batchEvent).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
}
return nil, fmt.Errorf("failed to get batch by block number, block number: %d, error: %w", blockNumber, err)
}
return &batchEvent, nil
}

// InsertOrUpdateBatchEvents inserts a new batch event or updates an existing one based on the BatchStatusType.
func (c *BatchEvent) InsertOrUpdateBatchEvents(ctx context.Context, l1BatchEvents []*BatchEvent, dbTX ...*gorm.DB) error {
originalDB := c.db
if len(dbTX) > 0 && dbTX[0] != nil {
originalDB = dbTX[0]
}
originalDB = originalDB.WithContext(ctx)
originalDB = originalDB.Model(&CrossMessage{})

for _, l1BatchEvent := range l1BatchEvents {
db := originalDB
db = db.Model(BatchEvent{})
updateFields := make(map[string]interface{})
switch BatchStatusType(l1BatchEvent.BatchStatus) {
case BatchStatusTypeCommitted:
if err := db.Create(l1BatchEvent).Error; err != nil {
return fmt.Errorf("failed to insert batch event, batch: %+v, error: %w", l1BatchEvent, err)
}
case BatchStatusTypeFinalized:
updateFields["batch_status"] = BatchStatusTypeFinalized
if err := db.Updates(updateFields).Error; err != nil {
return fmt.Errorf("failed to update batch event, batch: %+v, error: %w", l1BatchEvent, err)
}
case BatchStatusTypeReverted:
updateFields["batch_status"] = BatchStatusTypeReverted
if err := db.Updates(updateFields).Error; err != nil {
return fmt.Errorf("failed to update batch event, batch: %+v, error: %w", l1BatchEvent, err)
}
// Soft delete the batch event
if err := db.Delete(l1BatchEvent).Error; err != nil {
return fmt.Errorf("failed to soft delete batch event, batch: %+v, error: %w", l1BatchEvent, err)
}
}
}
return nil
}
Loading

0 comments on commit d1ea327

Please sign in to comment.