mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-14 00:18:03 -05:00
Co-authored-by: vincent <419436363@qq.com> Co-authored-by: georgehao <haohongfan@gmail.com> Co-authored-by: colinlyguo <colinlyguo@scroll.io>
189 lines
5.4 KiB
Go
189 lines
5.4 KiB
Go
package service
|
|
|
|
import (
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
|
|
"bridge-history-api/db"
|
|
"bridge-history-api/db/orm"
|
|
)
|
|
|
|
type Finalized struct {
|
|
Hash string `json:"hash"`
|
|
Amount string `json:"amount"`
|
|
To string `json:"to"` // useless
|
|
IsL1 bool `json:"isL1"`
|
|
BlockNumber uint64 `json:"blockNumber"`
|
|
BlockTimestamp *time.Time `json:"blockTimestamp"` // uselesss
|
|
}
|
|
|
|
type UserClaimInfo struct {
|
|
From string `json:"from"`
|
|
To string `json:"to"`
|
|
Value string `json:"value"`
|
|
Nonce string `json:"nonce"`
|
|
BatchHash string `json:"batch_hash"`
|
|
Message string `json:"message"`
|
|
Proof string `json:"proof"`
|
|
BatchIndex string `json:"batch_index"`
|
|
}
|
|
|
|
type TxHistoryInfo struct {
|
|
Hash string `json:"hash"`
|
|
Amount string `json:"amount"`
|
|
To string `json:"to"` // useless
|
|
IsL1 bool `json:"isL1"`
|
|
BlockNumber uint64 `json:"blockNumber"`
|
|
BlockTimestamp *time.Time `json:"blockTimestamp"` // useless
|
|
FinalizeTx *Finalized `json:"finalizeTx"`
|
|
ClaimInfo *UserClaimInfo `json:"claimInfo"`
|
|
CreatedAt *time.Time `json:"createdTime"`
|
|
}
|
|
|
|
// HistoryService example service.
|
|
type HistoryService interface {
|
|
GetTxsByAddress(address common.Address, offset int64, limit int64) ([]*TxHistoryInfo, uint64, error)
|
|
GetTxsByHashes(hashes []string) ([]*TxHistoryInfo, error)
|
|
}
|
|
|
|
// NewHistoryService returns a service backed with a "db"
|
|
func NewHistoryService(db db.OrmFactory) HistoryService {
|
|
service := &historyBackend{db: db, prefix: "Scroll-Bridge-History-Server"}
|
|
return service
|
|
}
|
|
|
|
type historyBackend struct {
|
|
prefix string
|
|
db db.OrmFactory
|
|
}
|
|
|
|
func GetCrossTxClaimInfo(msgHash string, db db.OrmFactory) *UserClaimInfo {
|
|
l2sentMsg, err := db.GetL2SentMsgByHash(msgHash)
|
|
if err != nil {
|
|
log.Debug("GetCrossTxClaimInfo failed", "error", err)
|
|
return &UserClaimInfo{}
|
|
}
|
|
batch, err := db.GetRollupBatchByIndex(l2sentMsg.BatchIndex)
|
|
if err != nil {
|
|
log.Debug("GetCrossTxClaimInfo failed", "error", err)
|
|
return &UserClaimInfo{}
|
|
}
|
|
return &UserClaimInfo{
|
|
From: l2sentMsg.Sender,
|
|
To: l2sentMsg.Target,
|
|
Value: l2sentMsg.Value,
|
|
Nonce: strconv.FormatUint(l2sentMsg.Nonce, 10),
|
|
Message: l2sentMsg.MsgData,
|
|
Proof: "0x" + l2sentMsg.MsgProof,
|
|
BatchHash: batch.BatchHash,
|
|
BatchIndex: strconv.FormatUint(l2sentMsg.BatchIndex, 10),
|
|
}
|
|
|
|
}
|
|
|
|
func updateCrossTxHash(msgHash string, txInfo *TxHistoryInfo, db db.OrmFactory) {
|
|
relayed, err := db.GetRelayedMsgByHash(msgHash)
|
|
if err != nil {
|
|
log.Error("updateCrossTxHash failed", "error", err)
|
|
return
|
|
}
|
|
if relayed == nil {
|
|
return
|
|
}
|
|
if relayed.Layer1Hash != "" {
|
|
txInfo.FinalizeTx.Hash = relayed.Layer1Hash
|
|
txInfo.FinalizeTx.BlockNumber = relayed.Height
|
|
return
|
|
}
|
|
if relayed.Layer2Hash != "" {
|
|
txInfo.FinalizeTx.Hash = relayed.Layer2Hash
|
|
txInfo.FinalizeTx.BlockNumber = relayed.Height
|
|
return
|
|
}
|
|
|
|
}
|
|
|
|
func (h *historyBackend) GetTxsByAddress(address common.Address, offset int64, limit int64) ([]*TxHistoryInfo, uint64, error) {
|
|
var txHistories []*TxHistoryInfo
|
|
total, err := h.db.GetTotalCrossMsgCountByAddress(address.String())
|
|
if err != nil || total == 0 {
|
|
return txHistories, 0, err
|
|
}
|
|
result, err := h.db.GetCrossMsgsByAddressWithOffset(address.String(), offset, limit)
|
|
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
for _, msg := range result {
|
|
txHistory := &TxHistoryInfo{
|
|
Hash: msg.Layer1Hash + msg.Layer2Hash,
|
|
Amount: msg.Amount,
|
|
To: msg.Target,
|
|
IsL1: msg.MsgType == int(orm.Layer1Msg),
|
|
BlockNumber: msg.Height,
|
|
BlockTimestamp: msg.Timestamp,
|
|
CreatedAt: msg.CreatedAt,
|
|
FinalizeTx: &Finalized{
|
|
Hash: "",
|
|
},
|
|
ClaimInfo: GetCrossTxClaimInfo(msg.MsgHash, h.db),
|
|
}
|
|
updateCrossTxHash(msg.MsgHash, txHistory, h.db)
|
|
txHistories = append(txHistories, txHistory)
|
|
}
|
|
return txHistories, total, nil
|
|
}
|
|
|
|
func (h *historyBackend) GetTxsByHashes(hashes []string) ([]*TxHistoryInfo, error) {
|
|
txHistories := make([]*TxHistoryInfo, 0)
|
|
for _, hash := range hashes {
|
|
l1result, err := h.db.GetL1CrossMsgByHash(common.HexToHash(hash))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if l1result != nil {
|
|
txHistory := &TxHistoryInfo{
|
|
Hash: l1result.Layer1Hash,
|
|
Amount: l1result.Amount,
|
|
To: l1result.Target,
|
|
IsL1: true,
|
|
BlockNumber: l1result.Height,
|
|
BlockTimestamp: l1result.Timestamp,
|
|
CreatedAt: l1result.CreatedAt,
|
|
FinalizeTx: &Finalized{
|
|
Hash: "",
|
|
},
|
|
}
|
|
updateCrossTxHash(l1result.MsgHash, txHistory, h.db)
|
|
txHistories = append(txHistories, txHistory)
|
|
continue
|
|
}
|
|
l2result, err := h.db.GetL2CrossMsgByHash(common.HexToHash(hash))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if l2result != nil {
|
|
txHistory := &TxHistoryInfo{
|
|
Hash: l2result.Layer2Hash,
|
|
Amount: l2result.Amount,
|
|
To: l2result.Target,
|
|
IsL1: false,
|
|
BlockNumber: l2result.Height,
|
|
BlockTimestamp: l2result.Timestamp,
|
|
CreatedAt: l2result.CreatedAt,
|
|
FinalizeTx: &Finalized{
|
|
Hash: "",
|
|
},
|
|
ClaimInfo: GetCrossTxClaimInfo(l2result.MsgHash, h.db),
|
|
}
|
|
updateCrossTxHash(l2result.MsgHash, txHistory, h.db)
|
|
txHistories = append(txHistories, txHistory)
|
|
continue
|
|
}
|
|
}
|
|
return txHistories, nil
|
|
}
|