From d1280791a7db204b30ed8bce98bc52b372292cbb Mon Sep 17 00:00:00 2001 From: krehermann <16602512+krehermann@users.noreply.github.com> Date: Wed, 18 Dec 2024 06:05:35 -0700 Subject: [PATCH] promote decode err to common (#15745) --- deployment/helpers.go | 27 ++++++++++++++++++++++++++- deployment/keystone/deploy.go | 24 +++--------------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/deployment/helpers.go b/deployment/helpers.go index dfbbccc2698..34a2584a544 100644 --- a/deployment/helpers.go +++ b/deployment/helpers.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rpc" "github.com/pkg/errors" chain_selectors "github.com/smartcontractkit/chain-selectors" @@ -87,7 +88,7 @@ func parseError(txError error) (string, error) { return callErr.Data, nil } -func ParseErrorFromABI(errorString string, contractABI string) (string, error) { +func parseErrorFromABI(errorString string, contractABI string) (string, error) { parsedAbi, err := abi.JSON(strings.NewReader(contractABI)) if err != nil { return "", errors.Wrap(err, "error loading ABI") @@ -112,6 +113,30 @@ func ParseErrorFromABI(errorString string, contractABI string) (string, error) { return "", errors.New("error not found in ABI") } +// DecodeErr decodes an error from a contract call using the contract's ABI. +// If the error is not decodable, it returns the original error. +func DecodeErr(encodedABI string, err error) error { + if err == nil { + return nil + } + //revive:disable + var d rpc.DataError + ok := errors.As(err, &d) + if ok { + encErr, ok := d.ErrorData().(string) + if !ok { + return fmt.Errorf("error without error data: %s", d.Error()) + } + errStr, parseErr := parseErrorFromABI(encErr, encodedABI) + if parseErr != nil { + return fmt.Errorf("failed to decode error '%s' with abi: %w", encErr, parseErr) + } + return fmt.Errorf("contract error: %s", errStr) + + } + return fmt.Errorf("cannot decode error with abi: %w", err) +} + // ContractDeploy represents the result of an EVM contract deployment // via an abigen Go binding. It contains all the return values // as they are useful in different ways. diff --git a/deployment/keystone/deploy.go b/deployment/keystone/deploy.go index cb7804d0051..3d415c5d2da 100644 --- a/deployment/keystone/deploy.go +++ b/deployment/keystone/deploy.go @@ -14,7 +14,6 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/rpc" "golang.org/x/exp/maps" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" @@ -605,27 +604,10 @@ func DefaultCapConfig(capType uint8, nNodes int) *capabilitiespb.CapabilityConfi } } +// DEPRECATED: use deployment.DecodeErr instead +// todo: refactor all keystone deps to use deployment.DecodeErr func DecodeErr(encodedABI string, err error) error { - if err == nil { - return nil - } - - //revive:disable - var d rpc.DataError - ok := errors.As(err, &d) - if ok { - encErr, ok := d.ErrorData().(string) - if !ok { - return fmt.Errorf("error without error data: %s", d.Error()) - } - errStr, parseErr := deployment.ParseErrorFromABI(encErr, encodedABI) - if parseErr != nil { - return fmt.Errorf("failed to decode error '%s' with abi: %w", encErr, parseErr) - } - return fmt.Errorf("contract error: %s", errStr) - - } - return fmt.Errorf("cannot decode error with abi: %w", err) + return deployment.DecodeErr(encodedABI, err) } // register nodes