From a5ca547961803e8b834d50259b5087bbcf1c1bbd Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Sat, 16 Dec 2023 23:33:02 +0800 Subject: [PATCH] bug fixes --- .../internal/controller/fetcher/l2_fetcher.go | 18 +++++++++------ .../internal/logic/history_logic.go | 14 +++++------ .../internal/orm/cross_message.go | 16 +++++++++---- bridge-history-api/internal/types/types.go | 23 +++++++++---------- .../internal/utils/withdraw_trie.go | 1 + 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/bridge-history-api/internal/controller/fetcher/l2_fetcher.go b/bridge-history-api/internal/controller/fetcher/l2_fetcher.go index 664df825cc..e2dc2c6dd7 100644 --- a/bridge-history-api/internal/controller/fetcher/l2_fetcher.go +++ b/bridge-history-api/internal/controller/fetcher/l2_fetcher.go @@ -119,14 +119,18 @@ func (c *L2MessageFetcher) updateL2WithdrawMessageProofs(ctx context.Context, l2 messageHashes[i] = common.HexToHash(message.MessageHash) } - proofs := withdrawTrie.AppendMessages(messageHashes) - if len(l2WithdrawMessages) != len(proofs) { - log.Error("invalid proof array length", "L2 withdrawal messages length", len(l2WithdrawMessages), "proofs length", len(proofs)) - return fmt.Errorf("invalid proof array length: got %d proofs for %d l2WithdrawMessages", len(proofs), len(l2WithdrawMessages)) - } + for i, messageHash := range messageHashes { + proof := withdrawTrie.AppendMessages([]common.Hash{messageHash}) + if err != nil { + log.Error("error generating proof", "messageHash", messageHash, "error", err) + return fmt.Errorf("error generating proof for messageHash %s: %v", messageHash, err) + } - for i, proof := range proofs { - l2WithdrawMessages[i].MerkleProof = proof + if len(proof) != 1 { + log.Error("invalid proof len", "got", len(proof), "expected", 1) + return fmt.Errorf("invalid proof len, got: %v, expected: 1", len(proof)) + } + l2WithdrawMessages[i].MerkleProof = proof[0] } // Verify if local info is correct. diff --git a/bridge-history-api/internal/logic/history_logic.go b/bridge-history-api/internal/logic/history_logic.go index d50dc51025..4da4dd7767 100644 --- a/bridge-history-api/internal/logic/history_logic.go +++ b/bridge-history-api/internal/logic/history_logic.go @@ -255,13 +255,13 @@ func (h *HistoryLogic) GetTxsByHashes(ctx context.Context, txHashes []string) ([ func getTxHistoryInfo(message *orm.CrossMessage) *types.TxHistoryInfo { txHistory := &types.TxHistoryInfo{ - MsgHash: message.MessageHash, - Amount: message.TokenAmounts, - L1Token: message.L1TokenAddress, - L2Token: message.L2TokenAddress, - IsL1: orm.MessageType(message.MessageType) == orm.MessageTypeL1SentMessage, - TxStatus: message.TxStatus, - CreatedAt: &message.CreatedAt, + MsgHash: message.MessageHash, + Amount: message.TokenAmounts, + L1Token: message.L1TokenAddress, + L2Token: message.L2TokenAddress, + IsL1: orm.MessageType(message.MessageType) == orm.MessageTypeL1SentMessage, + TxStatus: message.TxStatus, + BlockTimestamp: message.BlockTimestamp, } if txHistory.IsL1 { txHistory.Hash = message.L1TxHash diff --git a/bridge-history-api/internal/orm/cross_message.go b/bridge-history-api/internal/orm/cross_message.go index e1b690a396..826e8267d1 100644 --- a/bridge-history-api/internal/orm/cross_message.go +++ b/bridge-history-api/internal/orm/cross_message.go @@ -38,8 +38,14 @@ type TxStatusType int // Constants for TxStatusType. const ( - TxStatusTypeUnknown TxStatusType = iota - TxStatusTypeSent + // TxStatusTypeSent is one of the initial statuses for cross-chain messages (the other one is TxStatusTypeSentFailed). + // It is used as the default value to prevent overwriting the transaction status in scenarios where the message status might change + // from a later status (e.g., relayed) back to "sent". + // Example flow: + // 1. A relayed message is processed, setting tx_status to TxStatusTypeRelayed. + // 2. If a sent message is later processed for the same cross-chain message, the tx_status + // should remain as TxStatusTypeRelayed and not be modified back to TxStatusTypeSent. + TxStatusTypeSent TxStatusType = iota TxStatusTypeSentFailed TxStatusTypeRelayed // FailedRelayedMessage event: encoded tx failed, cannot retry. e.g., https://sepolia.scrollscan.com/tx/0xfc7d3ea5ec8dc9b664a5a886c3b33d21e665355057601033481a439498efb79a @@ -277,9 +283,10 @@ func (c *CrossMessage) InsertOrUpdateL1Messages(ctx context.Context, messages [] } db = db.WithContext(ctx) db = db.Model(&CrossMessage{}) + // 'tx_status' column is not explicitly assigned during the update to prevent a later status from being overwritten back to "sent". db = db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "message_hash"}}, - DoUpdates: clause.AssignmentColumns([]string{"sender", "receiver", "token_type", "l1_block_number", "l1_tx_hash", "l1_token_address", "l2_token_address", "token_ids", "token_amounts", "message_type", "tx_status", "block_timestamp", "message_nonce"}), + DoUpdates: clause.AssignmentColumns([]string{"sender", "receiver", "token_type", "l1_block_number", "l1_tx_hash", "l1_token_address", "l2_token_address", "token_ids", "token_amounts", "message_type", "block_timestamp", "message_nonce"}), }) if err := db.Create(messages).Error; err != nil { return fmt.Errorf("failed to insert message, error: %w", err) @@ -298,9 +305,10 @@ func (c *CrossMessage) InsertOrUpdateL2Messages(ctx context.Context, messages [] } db = db.WithContext(ctx) db = db.Model(&CrossMessage{}) + // 'tx_status' column is not explicitly assigned during the update to prevent a later status from being overwritten back to "sent". db = db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "message_hash"}}, - DoUpdates: clause.AssignmentColumns([]string{"sender", "receiver", "token_type", "l2_block_number", "l2_tx_hash", "l1_token_address", "l2_token_address", "token_ids", "token_amounts", "message_type", "tx_status", "block_timestamp", "message_from", "message_to", "message_value", "message_data", "merkle_proof", "message_nonce"}), + DoUpdates: clause.AssignmentColumns([]string{"sender", "receiver", "token_type", "l2_block_number", "l2_tx_hash", "l1_token_address", "l2_token_address", "token_ids", "token_amounts", "message_type", "block_timestamp", "message_from", "message_to", "message_value", "message_data", "merkle_proof", "message_nonce"}), }) if err := db.Create(messages).Error; err != nil { return fmt.Errorf("failed to insert message, error: %w", err) diff --git a/bridge-history-api/internal/types/types.go b/bridge-history-api/internal/types/types.go index 6760be1cb6..d15e6a89f7 100644 --- a/bridge-history-api/internal/types/types.go +++ b/bridge-history-api/internal/types/types.go @@ -2,7 +2,6 @@ package types import ( "net/http" - "time" "github.com/gin-gonic/gin" ) @@ -69,17 +68,17 @@ type UserClaimInfo struct { // TxHistoryInfo the schema of tx history infos type TxHistoryInfo struct { - Hash string `json:"hash"` - MsgHash string `json:"msgHash"` - Amount string `json:"amount"` - IsL1 bool `json:"isL1"` - L1Token string `json:"l1Token"` - L2Token string `json:"l2Token"` - BlockNumber uint64 `json:"blockNumber"` - TxStatus int `json:"txStatus"` - FinalizeTx *Finalized `json:"finalizeTx"` - ClaimInfo *UserClaimInfo `json:"claimInfo"` - CreatedAt *time.Time `json:"createdTime"` + Hash string `json:"hash"` + MsgHash string `json:"msgHash"` + Amount string `json:"amount"` + IsL1 bool `json:"isL1"` + L1Token string `json:"l1Token"` + L2Token string `json:"l2Token"` + BlockNumber uint64 `json:"blockNumber"` + TxStatus int `json:"txStatus"` + FinalizeTx *Finalized `json:"finalizeTx"` + ClaimInfo *UserClaimInfo `json:"claimInfo"` + BlockTimestamp uint64 `json:"blockTimestamp"` } // RenderJSON renders response with json diff --git a/bridge-history-api/internal/utils/withdraw_trie.go b/bridge-history-api/internal/utils/withdraw_trie.go index 98af808ce8..37f0667aff 100644 --- a/bridge-history-api/internal/utils/withdraw_trie.go +++ b/bridge-history-api/internal/utils/withdraw_trie.go @@ -46,6 +46,7 @@ func (w *WithdrawTrie) Initialize(currentMessageNonce uint64, msgHash common.Has } // AppendMessages appends a list of new messages as leaf nodes to the rightest of the tree and returns the proofs for all messages. +// FIXME: The former proofs are wrong when inserting multiple messages. func (w *WithdrawTrie) AppendMessages(hashes []common.Hash) [][]byte { length := len(hashes) if length == 0 {