Skip to content

Commit

Permalink
verify contract when binding (#13613)
Browse files Browse the repository at this point in the history
* verify contract when binding

* fix tests that rely on Bind

* fix len check

* change error to custom error

* add error test
  • Loading branch information
EasterTheBunny authored Jun 19, 2024
1 parent c8c9010 commit 29196d5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
13 changes: 13 additions & 0 deletions core/services/relay/evm/chain_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/jmoiron/sqlx"
Expand Down Expand Up @@ -145,6 +146,18 @@ func TestChainReader(t *testing.T) {
it := &EVMChainReaderInterfaceTester[*testing.T]{Helper: &helper{}}
RunChainReaderEvmTests(t, it)
RunChainReaderInterfaceTests[*testing.T](t, commontestutils.WrapChainReaderTesterForLoop(it))

t.Run("Bind returns error on missing contract at address", func(t *testing.T) {
t.Parallel()
it.Setup(t)

addr := common.BigToAddress(big.NewInt(42))
reader := it.GetChainReader(t)

err := reader.Bind(context.Background(), []clcommontypes.BoundContract{{Name: AnyContractName, Address: addr.Hex(), Pending: true}})

require.ErrorIs(t, err, evm.NoContractExistsError{Address: addr})
})
}

type helper struct {
Expand Down
25 changes: 23 additions & 2 deletions core/services/relay/evm/method_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ import (
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
)

type NoContractExistsError struct {
Address common.Address
}

func (e NoContractExistsError) Error() string {
return fmt.Sprintf("contract does not exist at address: %s", e.Address)
}

type methodBinding struct {
address common.Address
contractName string
Expand All @@ -28,9 +36,22 @@ func (m *methodBinding) SetCodec(codec commontypes.RemoteCodec) {
m.codec = codec
}

func (m *methodBinding) Bind(_ context.Context, binding commontypes.BoundContract) error {
m.address = common.HexToAddress(binding.Address)
func (m *methodBinding) Bind(ctx context.Context, binding commontypes.BoundContract) error {
addr := common.HexToAddress(binding.Address)

// check for contract byte code at the latest block and provided address
byteCode, err := m.client.CodeAt(ctx, addr, nil)
if err != nil {
return err
}

if len(byteCode) == 0 {
return NoContractExistsError{Address: addr}
}

m.address = addr
m.bound = true

return nil
}

Expand Down
1 change: 1 addition & 0 deletions core/services/relay/evm/write_target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func TestEvmWrite(t *testing.T) {
mockCall = append(mockCall, byte(0))
}
evmClient.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(mockCall, nil).Maybe()
evmClient.On("CodeAt", mock.Anything, mock.Anything, mock.Anything).Return([]byte("test"), nil)

chain.On("ID").Return(big.NewInt(11155111))
chain.On("TxManager").Return(txManager)
Expand Down

0 comments on commit 29196d5

Please sign in to comment.