From 348d7f85b9c890de3c15cc9cf0a3137c2e50c365 Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 12 Aug 2024 20:28:48 +0300 Subject: [PATCH] core/capabilities/ccip: bump chainlink-ccip (#1284) ## Motivation Recent merges to chainlink-ccip have caused the integration test to break. ## Solution Include the gas estimator changes required as well as some token data reader changes. Include fixes from https://github.com/smartcontractkit/chainlink-ccip/pull/60 --- core/capabilities/ccip/ccipevm/gas_helpers.go | 89 ++++++++++ .../ccip/ccipevm/gas_helpers_test.go | 157 ++++++++++++++++++ .../ccip/oraclecreator/inprocess.go | 3 + .../ccip/superfakes/token_data_reader.go | 23 +++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 12 files changed, 284 insertions(+), 12 deletions(-) create mode 100644 core/capabilities/ccip/ccipevm/gas_helpers.go create mode 100644 core/capabilities/ccip/ccipevm/gas_helpers_test.go create mode 100644 core/capabilities/ccip/superfakes/token_data_reader.go diff --git a/core/capabilities/ccip/ccipevm/gas_helpers.go b/core/capabilities/ccip/ccipevm/gas_helpers.go new file mode 100644 index 00000000000..41acb2a15fa --- /dev/null +++ b/core/capabilities/ccip/ccipevm/gas_helpers.go @@ -0,0 +1,89 @@ +package ccipevm + +import ( + "math" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +const ( + EvmAddressLengthBytes = 20 + EvmWordBytes = 32 + CalldataGasPerByte = 16 + TokenAdminRegistryWarmupCost = 2_500 + TokenAdminRegistryPoolLookupGas = 100 + // WARM_ACCESS_COST TokenAdminRegistry + 700 + // CALL cost for TokenAdminRegistry + 2_100 // COLD_SLOAD_COST loading the pool address + SupportsInterfaceCheck = 2600 + // because the receiver will be untouched initially + 30_000*3 // supportsInterface of ERC165Checker library performs 3 static-calls of 30k gas each + PerTokenOverheadGas = TokenAdminRegistryPoolLookupGas + + SupportsInterfaceCheck + + 200_000 + // releaseOrMint using callWithExactGas + 50_000 // transfer using callWithExactGas + RateLimiterOverheadGas = 2_100 + // COLD_SLOAD_COST for accessing token bucket + 5_000 // SSTORE_RESET_GAS for updating & decreasing token bucket + ConstantMessagePartBytes = 10 * 32 // A message consists of 10 abi encoded fields 32B each (after encoding) + ExecutionStateProcessingOverheadGas = 2_100 + // COLD_SLOAD_COST for first reading the state + 20_000 + // SSTORE_SET_GAS for writing from 0 (untouched) to non-zero (in-progress) + 100 //# SLOAD_GAS = WARM_STORAGE_READ_COST for rewriting from non-zero (in-progress) to non-zero (success/failure) +) + +func NewGasEstimateProvider() EstimateProvider { + return EstimateProvider{} +} + +type EstimateProvider struct { +} + +// CalculateMerkleTreeGas estimates the merkle tree gas based on number of requests +func (gp EstimateProvider) CalculateMerkleTreeGas(numRequests int) uint64 { + if numRequests == 0 { + return 0 + } + merkleProofBytes := (math.Ceil(math.Log2(float64(numRequests))))*32 + (1+2)*32 // only ever one outer root hash + return uint64(merkleProofBytes * CalldataGasPerByte) +} + +// return the size of bytes for msg tokens +func bytesForMsgTokens(numTokens int) int { + // token address (address) + token amount (uint256) + return (EvmAddressLengthBytes + EvmWordBytes) * numTokens +} + +// CalculateMessageMaxGas computes the maximum gas overhead for a message. +func (gp EstimateProvider) CalculateMessageMaxGas(msg cciptypes.Message) uint64 { + numTokens := len(msg.TokenAmounts) + var data []byte = msg.Data + dataLength := len(data) + + // TODO: update interface to return error? + // Although this decoding should never fail. + messageGasLimit, err := decodeExtraArgsV1V2(msg.ExtraArgs) + if err != nil { + panic(err) + } + + messageBytes := ConstantMessagePartBytes + + bytesForMsgTokens(numTokens) + + dataLength + + messageCallDataGas := uint64(messageBytes * CalldataGasPerByte) + + // Rate limiter only limits value in tokens. It's not called if there are no + // tokens in the message. The same goes for the admin registry, it's only loaded + // if there are tokens, and it's only loaded once. + rateLimiterOverhead := uint64(0) + adminRegistryOverhead := uint64(0) + if numTokens >= 1 { + rateLimiterOverhead = RateLimiterOverheadGas + adminRegistryOverhead = TokenAdminRegistryWarmupCost + } + + return messageGasLimit.Uint64() + + messageCallDataGas + + ExecutionStateProcessingOverheadGas + + SupportsInterfaceCheck + + adminRegistryOverhead + + rateLimiterOverhead + + PerTokenOverheadGas*uint64(numTokens) +} diff --git a/core/capabilities/ccip/ccipevm/gas_helpers_test.go b/core/capabilities/ccip/ccipevm/gas_helpers_test.go new file mode 100644 index 00000000000..f7897898fbc --- /dev/null +++ b/core/capabilities/ccip/ccipevm/gas_helpers_test.go @@ -0,0 +1,157 @@ +package ccipevm + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +func Test_calculateMessageMaxGas(t *testing.T) { + type args struct { + dataLen int + numTokens int + extraArgs []byte + } + tests := []struct { + name string + args args + want uint64 + }{ + { + name: "base", + args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV1(200_000)}, + want: 1_022_264, + }, + { + name: "large", + args: args{dataLen: 1000, numTokens: 1000, extraArgs: makeExtraArgsV1(200_000)}, + want: 346_677_520, + }, + { + name: "overheadGas test 1", + args: args{dataLen: 0, numTokens: 0, extraArgs: makeExtraArgsV1(200_000)}, + want: 319_920, + }, + { + name: "overheadGas test 2", + args: args{dataLen: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), numTokens: 1, extraArgs: makeExtraArgsV1(200_000)}, + want: 675_948, + }, + { + name: "allowOOO set to true makes no difference to final gas estimate", + args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV2(200_000, true)}, + want: 1_022_264, + }, + { + name: "allowOOO set to false makes no difference to final gas estimate", + args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV2(200_000, false)}, + want: 1_022_264, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + msg := ccipocr3.Message{ + Data: make([]byte, tt.args.dataLen), + TokenAmounts: make([]ccipocr3.RampTokenAmount, tt.args.numTokens), + ExtraArgs: tt.args.extraArgs, + } + ep := EstimateProvider{} + got := ep.CalculateMessageMaxGas(msg) + t.Log(got) + assert.Equalf(t, tt.want, got, "calculateMessageMaxGas(%v, %v)", tt.args.dataLen, tt.args.numTokens) + }) + } +} + +// TestCalculateMaxGas is taken from the ccip repo where the CalculateMerkleTreeGas and CalculateMessageMaxGas values +// are combined to one function. +func TestCalculateMaxGas(t *testing.T) { + tests := []struct { + name string + numRequests int + dataLength int + numberOfTokens int + extraArgs []byte + want uint64 + }{ + { + name: "maxGasOverheadGas 1", + numRequests: 6, + dataLength: 0, + numberOfTokens: 0, + extraArgs: makeExtraArgsV1(200_000), + want: 322_992, + }, + { + name: "maxGasOverheadGas 2", + numRequests: 3, + dataLength: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + numberOfTokens: 1, + extraArgs: makeExtraArgsV1(200_000), + want: 678_508, + }, + { + name: "v2 extra args", + numRequests: 3, + dataLength: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + numberOfTokens: 1, + extraArgs: makeExtraArgsV2(200_000, true), + want: 678_508, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + msg := ccipocr3.Message{ + Data: make([]byte, tt.dataLength), + TokenAmounts: make([]ccipocr3.RampTokenAmount, tt.numberOfTokens), + ExtraArgs: tt.extraArgs, + } + ep := EstimateProvider{} + + gotTree := ep.CalculateMerkleTreeGas(tt.numRequests) + gotMsg := ep.CalculateMessageMaxGas(msg) + t.Log("want", tt.want, "got", gotTree+gotMsg) + assert.Equal(t, tt.want, gotTree+gotMsg) + }) + } +} + +func makeExtraArgsV1(gasLimit uint64) []byte { + // extra args is the tag followed by the gas limit abi-encoded. + var extraArgs []byte + extraArgs = append(extraArgs, evmExtraArgsV1Tag...) + gasLimitBytes := new(big.Int).SetUint64(gasLimit).Bytes() + // pad from the left to 32 bytes + gasLimitBytes = common.LeftPadBytes(gasLimitBytes, 32) + extraArgs = append(extraArgs, gasLimitBytes...) + return extraArgs +} + +func makeExtraArgsV2(gasLimit uint64, allowOOO bool) []byte { + // extra args is the tag followed by the gas limit and allowOOO abi-encoded. + var extraArgs []byte + extraArgs = append(extraArgs, evmExtraArgsV2Tag...) + gasLimitBytes := new(big.Int).SetUint64(gasLimit).Bytes() + // pad from the left to 32 bytes + gasLimitBytes = common.LeftPadBytes(gasLimitBytes, 32) + + // abi-encode allowOOO + var allowOOOBytes []byte + if allowOOO { + allowOOOBytes = append(allowOOOBytes, 1) + } else { + allowOOOBytes = append(allowOOOBytes, 0) + } + // pad from the left to 32 bytes + allowOOOBytes = common.LeftPadBytes(allowOOOBytes, 32) + + extraArgs = append(extraArgs, gasLimitBytes...) + extraArgs = append(extraArgs, allowOOOBytes...) + return extraArgs +} diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/inprocess.go index 6616d356756..fa74c1b0eaa 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/inprocess.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/superfakes" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/ethereum/go-ethereum/common" @@ -310,6 +311,8 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp ccipevm.NewExecutePluginCodecV1(), ccipevm.NewMessageHasherV1(), i.homeChainReader, + superfakes.NewNilTokenDataReader(), + ccipevm.NewGasEstimateProvider(), // TODO: this works for evm only, how about non-evm? contractReaders, chainWriters, ) diff --git a/core/capabilities/ccip/superfakes/token_data_reader.go b/core/capabilities/ccip/superfakes/token_data_reader.go new file mode 100644 index 00000000000..ff6a88076ce --- /dev/null +++ b/core/capabilities/ccip/superfakes/token_data_reader.go @@ -0,0 +1,23 @@ +package superfakes + +import ( + "context" + + "github.com/smartcontractkit/chainlink-ccip/execute/exectypes" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +// NewNilTokenDataReader returns a new nilTokenDataReader. +// This token data reader always returns nil for the token data. +func NewNilTokenDataReader() exectypes.TokenDataReader { + return &nilTokenDataReader{} +} + +type nilTokenDataReader struct{} + +// ReadTokenData implements exectypes.TokenDataReader. +func (t *nilTokenDataReader) ReadTokenData(ctx context.Context, srcChain ccipocr3.ChainSelector, num ccipocr3.SeqNum) (r [][]byte, err error) { + return nil, nil +} + +var _ exectypes.TokenDataReader = (*nilTokenDataReader)(nil) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index bb9ce89e3e3..2b261f90640 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d2e704977b0..9bb354f0d16 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1070,8 +1070,8 @@ github.com/smartcontractkit/chain-selectors v1.0.19 h1:y82TyWaOA6gSvi26bbyDYgfZv github.com/smartcontractkit/chain-selectors v1.0.19/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index c1b106d3186..d07503cddd8 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.19 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa diff --git a/go.sum b/go.sum index 3d0dd16d3a1..b74642c8b43 100644 --- a/go.sum +++ b/go.sum @@ -1027,8 +1027,8 @@ github.com/smartcontractkit/chain-selectors v1.0.19 h1:y82TyWaOA6gSvi26bbyDYgfZv github.com/smartcontractkit/chain-selectors v1.0.19/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e8e4bae14f0..cada40ad031 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -384,7 +384,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 7e19b5115c2..d7a5942e412 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1392,8 +1392,8 @@ github.com/smartcontractkit/chain-selectors v1.0.19 h1:y82TyWaOA6gSvi26bbyDYgfZv github.com/smartcontractkit/chain-selectors v1.0.19/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 7c2faa39968..c643a07f572 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -40,7 +40,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect k8s.io/apimachinery v0.30.2 // indirect ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 156ab3497d6..3ad8b958d11 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1374,8 +1374,8 @@ github.com/smartcontractkit/chain-selectors v1.0.19 h1:y82TyWaOA6gSvi26bbyDYgfZv github.com/smartcontractkit/chain-selectors v1.0.19/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0=