From 5e20f7fc3009acccae23f34c1765ad06c731ece1 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 30 Apr 2024 10:18:46 +0200 Subject: [PATCH] contract call retrier as a debug --- integration-tests/go.mod | 2 +- integration-tests/wrappers/contract_caller.go | 71 +++++++++++++++++-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 671c0861d5f..5558f7fd514 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -6,6 +6,7 @@ go 1.21.7 replace github.com/smartcontractkit/chainlink/v2 => ../ require ( + github.com/avast/retry-go v3.0.0+incompatible github.com/avast/retry-go/v4 v4.5.1 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/cli/go-gh/v2 v2.0.0 @@ -88,7 +89,6 @@ require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect diff --git a/integration-tests/wrappers/contract_caller.go b/integration-tests/wrappers/contract_caller.go index 4be76ee74a1..35598a6a013 100644 --- a/integration-tests/wrappers/contract_caller.go +++ b/integration-tests/wrappers/contract_caller.go @@ -2,18 +2,25 @@ package wrappers import ( "context" + "fmt" "math/big" + "strings" + "time" + "github.com/avast/retry-go" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" + "github.com/rs/zerolog" "github.com/smartcontractkit/seth" evmClient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/logging" ) // WrappedContractBackend is a wrapper around the go-ethereum ContractBackend interface. It's a thin wrapper @@ -23,6 +30,7 @@ import ( type WrappedContractBackend struct { evmClient blockchain.EVMClient sethClient *seth.Client + l zerolog.Logger } // MustNewWrappedContractBackend creates a new WrappedContractBackend with the given clients @@ -34,6 +42,20 @@ func MustNewWrappedContractBackend(evmClient blockchain.EVMClient, sethClient *s return &WrappedContractBackend{ evmClient: evmClient, sethClient: sethClient, + l: logging.GetTestLogger(nil), + } +} + +// MustNewWrappedContractBackendWithLogger creates a new WrappedContractBackend with the given clients and logger instance +func MustNewWrappedContractBackendWithLogger(evmClient blockchain.EVMClient, sethClient *seth.Client, l zerolog.Logger) *WrappedContractBackend { + if evmClient == nil && sethClient == nil { + panic("Must provide at least one client") + } + + return &WrappedContractBackend{ + evmClient: evmClient, + sethClient: sethClient, + l: l, } } @@ -110,13 +132,48 @@ func (w *WrappedContractBackend) SubscribeFilterLogs(ctx context.Context, query } func (w *WrappedContractBackend) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { - var hex hexutil.Bytes - client := w.getGethClient() - err := client.Client().CallContext(ctx, &hex, "eth_call", evmClient.ToBackwardCompatibleCallArg(msg), evmClient.ToBackwardCompatibleBlockNumArg(blockNumber)) - if err != nil { - return nil, err - } - return hex, nil + var result []byte + err := retry.Do(func() error { + var hex hexutil.Bytes + client := w.getGethClient() + err := client.Client().CallContext(ctx, &hex, "eth_call", evmClient.ToBackwardCompatibleCallArg(msg), evmClient.ToBackwardCompatibleBlockNumArg(blockNumber)) + if err != nil { + return err + } + result = hex + return nil + }, + retry.RetryIf(func(err error) bool { + if err.Error() == rpc.ErrClientQuit.Error() || + err.Error() == rpc.ErrBadResult.Error() || + strings.Contains(err.Error(), "connection") || + strings.Contains(err.Error(), "EOF") { + return true + } + + w.l.Error().Err(err).Msg("Error in CallContract. Not retrying.") + + return false + }), + retry.Attempts(uint(10)), + retry.Delay(1*time.Second), + retry.OnRetry(func(n uint, err error) { + w.l.Info(). + Str("Attempt", fmt.Sprintf("%d/%d", n+1, 10)). + Str("Error", err.Error()). + Msg("Retrying CallContract") + }), + ) + + return result, err + + // var hex hexutil.Bytes + // client := w.getGethClient() + // err := client.Client().CallContext(ctx, &hex, "eth_call", evmClient.ToBackwardCompatibleCallArg(msg), evmClient.ToBackwardCompatibleBlockNumArg(blockNumber)) + // if err != nil { + // return nil, err + // } + // return hex, nil } func (w *WrappedContractBackend) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) {