From 1032ba3ae823442732d9007ca8e479ca9debd350 Mon Sep 17 00:00:00 2001 From: Jim W Date: Mon, 4 Dec 2023 20:05:11 -0500 Subject: [PATCH] remove pkgerrors dependency from common pkg (#11479) * remove pkgerrors dependency from common pkg * fix naming inconsistencies * clean up error return * clean up error return and remove use of Unwrap --- common/client/multi_node.go | 7 +-- common/client/multi_node_test.go | 2 +- common/client/node.go | 10 ++-- common/client/node_lifecycle.go | 2 +- common/client/node_lifecycle_test.go | 2 +- common/client/send_only_node_test.go | 2 +- common/fee/models.go | 12 ++-- common/fee/utils.go | 4 +- common/headtracker/head_listener.go | 5 +- common/headtracker/head_tracker.go | 12 ++-- common/txmgr/broadcaster.go | 50 ++++++++--------- common/txmgr/confirmer.go | 83 ++++++++++++++-------------- common/txmgr/strategies.go | 4 +- common/txmgr/types/tx.go | 14 ++++- 14 files changed, 110 insertions(+), 99 deletions(-) diff --git a/common/client/multi_node.go b/common/client/multi_node.go index db5380e91f5..dfd6585b642 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -7,7 +7,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -166,12 +165,12 @@ func NewMultiNode[ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) Dial(ctx context.Context) error { return c.StartOnce("MultiNode", func() (merr error) { if len(c.nodes) == 0 { - return errors.Errorf("no available nodes for chain %s", c.chainID.String()) + return fmt.Errorf("no available nodes for chain %s", c.chainID.String()) } var ms services.MultiStart for _, n := range c.nodes { if n.ConfiguredChainID().String() != c.chainID.String() { - return ms.CloseBecause(errors.Errorf("node %s has configured chain ID %s which does not match multinode configured chain ID of %s", n.String(), n.ConfiguredChainID().String(), c.chainID.String())) + return ms.CloseBecause(fmt.Errorf("node %s has configured chain ID %s which does not match multinode configured chain ID of %s", n.String(), n.ConfiguredChainID().String(), c.chainID.String())) } rawNode, ok := n.(*node[CHAIN_ID, HEAD, RPC_CLIENT]) if ok { @@ -188,7 +187,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } for _, s := range c.sendonlys { if s.ConfiguredChainID().String() != c.chainID.String() { - return ms.CloseBecause(errors.Errorf("sendonly node %s has configured chain ID %s which does not match multinode configured chain ID of %s", s.String(), s.ConfiguredChainID().String(), c.chainID.String())) + return ms.CloseBecause(fmt.Errorf("sendonly node %s has configured chain ID %s which does not match multinode configured chain ID of %s", s.String(), s.ConfiguredChainID().String(), c.chainID.String())) } if err := ms.Start(ctx, s); err != nil { return err diff --git a/common/client/multi_node_test.go b/common/client/multi_node_test.go index 229f1320a14..82af7411080 100644 --- a/common/client/multi_node_test.go +++ b/common/client/multi_node_test.go @@ -1,13 +1,13 @@ package client import ( + "errors" "fmt" big "math/big" "math/rand" "testing" "time" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/common/client/node.go b/common/client/node.go index 4fad18b42cf..ce144bbca86 100644 --- a/common/client/node.go +++ b/common/client/node.go @@ -2,13 +2,13 @@ package client import ( "context" + "errors" "fmt" "math/big" "net/url" "sync" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -256,15 +256,15 @@ func (n *node[CHAIN_ID, HEAD, RPC]) verify(callerCtx context.Context) (err error var chainID CHAIN_ID if chainID, err = n.rpc.ChainID(callerCtx); err != nil { promFailed() - return errors.Wrapf(err, "failed to verify chain ID for node %s", n.name) + return fmt.Errorf("failed to verify chain ID for node %s: %w", n.name, err) } else if chainID.String() != n.chainID.String() { promFailed() - return errors.Wrapf( - errInvalidChainID, - "rpc ChainID doesn't match local chain ID: RPC ID=%s, local ID=%s, node name=%s", + return fmt.Errorf( + "rpc ChainID doesn't match local chain ID: RPC ID=%s, local ID=%s, node name=%s: %w", chainID.String(), n.chainID.String(), n.name, + errInvalidChainID, ) } diff --git a/common/client/node_lifecycle.go b/common/client/node_lifecycle.go index 59a59691c83..5ba0bff3238 100644 --- a/common/client/node_lifecycle.go +++ b/common/client/node_lifecycle.go @@ -2,12 +2,12 @@ package client import ( "context" + "errors" "fmt" "math" "math/big" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" diff --git a/common/client/node_lifecycle_test.go b/common/client/node_lifecycle_test.go index 224b79d8378..bf94e6bd063 100644 --- a/common/client/node_lifecycle_test.go +++ b/common/client/node_lifecycle_test.go @@ -1,13 +1,13 @@ package client import ( + "errors" "fmt" big "math/big" "sync/atomic" "testing" "github.com/cometbft/cometbft/libs/rand" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "go.uber.org/zap" diff --git a/common/client/send_only_node_test.go b/common/client/send_only_node_test.go index 459f923cba8..79f4bfd60e3 100644 --- a/common/client/send_only_node_test.go +++ b/common/client/send_only_node_test.go @@ -1,11 +1,11 @@ package client import ( + "errors" "fmt" "net/url" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/common/fee/models.go b/common/fee/models.go index b843cc3f055..1fe4d2b053b 100644 --- a/common/fee/models.go +++ b/common/fee/models.go @@ -1,10 +1,10 @@ package fee import ( + "errors" + "fmt" "math/big" - "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink-common/pkg/logger" bigmath "github.com/smartcontractkit/chainlink-common/pkg/utils/big_math" "github.com/smartcontractkit/chainlink/v2/common/chains/label" @@ -47,15 +47,15 @@ func CalculateBumpedFee( bumpedFeePrice = maxFee(lggr, currentfeePrice, bumpedFeePrice, maxFeePrice, "fee price", toChainUnit) if bumpedFeePrice.Cmp(maxFeePrice) > 0 { - return maxFeePrice, errors.Wrapf(ErrBumpFeeExceedsLimit, "bumped fee price of %s would exceed configured max fee price of %s (original price was %s). %s", - toChainUnit(bumpedFeePrice), toChainUnit(maxFeePrice), toChainUnit(originalfeePrice), label.NodeConnectivityProblemWarning) + return maxFeePrice, fmt.Errorf("bumped fee price of %s would exceed configured max fee price of %s (original price was %s). %s: %w", + toChainUnit(bumpedFeePrice), toChainUnit(maxFeePrice), toChainUnit(originalfeePrice), label.NodeConnectivityProblemWarning, ErrBumpFeeExceedsLimit) } else if bumpedFeePrice.Cmp(originalfeePrice) == 0 { // NOTE: This really shouldn't happen since we enforce minimums for // FeeEstimator.BumpPercent and FeeEstimator.BumpMin in the config validation, // but it's here anyway for a "belts and braces" approach - return bumpedFeePrice, errors.Wrapf(ErrBump, "bumped fee price of %s is equal to original fee price of %s."+ + return bumpedFeePrice, fmt.Errorf("bumped fee price of %s is equal to original fee price of %s."+ " ACTION REQUIRED: This is a configuration error, you must increase either "+ - "FeeEstimator.BumpPercent or FeeEstimator.BumpMin", toChainUnit(bumpedFeePrice), toChainUnit(bumpedFeePrice)) + "FeeEstimator.BumpPercent or FeeEstimator.BumpMin: %w", toChainUnit(bumpedFeePrice), toChainUnit(bumpedFeePrice), ErrBump) } return bumpedFeePrice, nil } diff --git a/common/fee/utils.go b/common/fee/utils.go index 71ababddbe3..eeb2c966719 100644 --- a/common/fee/utils.go +++ b/common/fee/utils.go @@ -1,10 +1,10 @@ package fee import ( + "fmt" "math" "math/big" - "github.com/pkg/errors" "github.com/shopspring/decimal" ) @@ -12,7 +12,7 @@ func ApplyMultiplier(feeLimit uint32, multiplier float32) (uint32, error) { result := decimal.NewFromBigInt(big.NewInt(0).SetUint64(uint64(feeLimit)), 0).Mul(decimal.NewFromFloat32(multiplier)).IntPart() if result > math.MaxUint32 { - return 0, errors.Errorf("integer overflow when applying multiplier of %f to fee limit of %d", multiplier, feeLimit) + return 0, fmt.Errorf("integer overflow when applying multiplier of %f to fee limit of %d", multiplier, feeLimit) } return uint32(result), nil } diff --git a/common/headtracker/head_listener.go b/common/headtracker/head_listener.go index 2013895d0b8..0aebf606634 100644 --- a/common/headtracker/head_listener.go +++ b/common/headtracker/head_listener.go @@ -2,10 +2,11 @@ package headtracker import ( "context" + "errors" + "fmt" "sync/atomic" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -202,7 +203,7 @@ func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) subscribeToHead(ctx context.Cont hl.headSubscription, err = hl.client.SubscribeNewHead(ctx, hl.chHeaders) if err != nil { close(hl.chHeaders) - return errors.Wrap(err, "Client#SubscribeNewHead") + return fmt.Errorf("Client#SubscribeNewHead: %w", err) } hl.connected.Store(true) diff --git a/common/headtracker/head_tracker.go b/common/headtracker/head_tracker.go index 6e379776c0f..c977eb023cc 100644 --- a/common/headtracker/head_tracker.go +++ b/common/headtracker/head_tracker.go @@ -2,11 +2,11 @@ package headtracker import ( "context" + "errors" "fmt" "sync" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -123,7 +123,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Start(ctx context.Context) error ht.log.Errorw("Error getting initial head", "err", err) } else if initialHead.IsValid() { if err := ht.handleNewHead(ctx, initialHead); err != nil { - return errors.Wrap(err, "error handling initial head") + return fmt.Errorf("error handling initial head: %w", err) } } else { ht.log.Debug("Got nil initial head") @@ -179,7 +179,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) LatestChain() HTH { func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) getInitialHead(ctx context.Context) (HTH, error) { head, err := ht.client.HeadByNumber(ctx, nil) if err != nil { - return ht.getNilHead(), errors.Wrap(err, "failed to fetch initial head") + return ht.getNilHead(), fmt.Errorf("failed to fetch initial head: %w", err) } loggerFields := []interface{}{"head", head} if head.IsValid() { @@ -204,7 +204,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context if ctx.Err() != nil { return nil } else if err != nil { - return errors.Wrapf(err, "failed to save head: %#v", head) + return fmt.Errorf("failed to save head: %#v: %w", head, err) } if !prevHead.IsValid() || head.BlockNumber() > prevHead.BlockNumber() { @@ -212,7 +212,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context headWithChain := ht.headSaver.Chain(head.BlockHash()) if !headWithChain.IsValid() { - return errors.Errorf("HeadTracker#handleNewHighestHead headWithChain was unexpectedly nil") + return fmt.Errorf("HeadTracker#handleNewHighestHead headWithChain was unexpectedly nil") } ht.backfillMB.Deliver(headWithChain) ht.broadcastMB.Deliver(headWithChain) @@ -339,7 +339,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, hea ht.log.Debugw("context canceled, aborting backfill", "err", err, "ctx.Err", ctx.Err()) break } else if err != nil { - return errors.Wrap(err, "fetchAndSaveHead failed") + return fmt.Errorf("fetchAndSaveHead failed: %w", err) } } return diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 54ae653f662..f10ecafc670 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -3,13 +3,13 @@ package txmgr import ( "context" "database/sql" + "errors" "fmt" "slices" "sync" "time" "github.com/jpillora/backoff" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "go.uber.org/multierr" @@ -210,7 +210,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) star var err error eb.enabledAddresses, err = eb.ks.EnabledAddressesForChain(eb.chainID) if err != nil { - return errors.Wrap(err, "Broadcaster: failed to load EnabledAddressesForChain") + return fmt.Errorf("Broadcaster: failed to load EnabledAddressesForChain: %w", err) } if len(eb.enabledAddresses) > 0 { @@ -246,7 +246,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) clos eb.initSync.Lock() defer eb.initSync.Unlock() if !eb.isStarted { - return errors.Wrap(services.ErrAlreadyStopped, "Broadcaster is not started") + return fmt.Errorf("Broadcaster is not started: %w", services.ErrAlreadyStopped) } close(eb.chStop) eb.wg.Wait() @@ -454,19 +454,19 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) proc err, retryable = eb.handleAnyInProgressTx(ctx, fromAddress) if err != nil { - return retryable, errors.Wrap(err, "processUnstartedTxs failed on handleAnyInProgressTx") + return retryable, fmt.Errorf("processUnstartedTxs failed on handleAnyInProgressTx: %w", err) } for { maxInFlightTransactions := eb.txConfig.MaxInFlight() if maxInFlightTransactions > 0 { nUnconfirmed, err := eb.txStore.CountUnconfirmedTransactions(ctx, fromAddress, eb.chainID) if err != nil { - return true, errors.Wrap(err, "CountUnconfirmedTransactions failed") + return true, fmt.Errorf("CountUnconfirmedTransactions failed: %w", err) } if nUnconfirmed >= maxInFlightTransactions { nUnstarted, err := eb.txStore.CountUnstartedTransactions(ctx, fromAddress, eb.chainID) if err != nil { - return true, errors.Wrap(err, "CountUnstartedTransactions failed") + return true, fmt.Errorf("CountUnstartedTransactions failed: %w", err) } eb.lggr.Warnw(fmt.Sprintf(`Transaction throttling; %d transactions in-flight and %d unstarted transactions pending (maximum number of in-flight transactions is %d per key). %s`, nUnconfirmed, nUnstarted, maxInFlightTransactions, label.MaxInFlightTransactionsWarning), "maxInFlightTransactions", maxInFlightTransactions, "nUnconfirmed", nUnconfirmed, "nUnstarted", nUnstarted) select { @@ -479,7 +479,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) proc } etx, err := eb.nextUnstartedTransactionWithSequence(fromAddress) if err != nil { - return true, errors.Wrap(err, "processUnstartedTxs failed on nextUnstartedTransactionWithSequence") + return true, fmt.Errorf("processUnstartedTxs failed on nextUnstartedTransactionWithSequence: %w", err) } if etx == nil { return false, nil @@ -489,18 +489,18 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) proc var retryable bool a, _, _, retryable, err = eb.NewTxAttempt(ctx, *etx, eb.lggr) if err != nil { - return retryable, errors.Wrap(err, "processUnstartedTxs failed on NewAttempt") + return retryable, fmt.Errorf("processUnstartedTxs failed on NewAttempt: %w", err) } if err := eb.txStore.UpdateTxUnstartedToInProgress(ctx, etx, &a); errors.Is(err, ErrTxRemoved) { eb.lggr.Debugw("tx removed", "txID", etx.ID, "subject", etx.Subject) continue } else if err != nil { - return true, errors.Wrap(err, "processUnstartedTxs failed on UpdateTxUnstartedToInProgress") + return true, fmt.Errorf("processUnstartedTxs failed on UpdateTxUnstartedToInProgress: %w", err) } if err, retryable := eb.handleInProgressTx(ctx, *etx, a, time.Now()); err != nil { - return retryable, errors.Wrap(err, "processUnstartedTxs failed on handleAnyInProgressTx") + return retryable, fmt.Errorf("processUnstartedTxs failed on handleInProgressTx: %w", err) } } } @@ -510,11 +510,11 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) proc func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) handleAnyInProgressTx(ctx context.Context, fromAddress ADDR) (err error, retryable bool) { etx, err := eb.txStore.GetTxInProgress(ctx, fromAddress) if err != nil { - return errors.Wrap(err, "handleAnyInProgressTx failed"), true + return fmt.Errorf("handleAnyInProgressTx failed: %w", err), true } if etx != nil { if err, retryable := eb.handleInProgressTx(ctx, *etx, etx.TxAttempts[0], etx.CreatedAt); err != nil { - return errors.Wrap(err, "handleAnyInProgressTx failed"), retryable + return fmt.Errorf("handleAnyInProgressTx failed: %w", err), retryable } } return nil, false @@ -524,17 +524,17 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand // Here we complete the job that we didn't finish last time. func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) handleInProgressTx(ctx context.Context, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time) (error, bool) { if etx.State != TxInProgress { - return errors.Errorf("invariant violation: expected transaction %v to be in_progress, it was %s", etx.ID, etx.State), false + return fmt.Errorf("invariant violation: expected transaction %v to be in_progress, it was %s", etx.ID, etx.State), false } checkerSpec, err := etx.GetChecker() if err != nil { - return errors.Wrap(err, "parsing transmit checker"), false + return fmt.Errorf("parsing transmit checker: %w", err), false } checker, err := eb.checkerFactory.BuildChecker(checkerSpec) if err != nil { - return errors.Wrap(err, "building transmit checker"), false + return fmt.Errorf("building transmit checker: %w", err), false } lgr := etx.GetLogger(logger.With(eb.lggr, "fee", attempt.TxFee)) @@ -659,7 +659,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand nextSequence, e := eb.client.PendingSequenceAt(ctx, etx.FromAddress) if e != nil { err = multierr.Combine(e, err) - return errors.Wrapf(err, "failed to fetch latest pending sequence after encountering unknown RPC error while sending transaction"), true + return fmt.Errorf("failed to fetch latest pending sequence after encountering unknown RPC error while sending transaction: %w", err), true } if nextSequence.Int64() > (*etx.Sequence).Int64() { // Despite the error, the RPC node considers the previously sent @@ -686,7 +686,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand // // In all cases, the best thing we can do is go into a retry loop and keep // trying to send the transaction over again. - return errors.Wrapf(err, "retryable error while sending transaction %s (tx ID %d)", attempt.Hash.String(), etx.ID), true + return fmt.Errorf("retryable error while sending transaction %s (tx ID %d): %w", attempt.Hash.String(), etx.ID, err), true } } @@ -702,7 +702,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) next // Finish. No more transactions left to process. Hoorah! return nil, nil } - return nil, errors.Wrap(err, "findNextUnstartedTransactionFromAddress failed") + return nil, fmt.Errorf("findNextUnstartedTransactionFromAddress failed: %w", err) } sequence, err := eb.GetNextSequence(ctx, etx.FromAddress) @@ -726,7 +726,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA replacementAttempt, bumpedFee, bumpedFeeLimit, retryable, err := eb.NewBumpTxAttempt(ctx, etx, attempt, nil, lgr) if err != nil { - return errors.Wrap(err, "tryAgainBumpFee failed"), retryable + return fmt.Errorf("tryAgainBumpFee failed: %w", err), retryable } return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, bumpedFee, bumpedFeeLimit) @@ -734,14 +734,14 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryAgainWithNewEstimation(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time) (err error, retryable bool) { if attempt.TxType == 0x2 { - err = errors.Errorf("re-estimation is not supported for EIP-1559 transactions. Node returned error: %v. This is a bug", txError.Error()) + err = fmt.Errorf("re-estimation is not supported for EIP-1559 transactions. Node returned error: %v. This is a bug", txError.Error()) logger.Sugared(eb.lggr).AssumptionViolation(err.Error()) return err, false } replacementAttempt, fee, feeLimit, retryable, err := eb.NewTxAttemptWithType(ctx, etx, lgr, attempt.TxType, feetypes.OptForceRefetch) if err != nil { - return errors.Wrap(err, "tryAgainWithNewEstimation failed to build new attempt"), retryable + return fmt.Errorf("tryAgainWithNewEstimation failed to build new attempt: %w", err), retryable } lgr.Warnw("L2 rejected transaction due to incorrect fee, re-estimated and will try again", "etxID", etx.ID, "err", err, "newGasPrice", fee, "newGasLimit", feeLimit) @@ -751,7 +751,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint32) (err error, retyrable bool) { if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &replacementAttempt); err != nil { - return errors.Wrap(err, "tryAgainWithNewFee failed"), true + return fmt.Errorf("tryAgainWithNewFee failed: %w", err), true } lgr.Debugw("Bumped fee on initial send", "oldFee", attempt.TxFee.String(), "newFee", newFee.String(), "newFeeLimit", newFeeLimit) return eb.handleInProgressTx(ctx, etx, replacementAttempt, initialBroadcastAt) @@ -761,7 +761,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) save ctx, cancel := eb.chStop.NewCtx() defer cancel() if etx.State != TxInProgress { - return errors.Errorf("can only transition to fatal_error from in_progress, transaction is currently %s", etx.State) + return fmt.Errorf("can only transition to fatal_error from in_progress, transaction is currently %s", etx.State) } if !etx.Error.Valid { return errors.New("expected error field to be set") @@ -779,11 +779,11 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) save // is relatively benign and probably nobody will ever run into it in // practice, but something to be aware of. if etx.PipelineTaskRunID.Valid && eb.resumeCallback != nil && etx.SignalCallback { - err := eb.resumeCallback(etx.PipelineTaskRunID.UUID, nil, errors.Errorf("fatal error while sending transaction: %s", etx.Error.String)) + err := eb.resumeCallback(etx.PipelineTaskRunID.UUID, nil, fmt.Errorf("fatal error while sending transaction: %s", etx.Error.String)) if errors.Is(err, sql.ErrNoRows) { lgr.Debugw("callback missing or already resumed", "etxID", etx.ID) } else if err != nil { - return errors.Wrap(err, "failed to resume pipeline") + return fmt.Errorf("failed to resume pipeline: %w", err) } else { // Mark tx as having completed callback if err := eb.txStore.UpdateTxCallbackCompleted(ctx, etx.PipelineTaskRunID.UUID, eb.chainID); err != nil { diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index a56768ce206..95be9ad23e6 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -3,13 +3,13 @@ package txmgr import ( "context" "encoding/hex" + "errors" "fmt" "sort" "strconv" "sync" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "go.uber.org/multierr" @@ -201,7 +201,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sta var err error ec.enabledAddresses, err = ec.ks.EnabledAddressesForChain(ec.chainID) if err != nil { - return errors.Wrap(err, "Confirmer: failed to load EnabledAddressesForChain") + return fmt.Errorf("Confirmer: failed to load EnabledAddressesForChain: %w", err) } ec.ctx, ec.ctxCancel = context.WithCancel(context.Background()) @@ -223,7 +223,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) clo ec.initSync.Lock() defer ec.initSync.Unlock() if !ec.isStarted { - return errors.Wrap(utils.ErrAlreadyStopped, "Confirmer is not started") + return fmt.Errorf("Confirmer is not started: %w", utils.ErrAlreadyStopped) } ec.ctxCancel() ec.wg.Wait() @@ -281,28 +281,28 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) pro ec.lggr.Debugw("processHead start", "headNum", head.BlockNumber(), "id", "confirmer") if err := ec.txStore.SetBroadcastBeforeBlockNum(ctx, head.BlockNumber(), ec.chainID); err != nil { - return errors.Wrap(err, "SetBroadcastBeforeBlockNum failed") + return fmt.Errorf("SetBroadcastBeforeBlockNum failed: %w", err) } if err := ec.CheckConfirmedMissingReceipt(ctx); err != nil { - return errors.Wrap(err, "CheckConfirmedMissingReceipt failed") + return fmt.Errorf("CheckConfirmedMissingReceipt failed: %w", err) } if err := ec.CheckForReceipts(ctx, head.BlockNumber()); err != nil { - return errors.Wrap(err, "CheckForReceipts failed") + return fmt.Errorf("CheckForReceipts failed: %w", err) } ec.lggr.Debugw("Finished CheckForReceipts", "headNum", head.BlockNumber(), "time", time.Since(mark), "id", "confirmer") mark = time.Now() if err := ec.RebroadcastWhereNecessary(ctx, head.BlockNumber()); err != nil { - return errors.Wrap(err, "RebroadcastWhereNecessary failed") + return fmt.Errorf("RebroadcastWhereNecessary failed: %w", err) } ec.lggr.Debugw("Finished RebroadcastWhereNecessary", "headNum", head.BlockNumber(), "time", time.Since(mark), "id", "confirmer") mark = time.Now() if err := ec.EnsureConfirmedTransactionsInLongestChain(ctx, head); err != nil { - return errors.Wrap(err, "EnsureConfirmedTransactionsInLongestChain failed") + return fmt.Errorf("EnsureConfirmedTransactionsInLongestChain failed: %w", err) } ec.lggr.Debugw("Finished EnsureConfirmedTransactionsInLongestChain", "headNum", head.BlockNumber(), "time", time.Since(mark), "id", "confirmer") @@ -310,7 +310,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) pro if ec.resumeCallback != nil { mark = time.Now() if err := ec.ResumePendingTaskRuns(ctx, head); err != nil { - return errors.Wrap(err, "ResumePendingTaskRuns failed") + return fmt.Errorf("ResumePendingTaskRuns failed: %w", err) } ec.lggr.Debugw("Finished ResumePendingTaskRuns", "headNum", head.BlockNumber(), "time", time.Since(mark), "id", "confirmer") @@ -382,7 +382,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Che func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) CheckForReceipts(ctx context.Context, blockNum int64) error { attempts, err := ec.txStore.FindTxAttemptsRequiringReceiptFetch(ctx, ec.chainID) if err != nil { - return errors.Wrap(err, "FindTxAttemptsRequiringReceiptFetch failed") + return fmt.Errorf("FindTxAttemptsRequiringReceiptFetch failed: %w", err) } if len(attempts) == 0 { return nil @@ -398,7 +398,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Che for from, attempts := range attemptsByAddress { minedSequence, err := ec.getMinedSequenceForAddress(ctx, from) if err != nil { - return errors.Wrapf(err, "unable to fetch pending sequence for address: %v", from) + return fmt.Errorf("unable to fetch pending sequence for address: %v: %w", from, err) } // separateLikelyConfirmedAttempts is used as an optimisation: there is @@ -415,7 +415,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Che start := time.Now() err = ec.fetchAndSaveReceipts(ctx, likelyConfirmed, blockNum) if err != nil { - return errors.Wrapf(err, "unable to fetch and save receipts for likely confirmed txs, for address: %v", from) + return fmt.Errorf("unable to fetch and save receipts for likely confirmed txs, for address: %v: %w", from, err) } ec.lggr.Debugw(fmt.Sprintf("Fetching and saving %v likely confirmed receipts done", likelyConfirmedCount), "time", time.Since(start)) @@ -423,11 +423,11 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Che } if err := ec.txStore.MarkAllConfirmedMissingReceipt(ctx, ec.chainID); err != nil { - return errors.Wrap(err, "unable to mark txes as 'confirmed_missing_receipt'") + return fmt.Errorf("unable to mark txes as 'confirmed_missing_receipt': %w", err) } if err := ec.txStore.MarkOldTxesMissingReceiptAsErrored(ctx, blockNum, ec.chainConfig.FinalityDepth(), ec.chainID); err != nil { - return errors.Wrap(err, "unable to confirm buried unconfirmed txes") + return fmt.Errorf("unable to confirm buried unconfirmed txes': %w", err) } return nil } @@ -488,10 +488,10 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) fet receipts, err := ec.batchFetchReceipts(ctx, batch, blockNum) if err != nil { - return errors.Wrap(err, "batchFetchReceipts failed") + return fmt.Errorf("batchFetchReceipts failed: %w", err) } if err := ec.txStore.SaveFetchedReceipts(ctx, receipts, ec.chainID); err != nil { - return errors.Wrap(err, "saveFetchedReceipts failed") + return fmt.Errorf("saveFetchedReceipts failed: %w", err) } promNumConfirmedTxs.WithLabelValues(ec.chainID.String()).Add(float64(len(receipts))) @@ -514,7 +514,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bat if ec.txConfig.ForwardersEnabled() { err = ec.txStore.PreloadTxes(ctx, attempts) if err != nil { - return nil, errors.Wrap(err, "Confirmer#batchFetchReceipts error loading txs for attempts") + return nil, fmt.Errorf("Confirmer#batchFetchReceipts error loading txs for attempts: %w", err) } } @@ -629,7 +629,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Reb func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) rebroadcastWhereNecessary(ctx context.Context, address ADDR, blockHeight int64) error { if err := ec.handleAnyInProgressAttempts(ctx, address, blockHeight); err != nil { - return errors.Wrap(err, "handleAnyInProgressAttempts failed") + return fmt.Errorf("handleAnyInProgressAttempts failed: %w", err) } threshold := int64(ec.feeConfig.BumpThreshold()) @@ -637,24 +637,24 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) reb maxInFlightTransactions := ec.txConfig.MaxInFlight() etxs, err := ec.FindTxsRequiringRebroadcast(ctx, ec.lggr, address, blockHeight, threshold, bumpDepth, maxInFlightTransactions, ec.chainID) if err != nil { - return errors.Wrap(err, "FindTxsRequiringRebroadcast failed") + return fmt.Errorf("FindTxsRequiringRebroadcast failed: %w", err) } for _, etx := range etxs { lggr := etx.GetLogger(ec.lggr) attempt, err := ec.attemptForRebroadcast(ctx, lggr, *etx) if err != nil { - return errors.Wrap(err, "attemptForRebroadcast failed") + return fmt.Errorf("attemptForRebroadcast failed: %w", err) } lggr.Debugw("Rebroadcasting transaction", "nPreviousAttempts", len(etx.TxAttempts), "fee", attempt.TxFee) if err := ec.txStore.SaveInProgressAttempt(ctx, &attempt); err != nil { - return errors.Wrap(err, "saveInProgressAttempt failed") + return fmt.Errorf("saveInProgressAttempt failed: %w", err) } if err := ec.handleInProgressAttempt(ctx, lggr, *etx, attempt, blockHeight); err != nil { - return errors.Wrap(err, "handleInProgressAttempt failed") + return fmt.Errorf("handleInProgressAttempt failed: %w", err) } } return nil @@ -670,14 +670,14 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han if ctx.Err() != nil { return nil } else if err != nil { - return errors.Wrap(err, "GetInProgressTxAttempts failed") + return fmt.Errorf("GetInProgressTxAttempts failed: %w", err) } for _, a := range attempts { err := ec.handleInProgressAttempt(ctx, a.Tx.GetLogger(ec.lggr), a.Tx, a, blockHeight) if ctx.Err() != nil { break } else if err != nil { - return errors.Wrap(err, "handleInProgressAttempt failed") + return fmt.Errorf("handleInProgressAttempt failed: %w", err) } } return nil @@ -769,7 +769,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) att } return attempt, err } - return attempt, errors.Errorf("invariant violation: Tx %v was unconfirmed but didn't have any attempts. "+ + return attempt, fmt.Errorf("invariant violation: Tx %v was unconfirmed but didn't have any attempts. "+ "Falling back to default gas price instead."+ "This is a bug! Please report to https://github.com/smartcontractkit/chainlink/issues", etx.ID) } @@ -802,17 +802,17 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bum return bumpedAttempt, err } - if errors.Is(errors.Cause(err), commonfee.ErrBumpFeeExceedsLimit) { + if errors.Is(err, commonfee.ErrBumpFeeExceedsLimit) { promGasBumpExceedsLimit.WithLabelValues(ec.chainID.String()).Inc() } - return bumpedAttempt, errors.Wrap(err, "error bumping gas") + return bumpedAttempt, fmt.Errorf("error bumping gas: %w", err) } func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) handleInProgressAttempt(ctx context.Context, lggr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], blockHeight int64) error { if attempt.State != txmgrtypes.TxAttemptInProgress { - return errors.Errorf("invariant violation: expected tx_attempt %v to be in_progress, it was %s", attempt.ID, attempt.State) + return fmt.Errorf("invariant violation: expected tx_attempt %v to be in_progress, it was %s", attempt.ID, attempt.State) } now := time.Now() @@ -827,7 +827,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han // "Lazily" load attempts here since the overwhelmingly common case is // that we don't need them unless we enter this path if err := ec.txStore.LoadTxAttempts(ctx, &etx); err != nil { - return errors.Wrap(err, "failed to load TxAttempts while bumping on terminally underpriced error") + return fmt.Errorf("failed to load TxAttempts while bumping on terminally underpriced error: %w", err) } if len(etx.TxAttempts) == 0 { err := errors.New("expected to find at least 1 attempt") @@ -841,7 +841,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han } replacementAttempt, err := ec.bumpGas(ctx, etx, etx.TxAttempts) if err != nil { - return errors.Wrap(err, "could not bump gas for terminally underpriced transaction") + return fmt.Errorf("could not bump gas for terminally underpriced transaction: %w", err) } promNumGasBumps.WithLabelValues(ec.chainID.String()).Inc() logger.With(lggr, @@ -852,7 +852,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han ).Errorf("gas price was rejected by the node for being too low. Node returned: '%s'", sendError.Error()) if err := ec.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &replacementAttempt); err != nil { - return errors.Wrap(err, "saveReplacementInProgressAttempt failed") + return fmt.Errorf("saveReplacementInProgressAttempt failed: %w", err) } return ec.handleInProgressAttempt(ctx, lggr, etx, replacementAttempt, blockHeight) case client.ExceedsMaxFee: @@ -896,7 +896,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han // node operator. The node may have it in the mempool so we must keep the // attempt (leave it in_progress). Safest thing to do is bail out and wait // for the next head. - return errors.Wrapf(sendError, "unexpected error sending tx %v with hash %s", etx.ID, attempt.Hash.String()) + return fmt.Errorf("unexpected error sending tx %v with hash %s: %w", etx.ID, attempt.Hash.String(), sendError) } } @@ -924,13 +924,13 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Ens } etxs, err := ec.txStore.FindTransactionsConfirmedInBlockRange(ctx, head.BlockNumber(), head.EarliestHeadInChain().BlockNumber(), ec.chainID) if err != nil { - return errors.Wrap(err, "findTransactionsConfirmedInBlockRange failed") + return fmt.Errorf("findTransactionsConfirmedInBlockRange failed: %w", err) } for _, etx := range etxs { if !hasReceiptInLongestChain(*etx, head) { if err := ec.markForRebroadcast(*etx, head); err != nil { - return errors.Wrapf(err, "markForRebroadcast failed for etx %v", etx.ID) + return fmt.Errorf("markForRebroadcast failed for etx %v: %w", etx.ID, err) } } } @@ -983,7 +983,7 @@ func hasReceiptInLongestChain[ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) markForRebroadcast(etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], head types.Head[BLOCK_HASH]) error { if len(etx.TxAttempts) == 0 { - return errors.Errorf("invariant violation: expected tx %v to have at least one attempt", etx.ID) + return fmt.Errorf("invariant violation: expected tx %v to have at least one attempt", etx.ID) } // Rebroadcast the one with the highest gas price @@ -1016,8 +1016,11 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) mar ec.lggr.Infow(fmt.Sprintf("Re-org detected. Rebroadcasting transaction %s which may have been re-org'd out of the main chain", attempt.Hash.String()), logValues...) // Put it back in progress and delete all receipts (they do not apply to the new chain) - err := ec.txStore.UpdateTxForRebroadcast(ec.ctx, etx, attempt) - return errors.Wrap(err, "markForRebroadcast failed") + if err := ec.txStore.UpdateTxForRebroadcast(ec.ctx, etx, attempt); err != nil { + return fmt.Errorf("markForRebroadcast failed: %w", err) + } + + return nil } // ForceRebroadcast sends a transaction for every sequence in the given sequence range at the given gas price. @@ -1037,7 +1040,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) For etx, err := ec.txStore.FindTxWithSequence(ctx, address, seq) if err != nil { - return errors.Wrap(err, "ForceRebroadcast failed") + return fmt.Errorf("ForceRebroadcast failed: %w", err) } if etx == nil { ec.lggr.Debugf("ForceRebroadcast: no tx found with sequence %s, will rebroadcast empty transaction", seq) @@ -1076,7 +1079,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sen } txhash, err := ec.client.SendEmptyTransaction(ctx, ec.TxAttemptBuilder.NewEmptyTxAttempt, seq, gasLimit, fee, fromAddress) if err != nil { - return "", errors.Wrap(err, "(Confirmer).sendEmptyTransaction failed") + return "", fmt.Errorf("(Confirmer).sendEmptyTransaction failed: %w", err) } return txhash, nil } @@ -1099,7 +1102,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Res var taskErr error var output interface{} if data.FailOnRevert && data.Receipt.GetStatus() == 0 { - taskErr = errors.Errorf("transaction %s reverted on-chain", data.Receipt.GetTxHash()) + taskErr = fmt.Errorf("transaction %s reverted on-chain", data.Receipt.GetTxHash()) } else { output = data.Receipt } diff --git a/common/txmgr/strategies.go b/common/txmgr/strategies.go index b986d0d9b80..faba2ba97bc 100644 --- a/common/txmgr/strategies.go +++ b/common/txmgr/strategies.go @@ -2,10 +2,10 @@ package txmgr import ( "context" + "fmt" "time" "github.com/google/uuid" - "github.com/pkg/errors" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" ) @@ -63,7 +63,7 @@ func (s DropOldestStrategy) PruneQueue(ctx context.Context, pruneService txmgrty n, err = pruneService.PruneUnstartedTxQueue(ctx, s.queueSize, s.subject) if err != nil { - return 0, errors.Wrap(err, "DropOldestStrategy#PruneQueue failed") + return 0, fmt.Errorf("DropOldestStrategy#PruneQueue failed: %w", err) } return } diff --git a/common/txmgr/types/tx.go b/common/txmgr/types/tx.go index b8a16561d88..3af43b19617 100644 --- a/common/txmgr/types/tx.go +++ b/common/txmgr/types/tx.go @@ -3,6 +3,7 @@ package types import ( "context" "encoding/json" + "errors" "fmt" "math/big" "slices" @@ -10,7 +11,6 @@ import ( "time" "github.com/google/uuid" - "github.com/pkg/errors" "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -245,7 +245,11 @@ func (e *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) GetMeta() (*TxMeta[A return nil, nil } var m TxMeta[ADDR, TX_HASH] - return &m, errors.Wrap(json.Unmarshal(*e.Meta, &m), "unmarshalling meta") + if err := json.Unmarshal(*e.Meta, &m); err != nil { + return nil, fmt.Errorf("unmarshalling meta: %w", err) + } + + return &m, nil } // GetLogger returns a new logger with metadata fields. @@ -320,5 +324,9 @@ func (e *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) GetChecker() (Transm return TransmitCheckerSpec[ADDR]{}, nil } var t TransmitCheckerSpec[ADDR] - return t, errors.Wrap(json.Unmarshal(*e.TransmitChecker, &t), "unmarshalling transmit checker") + if err := json.Unmarshal(*e.TransmitChecker, &t); err != nil { + return t, fmt.Errorf("unmarshalling transmit checker: %w", err) + } + + return t, nil }