71 lines
2.5 KiB
Go
71 lines
2.5 KiB
Go
package watcher
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
|
|
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
|
|
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var (
|
|
ErrTxfailedCannotBeUpdated = errors.New("tx with status failed can not be updated because exists a confirmed tx for the same vaa ID")
|
|
ErrTxUnknowCannotBeUpdated = errors.New("tx with status unknown can not be updated because exists a tx (confirmed|failed) for the same vaa ID")
|
|
ErrInvalidTxStatus = errors.New("invalid tx status")
|
|
)
|
|
|
|
type FuncGetGlobalTransactionById func(ctx context.Context, id string) (storage.TransactionUpdate, error)
|
|
|
|
func updateGlobalTransaction(ctx context.Context, chainID sdk.ChainID, tx storage.TransactionUpdate, r *storage.Repository, log *zap.Logger) {
|
|
updateGlobalTx, err := checkTxShouldBeUpdated(ctx, tx, r.GetGlobalTransactionByID)
|
|
if !updateGlobalTx {
|
|
log.Info("tx can not be updated",
|
|
zap.String("id", tx.ID),
|
|
zap.String("txHash", tx.Destination.TxHash),
|
|
zap.String("status", tx.Destination.Status),
|
|
zap.Error(err))
|
|
return
|
|
}
|
|
|
|
err = r.UpsertGlobalTransaction(ctx, chainID, tx)
|
|
if err != nil {
|
|
log.Error("cannot save redeemed tx", zap.Error(err))
|
|
} else {
|
|
log.Info("saved redeemed tx", zap.String("vaa", tx.ID))
|
|
}
|
|
}
|
|
|
|
// checkTxShouldBeUpdated checks if the transaction should be updated.
|
|
func checkTxShouldBeUpdated(ctx context.Context, tx storage.TransactionUpdate, getGlobalTransactionByIDFunc FuncGetGlobalTransactionById) (bool, error) {
|
|
switch tx.Destination.Status {
|
|
case domain.DstTxStatusConfirmed:
|
|
return true, nil
|
|
case domain.DstTxStatusFailedToProcess:
|
|
// check if the transaction exists from the same vaa ID.
|
|
oldTx, err := getGlobalTransactionByIDFunc(ctx, tx.ID)
|
|
if err != nil {
|
|
return true, nil
|
|
}
|
|
// if the transaction was already confirmed, then no update it.
|
|
if oldTx.Destination.Status == domain.DstTxStatusConfirmed {
|
|
return false, ErrTxfailedCannotBeUpdated
|
|
}
|
|
return true, nil
|
|
case domain.DstTxStatusUnkonwn:
|
|
// check if the transaction exists from the same vaa ID.
|
|
oldTx, err := getGlobalTransactionByIDFunc(ctx, tx.ID)
|
|
if err != nil {
|
|
return true, nil
|
|
}
|
|
// if the transaction was already confirmed or failed to process, then no update it.
|
|
if oldTx.Destination.Status == domain.DstTxStatusConfirmed || oldTx.Destination.Status == domain.DstTxStatusFailedToProcess {
|
|
return false, ErrTxUnknowCannotBeUpdated
|
|
}
|
|
return true, nil
|
|
default:
|
|
return false, ErrInvalidTxStatus
|
|
}
|
|
}
|