diff --git a/internal/data/models.sqlc.gen.go b/internal/data/models.sqlc.gen.go index b1c7852..ba47d06 100644 --- a/internal/data/models.sqlc.gen.go +++ b/internal/data/models.sqlc.gen.go @@ -21,6 +21,7 @@ const ( TxStatusValPending TxStatusVal = "pending" TxStatusValShieldedinclusion TxStatusVal = "shielded inclusion" TxStatusValUnshieldedinclusion TxStatusVal = "unshielded inclusion" + TxStatusValInvalidfeetoolow TxStatusVal = "invalid fee too low" ) func (e *TxStatusVal) Scan(src interface{}) error { @@ -191,7 +192,6 @@ type TransactionSubmittedEventsSyncedUntil struct { } type ValidatorGraffiti struct { - ID int64 ValidatorIndex pgtype.Int8 Graffiti string BlockNumber int64 diff --git a/internal/metrics/tx_mapper_db.go b/internal/metrics/tx_mapper_db.go index d77c4df..adc84a5 100644 --- a/internal/metrics/tx_mapper_db.go +++ b/internal/metrics/tx_mapper_db.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "math" + "strings" "sync" "time" @@ -31,6 +32,8 @@ import ( const ReceiptWaitTimeout = 1 * time.Hour +var errSendTransaction = errors.New("send transaction failed") + type TxMapperDB struct { db *pgxpool.Pool dbQuery *data.Queries @@ -117,8 +120,8 @@ func (tm *TxMapperDB) AddDecryptionKeysAndMessages( if err != nil { return err } - if len(decryptionKeyIDs) == 0 { - log.Debug().Msg("no decryption key was added") + if len(decryptionKeyIDs) == 0 || len(decryptionKeyIDs) != len(slots) { + log.Debug().Msg("no new decryption key was added") return nil } err = qtx.CreateDecryptionKeyMessages(ctx, data.CreateDecryptionKeyMessagesParams{ @@ -458,18 +461,22 @@ func (tm *TxMapperDB) processTransactionExecution( return } } else { + txStatus := data.TxStatusValInvalid + if isFeeTooLowError(err) { + txStatus = data.TxStatusValInvalidfeetoolow + } err := tm.dbQuery.CreateDecryptedTX(ctx, data.CreateDecryptedTXParams{ Slot: slot, TxIndex: txSubEvent.TxIndex, TxHash: decryptedTx.Hash().Bytes(), - TxStatus: data.TxStatusValInvalid, + TxStatus: txStatus, DecryptionKeyID: decryptionKeyID, TransactionSubmittedEventID: txSubEvent.ID, }) if err != nil { log.Err(err).Msg("failed to create decrypted tx") } - txErrorSignalCh <- fmt.Errorf("failed to send transaction: %w", err) + txErrorSignalCh <- fmt.Errorf("%w: %v", errSendTransaction, err) return } } else { @@ -498,6 +505,9 @@ func (tm *TxMapperDB) processTransactionExecution( receipt, err := tm.waitForReceiptWithTimeout(ctx, txHash, ReceiptWaitTimeout, txErrorSignalCh) if err != nil { log.Err(err).Msg("") + if errors.Is(err, errSendTransaction) { + return + } // update/create status to not included err := tm.dbQuery.UpsertTX(ctx, data.UpsertTXParams{ Slot: slot, @@ -748,6 +758,15 @@ func decryptTransaction(key []byte, encrypted []byte) (*types.Transaction, error return tx, nil } +func isFeeTooLowError(err error) bool { + if err == nil { + return false + } + return strings.Contains(strings.ToLower(err.Error()), "feetoolow") || + strings.Contains(strings.ToLower(err.Error()), "underpriced") || + strings.Contains(strings.ToLower(err.Error()), "maxfeepergaslessthanblockbasefee") +} + // waitForReceiptWithTimeout waits for a transaction receipt with a provided timeout. func (tm *TxMapperDB) waitForReceiptWithTimeout(ctx context.Context, txHash common.Hash, receiptWaitTimeout time.Duration, txErrorSignalCh chan error) (*types.Receipt, error) { ctx, cancel := context.WithTimeout(ctx, receiptWaitTimeout) diff --git a/migrations/20260115175310_add_tx_status_invalid_fee_too_low.sql b/migrations/20260115175310_add_tx_status_invalid_fee_too_low.sql new file mode 100644 index 0000000..9334c36 --- /dev/null +++ b/migrations/20260115175310_add_tx_status_invalid_fee_too_low.sql @@ -0,0 +1,8 @@ +-- +goose Up +-- +goose StatementBegin +ALTER TYPE tx_status_val ADD VALUE 'invalid fee too low'; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +-- +goose StatementEnd