Skip to content

Commit

Permalink
Fix type and version error paths (#376)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorwstein authored Dec 13, 2023
1 parent e3f6571 commit 6c9a0a2
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 13 deletions.
2 changes: 1 addition & 1 deletion core/services/ocr2/plugins/ccip/config/type_and_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TypeAndVersion(addr common.Address, client bind.ContractBackend) (ContractT
}
v, err := semver.NewVersion(versionStr)
if err != nil {
return "", semver.Version{}, err
return "", semver.Version{}, errors.Wrapf(err, "failed parsing version %s", versionStr)
}

if !ContractTypes.Contains(ContractType(contractType)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks"
rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
Expand Down Expand Up @@ -364,3 +365,41 @@ func TestCommitStoreReaders(t *testing.T) {
})
}
}

func TestNewCommitStoreReader(t *testing.T) {
var tt = []struct {
typeAndVersion string
expectedErr string
}{
{
typeAndVersion: "blah",
expectedErr: "unable to read type and version: invalid type and version blah",
},
{
typeAndVersion: "EVM2EVMOffRamp 1.0.0",
expectedErr: "expected CommitStore got EVM2EVMOffRamp",
},
{
typeAndVersion: "CommitStore 1.2.0",
expectedErr: "",
},
{
typeAndVersion: "CommitStore 2.0.0",
expectedErr: "unsupported commit store version 2.0.0",
},
}
for _, tc := range tt {
t.Run(tc.typeAndVersion, func(t *testing.T) {
b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion)
require.NoError(t, err)
c := evmclientmocks.NewClient(t)
c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil)
_, err = factory.NewCommitStoreReader(logger.TestLogger(t), common.Address{}, c, lpmocks.NewLogPoller(t), nil)
if tc.expectedErr != "" {
require.EqualError(t, err, tc.expectedErr)
} else {
require.NoError(t, err)
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import (
func NewCommitStoreReader(lggr logger.Logger, address common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (ccipdata.CommitStoreReader, error) {
contractType, version, err := ccipconfig.TypeAndVersion(address, ec)
if err != nil {
return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType)
return nil, errors.Wrapf(err, "unable to read type and version")
}
if contractType != ccipconfig.CommitStore {
return nil, errors.Errorf("expected %v got %v", ccipconfig.CommitStore, contractType)
}
switch version.String() {
case ccipdata.V1_0_0, ccipdata.V1_1_0:
Expand All @@ -31,7 +34,7 @@ func NewCommitStoreReader(lggr logger.Logger, address common.Address, ec client.
case ccipdata.V1_2_0, ccipdata.V1_3_0:
return v1_2_0.NewCommitStore(lggr, address, ec, lp, estimator)
default:
return nil, errors.Errorf("got unexpected version %v", version.String())
return nil, errors.Errorf("unsupported commit store version %v", version.String())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ import (
)

func NewOffRampReader(lggr logger.Logger, addr common.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (ccipdata.OffRampReader, error) {
_, version, err := ccipconfig.TypeAndVersion(addr, destClient)
contractType, version, err := ccipconfig.TypeAndVersion(addr, destClient)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "unable to read type and version")
}
if contractType != ccipconfig.EVM2EVMOffRamp {
return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOffRamp, contractType)
}
switch version.String() {
case ccipdata.V1_0_0, ccipdata.V1_1_0:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import (
func NewOnRampReader(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (ccipdata.OnRampReader, error) {
contractType, version, err := ccipconfig.TypeAndVersion(onRampAddress, source)
if err != nil {
return nil, errors.Errorf("expected '%v' got '%v' (%v)", ccipconfig.EVM2EVMOnRamp, contractType, err)
return nil, errors.Wrapf(err, "unable to read type and version")
}
if contractType != ccipconfig.EVM2EVMOnRamp {
return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType)
}
switch version.String() {
case ccipdata.V1_0_0:
Expand All @@ -31,6 +34,6 @@ func NewOnRampReader(lggr logger.Logger, sourceSelector, destSelector uint64, on
case ccipdata.V1_3_0:
return v1_3_0.NewOnRamp(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source)
default:
return nil, errors.Errorf("got unexpected version %v", version.String())
return nil, errors.Errorf("unsupported onramp version %v", version.String())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@ import (

// NewPriceRegistryReader determines the appropriate version of the price registry and returns a reader for it.
func NewPriceRegistryReader(lggr logger.Logger, priceRegistryAddress common.Address, lp logpoller.LogPoller, cl client.Client) (ccipdata.PriceRegistryReader, error) {
_, version, err := ccipconfig.TypeAndVersion(priceRegistryAddress, cl)
contractType, version, err := ccipconfig.TypeAndVersion(priceRegistryAddress, cl)
if err != nil {
if strings.Contains(err.Error(), "execution reverted") {
lggr.Infof("Assuming %v is 1.0.0 price registry, got %v", priceRegistryAddress.String(), err)
// Unfortunately the v1 price registry doesn't have a method to get the version so assume if it reverts
// its v1.
return v1_0_0.NewPriceRegistry(lggr, priceRegistryAddress, lp, cl)
}
return nil, err
return nil, errors.Wrapf(err, "unable to read type and version")
}
if contractType != ccipconfig.PriceRegistry {
return nil, errors.Errorf("expected %v got %v", ccipconfig.PriceRegistry, contractType)
}
switch version.String() {
case ccipdata.V1_2_0:
return v1_2_0.NewPriceRegistry(lggr, priceRegistryAddress, lp, cl)
default:
return nil, errors.Errorf("got unexpected version %v", version.String())
return nil, errors.Errorf("unsupported price registry version %v", version.String())
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ccipdata_test

import (
"github.com/stretchr/testify/mock"
"math/big"
"math/rand"
"testing"
Expand All @@ -13,6 +14,7 @@ import (

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper"
Expand Down Expand Up @@ -438,3 +440,41 @@ func testOffRampReader(t *testing.T, th offRampReaderTH) {
require.NoError(t, err)
require.Empty(t, destPools)
}

func TestNewOffRampReader(t *testing.T) {
var tt = []struct {
typeAndVersion string
expectedErr string
}{
{
typeAndVersion: "blah",
expectedErr: "unable to read type and version: invalid type and version blah",
},
{
typeAndVersion: "CommitStore 1.0.0",
expectedErr: "expected EVM2EVMOffRamp got CommitStore",
},
{
typeAndVersion: "EVM2EVMOffRamp 1.2.0",
expectedErr: "",
},
{
typeAndVersion: "EVM2EVMOffRamp 2.0.0",
expectedErr: "unsupported offramp version 2.0.0",
},
}
for _, tc := range tt {
t.Run(tc.typeAndVersion, func(t *testing.T) {
b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion)
require.NoError(t, err)
c := evmclientmocks.NewClient(t)
c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil)
_, err = factory.NewOffRampReader(logger.TestLogger(t), common.Address{}, c, lpmocks.NewLogPoller(t), nil)
if tc.expectedErr != "" {
assert.EqualError(t, err, tc.expectedErr)
} else {
assert.NoError(t, err)
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ccipdata_test

import (
evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/stretchr/testify/mock"
"math/big"
"testing"
"time"
Expand Down Expand Up @@ -33,9 +35,8 @@ type onRampReaderTH struct {

func TestNewOnRampReader_noContractAtAddress(t *testing.T) {
_, bc := ccipdata.NewSimulation(t)
lp := lpmocks.NewLogPoller(t)
_, err := factory.NewOnRampReader(logger.TestLogger(t), testutils.SimulatedChainID.Uint64(), testutils.SimulatedChainID.Uint64(), common.Address{}, lp, bc)
assert.EqualError(t, err, "expected 'EVM2EVMOnRamp' got '' (no contract code at given address)")
_, err := factory.NewOnRampReader(logger.TestLogger(t), testutils.SimulatedChainID.Uint64(), testutils.SimulatedChainID.Uint64(), common.Address{}, lpmocks.NewLogPoller(t), bc)
assert.EqualError(t, err, "unable to read type and version: no contract code at given address")
}

func TestOnRampReaderInit(t *testing.T) {
Expand Down Expand Up @@ -416,3 +417,41 @@ func testOnRampReader(t *testing.T, th onRampReaderTH, expectedRouterAddress com
require.NotNil(t, cfg)
require.Equal(t, expectedRouterAddress, cfg.Router)
}

func TestNewOnRampReader(t *testing.T) {
var tt = []struct {
typeAndVersion string
expectedErr string
}{
{
typeAndVersion: "blah",
expectedErr: "unable to read type and version: invalid type and version blah",
},
{
typeAndVersion: "EVM2EVMOffRamp 1.0.0",
expectedErr: "expected EVM2EVMOnRamp got EVM2EVMOffRamp",
},
{
typeAndVersion: "EVM2EVMOnRamp 1.2.0",
expectedErr: "",
},
{
typeAndVersion: "EVM2EVMOnRamp 2.0.0",
expectedErr: "unsupported onramp version 2.0.0",
},
}
for _, tc := range tt {
t.Run(tc.typeAndVersion, func(t *testing.T) {
b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion)
require.NoError(t, err)
c := evmclientmocks.NewClient(t)
c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil)
_, err = factory.NewOnRampReader(logger.TestLogger(t), 1, 2, common.Address{}, lpmocks.NewLogPoller(t), c)
if tc.expectedErr != "" {
require.EqualError(t, err, tc.expectedErr)
} else {
require.NoError(t, err)
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ccipdata_test

import (
"context"
"github.com/stretchr/testify/mock"
"math/big"
"reflect"
"testing"
Expand All @@ -16,6 +17,7 @@ import (

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry"
Expand Down Expand Up @@ -229,3 +231,41 @@ func TestPriceRegistryReader(t *testing.T) {
})
}
}

func TestNewPriceRegistryReader(t *testing.T) {
var tt = []struct {
typeAndVersion string
expectedErr string
}{
{
typeAndVersion: "blah",
expectedErr: "unable to read type and version: invalid type and version blah",
},
{
typeAndVersion: "EVM2EVMOffRamp 1.0.0",
expectedErr: "expected PriceRegistry got EVM2EVMOffRamp",
},
{
typeAndVersion: "PriceRegistry 1.2.0",
expectedErr: "",
},
{
typeAndVersion: "PriceRegistry 2.0.0",
expectedErr: "unsupported price registry version 2.0.0",
},
}
for _, tc := range tt {
t.Run(tc.typeAndVersion, func(t *testing.T) {
b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion)
require.NoError(t, err)
c := evmclientmocks.NewClient(t)
c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil)
_, err = factory.NewPriceRegistryReader(logger.TestLogger(t), common.Address{}, lpmocks.NewLogPoller(t), c)
if tc.expectedErr != "" {
require.EqualError(t, err, tc.expectedErr)
} else {
require.NoError(t, err)
}
})
}
}

0 comments on commit 6c9a0a2

Please sign in to comment.