Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace multierr dep with stnd lib as much as possible #11818

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions common/txmgr/broadcaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/jpillora/backoff"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"go.uber.org/multierr"
"gopkg.in/guregu/null.v4"

"github.com/smartcontractkit/chainlink-common/pkg/chains/label"
Expand Down Expand Up @@ -669,7 +668,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand
`Urgent resolution required, Chainlink is currently operating in a degraded state and may miss transactions`, "attempt", attempt)
nextSequence, e := eb.client.PendingSequenceAt(ctx, etx.FromAddress)
if e != nil {
err = multierr.Combine(e, err)
err = errors.Join(e, err)
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() {
Expand Down
13 changes: 6 additions & 7 deletions common/txmgr/confirmer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"go.uber.org/multierr"

"github.com/smartcontractkit/chainlink-common/pkg/chains/label"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
Expand Down Expand Up @@ -608,13 +607,13 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Reb
// It is safe to process separate keys concurrently
// NOTE: This design will block one key if another takes a really long time to execute
wg.Add(len(ec.enabledAddresses))
errors := []error{}
errs := []error{}
var errMu sync.Mutex
for _, address := range ec.enabledAddresses {
go func(fromAddress ADDR) {
if err := ec.rebroadcastWhereNecessary(ctx, fromAddress, blockHeight); err != nil {
errMu.Lock()
errors = append(errors, err)
errs = append(errs, err)
errMu.Unlock()
ec.lggr.Errorw("Error in RebroadcastWhereNecessary", "err", err, "fromAddress", fromAddress)
}
Expand All @@ -625,7 +624,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Reb

wg.Wait()

return multierr.Combine(errors...)
return errors.Join(errs...)
}

func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) rebroadcastWhereNecessary(ctx context.Context, address ADDR, blockHeight int64) error {
Expand Down Expand Up @@ -938,14 +937,14 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Ens
// It is safe to process separate keys concurrently
// NOTE: This design will block one key if another takes a really long time to execute
var wg sync.WaitGroup
errors := []error{}
errs := []error{}
var errMu sync.Mutex
wg.Add(len(ec.enabledAddresses))
for _, address := range ec.enabledAddresses {
go func(fromAddress ADDR) {
if err := ec.handleAnyInProgressAttempts(ctx, fromAddress, head.BlockNumber()); err != nil {
errMu.Lock()
errors = append(errors, err)
errs = append(errs, err)
errMu.Unlock()
ec.lggr.Errorw("Error in handleAnyInProgressAttempts", "err", err, "fromAddress", fromAddress)
}
Expand All @@ -956,7 +955,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Ens

wg.Wait()

return multierr.Combine(errors...)
return errors.Join(errs...)
}

func hasReceiptInLongestChain[
Expand Down
5 changes: 2 additions & 3 deletions core/chains/evm/config/chain_scoped.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package config

import (
"errors"
"math/big"
"time"

"go.uber.org/multierr"

ocr "github.com/smartcontractkit/libocr/offchainreporting"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types"

Expand Down Expand Up @@ -57,7 +56,7 @@ func (c *ChainScoped) Validate() (err error) {
DataSourceGracePeriod: c.EVM().OCR().ObservationGracePeriod(),
}
if ocrerr := ocr.SanityCheckLocalConfig(lc); ocrerr != nil {
err = multierr.Append(err, ocrerr)
err = errors.Join(err, ocrerr)
}
return
}
Expand Down
74 changes: 37 additions & 37 deletions core/chains/evm/config/toml/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package toml

import (
"errors"
"fmt"
"net/url"
"slices"
Expand All @@ -9,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/pelletier/go-toml/v2"
"github.com/shopspring/decimal"
"go.uber.org/multierr"
"gopkg.in/guregu/null.v4"

commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets"
Expand Down Expand Up @@ -39,7 +39,7 @@ func (cs EVMConfigs) validateKeys() (err error) {
chainIDs := commonconfig.UniqueStrings{}
for i, c := range cs {
if chainIDs.IsDupeFmt(c.ChainID) {
err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.ChainID", i), c.ChainID.String()))
err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.ChainID", i), c.ChainID.String()))
}
}

Expand All @@ -48,7 +48,7 @@ func (cs EVMConfigs) validateKeys() (err error) {
for i, c := range cs {
for j, n := range c.Nodes {
if names.IsDupe(n.Name) {
err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.Name", i, j), *n.Name))
err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.Name", i, j), *n.Name))
}
}
}
Expand All @@ -59,7 +59,7 @@ func (cs EVMConfigs) validateKeys() (err error) {
for j, n := range c.Nodes {
u := (*url.URL)(n.WSURL)
if wsURLs.IsDupeFmt(u) {
err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.WSURL", i, j), u.String()))
err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.WSURL", i, j), u.String()))
}
}
}
Expand All @@ -70,7 +70,7 @@ func (cs EVMConfigs) validateKeys() (err error) {
for j, n := range c.Nodes {
u := (*url.URL)(n.HTTPURL)
if httpURLs.IsDupeFmt(u) {
err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.HTTPURL", i, j), u.String()))
err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.HTTPURL", i, j), u.String()))
}
}
}
Expand Down Expand Up @@ -289,29 +289,29 @@ func (c *EVMConfig) SetFrom(f *EVMConfig) {

func (c *EVMConfig) ValidateConfig() (err error) {
if c.ChainID == nil {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "ChainID", Msg: "required for all chains"})
err = errors.Join(err, commonconfig.ErrMissing{Name: "ChainID", Msg: "required for all chains"})
} else if c.ChainID.String() == "" {
err = multierr.Append(err, commonconfig.ErrEmpty{Name: "ChainID", Msg: "required for all chains"})
err = errors.Join(err, commonconfig.ErrEmpty{Name: "ChainID", Msg: "required for all chains"})
} else if must, ok := ChainTypeForID(c.ChainID); ok { // known chain id
if c.ChainType == nil && must != "" {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "ChainType",
err = errors.Join(err, commonconfig.ErrMissing{Name: "ChainType",
Msg: fmt.Sprintf("only %q can be used with this chain id", must)})
} else if c.ChainType != nil && *c.ChainType != string(must) {
if *c.ChainType == "" {
err = multierr.Append(err, commonconfig.ErrEmpty{Name: "ChainType",
err = errors.Join(err, commonconfig.ErrEmpty{Name: "ChainType",
Msg: fmt.Sprintf("only %q can be used with this chain id", must)})
} else if must == "" {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType,
Msg: "must not be set with this chain id"})
} else {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType,
Msg: fmt.Sprintf("only %q can be used with this chain id", must)})
}
}
}

if len(c.Nodes) == 0 {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "Nodes", Msg: "must have at least one node"})
err = errors.Join(err, commonconfig.ErrMissing{Name: "Nodes", Msg: "must have at least one node"})
} else {
var hasPrimary bool
for _, n := range c.Nodes {
Expand All @@ -322,12 +322,12 @@ func (c *EVMConfig) ValidateConfig() (err error) {
break
}
if !hasPrimary {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "Nodes",
err = errors.Join(err, commonconfig.ErrMissing{Name: "Nodes",
Msg: "must have at least one primary node with WSURL"})
}
}

err = multierr.Append(err, c.Chain.ValidateConfig())
err = errors.Join(err, c.Chain.ValidateConfig())

return
}
Expand Down Expand Up @@ -376,24 +376,24 @@ func (c *Chain) ValidateConfig() (err error) {
chainType = config.ChainType(*c.ChainType)
}
if !chainType.IsValid() {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType,
Msg: config.ErrInvalidChainType.Error()})
}

if c.GasEstimator.BumpTxDepth != nil && *c.GasEstimator.BumpTxDepth > *c.Transactions.MaxInFlight {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "GasEstimator.BumpTxDepth", Value: *c.GasEstimator.BumpTxDepth,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "GasEstimator.BumpTxDepth", Value: *c.GasEstimator.BumpTxDepth,
Msg: "must be less than or equal to Transactions.MaxInFlight"})
}
if *c.HeadTracker.HistoryDepth < *c.FinalityDepth {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "HeadTracker.HistoryDepth", Value: *c.HeadTracker.HistoryDepth,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "HeadTracker.HistoryDepth", Value: *c.HeadTracker.HistoryDepth,
Msg: "must be equal to or greater than FinalityDepth"})
}
if *c.FinalityDepth < 1 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FinalityDepth", Value: *c.FinalityDepth,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "FinalityDepth", Value: *c.FinalityDepth,
Msg: "must be greater than or equal to 1"})
}
if *c.MinIncomingConfirmations < 1 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "MinIncomingConfirmations", Value: *c.MinIncomingConfirmations,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "MinIncomingConfirmations", Value: *c.MinIncomingConfirmations,
Msg: "must be greater than or equal to 1"})
}
return
Expand Down Expand Up @@ -486,36 +486,36 @@ type GasEstimator struct {

func (e *GasEstimator) ValidateConfig() (err error) {
if uint64(*e.BumpPercent) < legacypool.DefaultConfig.PriceBump {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "BumpPercent", Value: *e.BumpPercent,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "BumpPercent", Value: *e.BumpPercent,
Msg: fmt.Sprintf("may not be less than Geth's default of %d", legacypool.DefaultConfig.PriceBump)})
}
if e.TipCapDefault.Cmp(e.TipCapMin) < 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "TipCapDefault", Value: e.TipCapDefault,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "TipCapDefault", Value: e.TipCapDefault,
Msg: "must be greater than or equal to TipCapMinimum"})
}
if e.FeeCapDefault.Cmp(e.TipCapDefault) < 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.TipCapDefault,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.TipCapDefault,
Msg: "must be greater than or equal to TipCapDefault"})
}
if *e.Mode == "FixedPrice" && *e.BumpThreshold == 0 && *e.EIP1559DynamicFees && e.FeeCapDefault.Cmp(e.PriceMax) != 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault,
Msg: fmt.Sprintf("must be equal to PriceMax (%s) since you are using FixedPrice estimation with gas bumping disabled in "+
"EIP1559 mode - PriceMax will be used as the FeeCap for transactions instead of FeeCapDefault", e.PriceMax)})
} else if e.FeeCapDefault.Cmp(e.PriceMax) > 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault,
Msg: fmt.Sprintf("must be less than or equal to PriceMax (%s)", e.PriceMax)})
}

if e.PriceMin.Cmp(e.PriceDefault) > 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "PriceMin", Value: e.PriceMin,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "PriceMin", Value: e.PriceMin,
Msg: "must be less than or equal to PriceDefault"})
}
if e.PriceMax.Cmp(e.PriceDefault) < 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "PriceMax", Value: e.PriceMin,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "PriceMax", Value: e.PriceMin,
Msg: "must be greater than or equal to PriceDefault"})
}
if *e.Mode == "BlockHistory" && *e.BlockHistory.BlockHistorySize <= 0 {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "BlockHistory.BlockHistorySize", Value: *e.BlockHistory.BlockHistorySize,
err = errors.Join(err, commonconfig.ErrInvalid{Name: "BlockHistory.BlockHistorySize", Value: *e.BlockHistory.BlockHistorySize,
Msg: "must be greater than or equal to 1 with BlockHistory Mode"})
}

Expand Down Expand Up @@ -642,7 +642,7 @@ func (ks KeySpecificConfig) ValidateConfig() (err error) {
for _, k := range ks {
addr := k.Key.String()
if _, ok := addrs[addr]; ok {
err = multierr.Append(err, commonconfig.NewErrDuplicate("Key", addr))
err = errors.Join(err, commonconfig.NewErrDuplicate("Key", addr))
} else {
addrs[addr] = struct{}{}
}
Expand Down Expand Up @@ -749,9 +749,9 @@ type Node struct {

func (n *Node) ValidateConfig() (err error) {
if n.Name == nil {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "Name", Msg: "required for all nodes"})
err = errors.Join(err, commonconfig.ErrMissing{Name: "Name", Msg: "required for all nodes"})
} else if *n.Name == "" {
err = multierr.Append(err, commonconfig.ErrEmpty{Name: "Name", Msg: "required for all nodes"})
err = errors.Join(err, commonconfig.ErrEmpty{Name: "Name", Msg: "required for all nodes"})
}

var sendOnly bool
Expand All @@ -760,34 +760,34 @@ func (n *Node) ValidateConfig() (err error) {
}
if n.WSURL == nil {
if !sendOnly {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "WSURL", Msg: "required for primary nodes"})
err = errors.Join(err, commonconfig.ErrMissing{Name: "WSURL", Msg: "required for primary nodes"})
}
} else if n.WSURL.IsZero() {
if !sendOnly {
err = multierr.Append(err, commonconfig.ErrEmpty{Name: "WSURL", Msg: "required for primary nodes"})
err = errors.Join(err, commonconfig.ErrEmpty{Name: "WSURL", Msg: "required for primary nodes"})
}
} else {
switch n.WSURL.Scheme {
case "ws", "wss":
default:
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "WSURL", Value: n.WSURL.Scheme, Msg: "must be ws or wss"})
err = errors.Join(err, commonconfig.ErrInvalid{Name: "WSURL", Value: n.WSURL.Scheme, Msg: "must be ws or wss"})
}
}

if n.HTTPURL == nil {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "HTTPURL", Msg: "required for all nodes"})
err = errors.Join(err, commonconfig.ErrMissing{Name: "HTTPURL", Msg: "required for all nodes"})
} else if n.HTTPURL.IsZero() {
err = multierr.Append(err, commonconfig.ErrEmpty{Name: "HTTPURL", Msg: "required for all nodes"})
err = errors.Join(err, commonconfig.ErrEmpty{Name: "HTTPURL", Msg: "required for all nodes"})
} else {
switch n.HTTPURL.Scheme {
case "http", "https":
default:
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "HTTPURL", Value: n.HTTPURL.Scheme, Msg: "must be http or https"})
err = errors.Join(err, commonconfig.ErrInvalid{Name: "HTTPURL", Value: n.HTTPURL.Scheme, Msg: "must be http or https"})
}
}

if n.Order != nil && (*n.Order < 1 || *n.Order > 100) {
err = multierr.Append(err, commonconfig.ErrInvalid{Name: "Order", Value: *n.Order, Msg: "must be between 1 and 100"})
err = errors.Join(err, commonconfig.ErrInvalid{Name: "Order", Value: *n.Order, Msg: "must be between 1 and 100"})
} else if n.Order == nil {
z := int32(100)
n.Order = &z
Expand Down
4 changes: 2 additions & 2 deletions core/chains/evm/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils_test

import (
"context"
"errors"
"math/big"
"strings"
"sync/atomic"
Expand All @@ -11,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/assert"
"go.uber.org/multierr"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestClient_ParseEthereumAddress(t *testing.T) {
assert.True(t, a1 == a2)
_, lowerErr := parse(strings.ToLower(address))
_, upperErr := parse(strings.ToUpper(address))
shouldBeError := multierr.Combine(lowerErr, upperErr)
shouldBeError := errors.Join(lowerErr, upperErr)
assert.Error(t, shouldBeError)
assert.True(t, strings.Contains(shouldBeError.Error(), no0xPrefix))
}
Expand Down
Loading
Loading