package consumer import ( "context" "errors" "time" "github.com/wormhole-foundation/wormhole-explorer/common/domain" "github.com/wormhole-foundation/wormhole-explorer/txtracker/chains" "github.com/wormhole-foundation/wormhole-explorer/txtracker/config" sdk "github.com/wormhole-foundation/wormhole/sdk/vaa" "go.uber.org/zap" ) // ProcessSourceTxParams is a struct that contains the parameters for the ProcessSourceTx method. type ProcessSourceTxParams struct { ChainId sdk.ChainID VaaId string Emitter string Sequence string TxHash string } func ProcessSourceTx( ctx context.Context, logger *zap.Logger, rpcServiceProviderSettings *config.RpcProviderSettings, repository *Repository, params *ProcessSourceTxParams, ) error { // Get transaction details from the emitter blockchain // // If the transaction is not found, will retry a few times before giving up. var txStatus domain.SourceTxStatus var txDetail *chains.TxDetail var err error for attempts := 1; attempts <= maxAttempts; attempts++ { txDetail, err = chains.FetchTx(ctx, rpcServiceProviderSettings, params.ChainId, params.TxHash) switch { // If the transaction is not found, retry after a delay case errors.Is(err, chains.ErrTransactionNotFound): txStatus = domain.SourceTxStatusInternalError logger.Warn("transaction not found, will retry after a delay", zap.String("vaaId", params.VaaId), zap.Duration("retryDelay", retryDelay), zap.Int("attempts", attempts), zap.Int("maxAttempts", maxAttempts), ) time.Sleep(retryDelay) continue // If the chain ID is not supported, we're done. case errors.Is(err, chains.ErrChainNotSupported): return err // If the context was cancelled, do not attempt to save the result on the database case errors.Is(err, context.Canceled): return err // If there is an internal error, give up case err != nil: logger.Error("Failed to fetch source transaction details", zap.String("vaaId", params.VaaId), zap.Error(err), ) txStatus = domain.SourceTxStatusInternalError break // Success case err == nil: txStatus = domain.SourceTxStatusConfirmed break } } // Store source transaction details in the database p := UpsertDocumentParams{ VaaId: params.VaaId, ChainId: params.ChainId, TxDetail: txDetail, TxStatus: txStatus, } return repository.UpsertDocument(ctx, &p) }