mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-04-23 03:00:50 -04:00
Co-authored-by: vincent <419436363@qq.com> Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Co-authored-by: colinlyguo <colinlyguo@scroll.io> Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com> Co-authored-by: georgehao <haohongfan@gmail.com>
109 lines
3.5 KiB
Go
109 lines
3.5 KiB
Go
package crossmsg
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
"gorm.io/gorm"
|
|
|
|
"bridge-history-api/orm"
|
|
)
|
|
|
|
// ReorgHandling handles reorg function type
|
|
type ReorgHandling func(ctx context.Context, reorgHeight uint64, db *gorm.DB) error
|
|
|
|
func reverseArray(arr []*types.Header) []*types.Header {
|
|
for i := 0; i < len(arr)/2; i++ {
|
|
j := len(arr) - i - 1
|
|
arr[i], arr[j] = arr[j], arr[i]
|
|
}
|
|
return arr
|
|
}
|
|
|
|
// IsParentAndChild match the child header ParentHash with parent header Hash
|
|
func IsParentAndChild(parentHeader *types.Header, header *types.Header) bool {
|
|
return header.ParentHash == parentHeader.Hash()
|
|
}
|
|
|
|
// MergeAddIntoHeaderList merges two header lists, if exceed the max length then drop the oldest entries
|
|
func MergeAddIntoHeaderList(baseArr, extraArr []*types.Header, maxLength int) []*types.Header {
|
|
mergedArr := append(baseArr, extraArr...)
|
|
if len(mergedArr) <= maxLength {
|
|
return mergedArr
|
|
}
|
|
|
|
startIndex := len(mergedArr) - maxLength
|
|
return mergedArr[startIndex:]
|
|
}
|
|
|
|
// BackwardFindReorgBlock finds the reorg block by backward search
|
|
func BackwardFindReorgBlock(ctx context.Context, headers []*types.Header, client *ethclient.Client, lastHeader *types.Header) (int, bool, []*types.Header) {
|
|
maxStep := len(headers)
|
|
backwardHeaderList := []*types.Header{lastHeader}
|
|
for iterRound := 0; iterRound < maxStep; iterRound++ {
|
|
header, err := client.HeaderByHash(ctx, lastHeader.ParentHash)
|
|
if err != nil {
|
|
log.Error("BackwardFindReorgBlock failed", "error", err)
|
|
return -1, false, nil
|
|
}
|
|
backwardHeaderList = append(backwardHeaderList, header)
|
|
for j := len(headers) - 1; j >= 0; j-- {
|
|
if IsParentAndChild(headers[j], header) {
|
|
backwardHeaderList = reverseArray(backwardHeaderList)
|
|
return j, true, backwardHeaderList
|
|
}
|
|
}
|
|
lastHeader = header
|
|
}
|
|
return -1, false, nil
|
|
}
|
|
|
|
// L1ReorgHandling handles l1 reorg
|
|
func L1ReorgHandling(ctx context.Context, reorgHeight uint64, db *gorm.DB) error {
|
|
l1CrossMsgOrm := orm.NewCrossMsg(db)
|
|
relayedOrm := orm.NewRelayedMsg(db)
|
|
err := db.Transaction(func(tx *gorm.DB) error {
|
|
if err := l1CrossMsgOrm.DeleteL1CrossMsgAfterHeight(ctx, reorgHeight, tx); err != nil {
|
|
log.Error("delete l1 cross msg from height", "height", reorgHeight, "err", err)
|
|
return err
|
|
}
|
|
if err := relayedOrm.DeleteL1RelayedHashAfterHeight(ctx, reorgHeight, tx); err != nil {
|
|
log.Error("delete l1 relayed msg from height", "height", reorgHeight, "err", err)
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
log.Crit("l1 reorg handling failed", "err", err)
|
|
}
|
|
return err
|
|
}
|
|
|
|
// L2ReorgHandling handles l2 reorg
|
|
func L2ReorgHandling(ctx context.Context, reorgHeight uint64, db *gorm.DB) error {
|
|
l2CrossMsgOrm := orm.NewCrossMsg(db)
|
|
relayedOrm := orm.NewRelayedMsg(db)
|
|
l2SentMsgOrm := orm.NewL2SentMsg(db)
|
|
err := db.Transaction(func(tx *gorm.DB) error {
|
|
if err := l2CrossMsgOrm.DeleteL2CrossMsgFromHeight(ctx, reorgHeight, tx); err != nil {
|
|
log.Error("delete l2 cross msg from height", "height", reorgHeight, "err", err)
|
|
return err
|
|
}
|
|
if err := relayedOrm.DeleteL2RelayedHashAfterHeight(ctx, reorgHeight, tx); err != nil {
|
|
log.Error("delete l2 relayed msg from height", "height", reorgHeight, "err", err)
|
|
return err
|
|
}
|
|
if err := l2SentMsgOrm.DeleteL2SentMsgAfterHeight(ctx, reorgHeight, tx); err != nil {
|
|
log.Error("delete l2 sent msg from height", "height", reorgHeight, "err", err)
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
log.Crit("l2 reorg handling failed", "err", err)
|
|
}
|
|
return err
|
|
}
|