From c6b55adff2e719f36ca840e065d061fa5dfc353f Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Thu, 11 Apr 2024 14:29:26 +0200 Subject: [PATCH] Revert "Batch token price updates (#623)" This reverts commit 2963a90a --- .changeset/large-keys-sniff.md | 5 - core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- .../ocr2/plugins/ccip/ccipcommit/factory.go | 2 +- .../plugins/ccip/ccipcommit/initializers.go | 56 +--- .../ocr2/plugins/ccip/ccipcommit/ocr2.go | 24 +- .../ocr2/plugins/ccip/ccipcommit/ocr2_test.go | 263 ++++-------------- .../ccip/internal/ccipcommon/shortcuts.go | 64 ----- .../internal/ccipcommon/shortcuts_test.go | 183 ------------ .../ccipdata/mocks/offramp_reader_mock.go | 28 -- .../plugins/ccip/internal/ccipdata/reader.go | 1 - .../ccip/internal/ccipdata/v1_0_0/offramp.go | 13 +- .../v1_0_0/offramp_reader_unit_test.go | 23 -- .../ccip/internal/ccipdata/v1_0_0/onramp.go | 1 - .../ccipdata/v1_2_0/commit_store_test.go | 14 +- .../ccip/internal/ccipdata/v1_2_0/offramp.go | 16 +- .../v1_2_0/offramp_reader_unit_test.go | 36 --- .../ccip/internal/ccipdata/v1_2_0/onramp.go | 1 - 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 +- 24 files changed, 96 insertions(+), 658 deletions(-) delete mode 100644 .changeset/large-keys-sniff.md delete mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go diff --git a/.changeset/large-keys-sniff.md b/.changeset/large-keys-sniff.md deleted file mode 100644 index d62d504131..0000000000 --- a/.changeset/large-keys-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"ccip": patch ---- - -Add ability for leader lane to report all token prices for the lane diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 6c0f0b08ec..464eed4d43 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.13 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index ddaa20a7fc..395d4a366e 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1168,8 +1168,8 @@ github.com/smartcontractkit/chain-selectors v1.0.13 h1:vHMbh7Wu+W+/DSD88feiwMMSX github.com/smartcontractkit/chain-selectors v1.0.13/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 h1:GNhRKD3izyzAoGMXDvVUAwEuzz4Atdj3U3RH7eak5Is= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35/go.mod h1:2I0dWdYdK6jHPnSYYy7Y7Xp7L0YTnJ3KZtkhLQflsTU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 h1:+ncHpL0jLpdCXXOm4JanT1NJVXimysKhyQbK4X22A9g= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 h1:SmnFGUhzfyHS8WdekapbVypFCAXXRqiBdTp6I4oFCV0= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/factory.go b/core/services/ocr2/plugins/ccip/ccipcommit/factory.go index 54731e8e61..8720b77c09 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/factory.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/factory.go @@ -92,7 +92,7 @@ func (rf *CommitReportingPluginFactory) NewReportingPlugin(config types.Reportin F: config.F, lggr: lggr, destPriceRegistryReader: rf.destPriceRegReader, - offRampReaders: rf.config.offRamps, + offRampReader: rf.config.offRamp, gasPriceEstimator: rf.config.commitStore.GasPriceEstimator(), offchainConfig: pluginOffChainConfig, metricsCollector: rf.config.metricsCollector, diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go index d97bfc92ba..c7a6145309 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/Masterminds/semver/v3" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" chainselectors "github.com/smartcontractkit/chain-selectors" @@ -18,7 +17,6 @@ import ( commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider" @@ -45,7 +43,7 @@ import ( ) func NewCommitServices(ctx context.Context, lggr logger.Logger, jb job.Job, chainSet legacyevm.LegacyChainContainer, new bool, pr pipeline.Runner, argsNoPlugin libocr2.OCR2OracleArgs, logError func(string), qopts ...pg.QOpt) ([]job.ServiceCtx, error) { - pluginConfig, backfillArgs, chainHealthcheck, err := jobSpecToCommitPluginConfig(ctx, lggr, jb, pr, chainSet, qopts...) + pluginConfig, backfillArgs, chainHealthcheck, err := jobSpecToCommitPluginConfig(lggr, jb, pr, chainSet, qopts...) if err != nil { return nil, err } @@ -116,7 +114,7 @@ func UnregisterCommitPluginLpFilters(ctx context.Context, lggr logger.Logger, jb return multiErr } -func jobSpecToCommitPluginConfig(ctx context.Context, lggr logger.Logger, jb job.Job, pr pipeline.Runner, chainSet legacyevm.LegacyChainContainer, qopts ...pg.QOpt) (*CommitPluginStaticConfig, *ccipcommon.BackfillArgs, *cache.ObservedChainHealthcheck, error) { +func jobSpecToCommitPluginConfig(lggr logger.Logger, jb job.Job, pr pipeline.Runner, chainSet legacyevm.LegacyChainContainer, qopts ...pg.QOpt) (*CommitPluginStaticConfig, *ccipcommon.BackfillArgs, *cache.ObservedChainHealthcheck, error) { params, err := extractJobSpecParams(jb, chainSet) if err != nil { return nil, nil, nil, err @@ -190,68 +188,28 @@ func jobSpecToCommitPluginConfig(ctx context.Context, lggr logger.Logger, jb job if err != nil { return nil, nil, nil, errors.Wrap(err, "failed offramp reader") } - // Look up all destination offRamps connected to the same router - destRouterAddr, err := offRampReader.GetRouter(ctx) - if err != nil { - return nil, nil, nil, err - } - destRouterEvmAddr, err := ccipcalc.GenericAddrToEvm(destRouterAddr) - if err != nil { - return nil, nil, nil, err - } - destRouter, err := router.NewRouter(destRouterEvmAddr, params.destChain.Client()) - if err != nil { - return nil, nil, nil, err - } - destRouterOffRamps, err := destRouter.GetOffRamps(&bind.CallOpts{Context: ctx}) - if err != nil { - return nil, nil, nil, err - } - var destOffRampReaders []ccipdata.OffRampReader - for _, o := range destRouterOffRamps { - destOffRampAddr := cciptypes.Address(o.OffRamp.String()) - destOffRampReader, err2 := factory.NewOffRampReader( - commitLggr, - versionFinder, - destOffRampAddr, - params.destChain.Client(), - params.destChain.LogPoller(), - params.destChain.GasEstimator(), - params.destChain.Config().EVM().GasEstimator().PriceMax().ToInt(), - true, - qopts..., - ) - if err2 != nil { - return nil, nil, nil, err2 - } - - destOffRampReaders = append(destOffRampReaders, destOffRampReader) - } - onRampRouterAddr, err := onRampReader.RouterAddress() if err != nil { return nil, nil, nil, err } - sourceRouterAddr, err := ccipcalc.GenericAddrToEvm(onRampRouterAddr) + routerAddr, err := ccipcalc.GenericAddrToEvm(onRampRouterAddr) if err != nil { return nil, nil, nil, err } - sourceRouter, err := router.NewRouter(sourceRouterAddr, params.sourceChain.Client()) + sourceRouter, err := router.NewRouter(routerAddr, params.sourceChain.Client()) if err != nil { return nil, nil, nil, err } - sourceNative, err := sourceRouter.GetWrappedNative(&bind.CallOpts{Context: ctx}) + sourceNative, err := sourceRouter.GetWrappedNative(nil) if err != nil { return nil, nil, nil, err } // Prom wrappers onRampReader = observability.NewObservedOnRampReader(onRampReader, params.sourceChain.ID().Int64(), ccip.CommitPluginLabel) + offRampReader = observability.NewObservedOffRampReader(offRampReader, params.destChain.ID().Int64(), ccip.CommitPluginLabel) commitStoreReader = observability.NewObservedCommitStoreReader(commitStoreReader, params.destChain.ID().Int64(), ccip.CommitPluginLabel) metricsCollector := ccip.NewPluginMetricsCollector(ccip.CommitPluginLabel, params.sourceChain.ID().Int64(), params.destChain.ID().Int64()) - for i, o := range destOffRampReaders { - destOffRampReaders[i] = observability.NewObservedOffRampReader(o, params.destChain.ID().Int64(), ccip.CommitPluginLabel) - } chainHealthcheck := cache.NewObservedChainHealthCheck( cache.NewChainHealthcheck( @@ -281,7 +239,7 @@ func jobSpecToCommitPluginConfig(ctx context.Context, lggr logger.Logger, jb job return &CommitPluginStaticConfig{ lggr: commitLggr, onRampReader: onRampReader, - offRamps: destOffRampReaders, + offRamp: offRampReader, sourceNative: ccipcalc.EvmAddrToGeneric(sourceNative), priceGetter: priceGetter, sourceChainSelector: params.commitStoreStaticCfg.SourceChainSelector, diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go index c6c6b3f847..d776e41536 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go @@ -15,7 +15,6 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -59,7 +58,7 @@ type CommitPluginStaticConfig struct { sourceChainSelector uint64 sourceNative cciptypes.Address // Dest - offRamps []ccipdata.OffRampReader + offRamp ccipdata.OffRampReader commitStore ccipdata.CommitStoreReader destChainSelector uint64 priceRegistryProvider ccipdataprovider.PriceRegistry @@ -80,7 +79,7 @@ type CommitReportingPlugin struct { commitStoreReader ccipdata.CommitStoreReader destPriceRegistryReader ccipdata.PriceRegistryReader offchainConfig cciptypes.CommitOffchainConfig - offRampReaders []ccipdata.OffRampReader + offRampReader ccipdata.OffRampReader F int // Offchain priceGetter pricegetter.PriceGetter @@ -184,12 +183,13 @@ func (r *CommitReportingPlugin) observePriceUpdates( return nil, nil, nil } - sortedChainTokens, err := ccipcommon.GetSortedChainTokens(ctx, r.offRampReaders, r.destPriceRegistryReader) + feeTokens, bridgeableTokens, err := ccipcommon.GetDestinationTokens(ctx, r.offRampReader, r.destPriceRegistryReader) if err != nil { return nil, nil, fmt.Errorf("get destination tokens: %w", err) } + destTokens := ccipcommon.FlattenUniqueSlice(feeTokens, bridgeableTokens) - return r.generatePriceUpdates(ctx, lggr, sortedChainTokens) + return r.generatePriceUpdates(ctx, lggr, destTokens) } // All prices are USD ($1=1e18) denominated. All prices must be not nil. @@ -197,11 +197,12 @@ func (r *CommitReportingPlugin) observePriceUpdates( func (r *CommitReportingPlugin) generatePriceUpdates( ctx context.Context, lggr logger.Logger, - sortedChainTokens []cciptypes.Address, + destTokens []cciptypes.Address, ) (sourceGasPriceUSD *big.Int, tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { // Include wrapped native in our token query as way to identify the source native USD price. // notice USD is in 1e18 scale, i.e. $1 = 1e18 - queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{r.sourceNative}, sortedChainTokens) + queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{r.sourceNative}, destTokens) + sort.Slice(queryTokens, func(i, j int) bool { return queryTokens[i] < queryTokens[j] }) // make the query deterministic rawTokenPricesUSD, err := r.priceGetter.TokenPricesUSD(ctx, queryTokens) if err != nil { @@ -221,13 +222,13 @@ func (r *CommitReportingPlugin) generatePriceUpdates( return nil, nil, fmt.Errorf("missing source native (%s) price", r.sourceNative) } - destTokensDecimals, err := r.destPriceRegistryReader.GetTokensDecimals(ctx, sortedChainTokens) + destTokensDecimals, err := r.destPriceRegistryReader.GetTokensDecimals(ctx, destTokens) if err != nil { return nil, nil, fmt.Errorf("get tokens decimals: %w", err) } tokenPricesUSD = make(map[cciptypes.Address]*big.Int, len(rawTokenPricesUSD)) - for i, token := range sortedChainTokens { + for i, token := range destTokens { tokenPricesUSD[token] = calculateUsdPer1e18TokenAmount(rawTokenPricesUSD[token], destTokensDecimals[i]) } @@ -324,13 +325,14 @@ func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types. parsableObservations := ccip.GetParsableObservations[ccip.CommitObservation](lggr, observations) - sortedChainTokens, err := ccipcommon.GetSortedChainTokens(ctx, r.offRampReaders, r.destPriceRegistryReader) + feeTokens, bridgeableTokens, err := ccipcommon.GetDestinationTokens(ctx, r.offRampReader, r.destPriceRegistryReader) if err != nil { return false, nil, fmt.Errorf("get destination tokens: %w", err) } + destTokens := ccipcommon.FlattenUniqueSlice(feeTokens, bridgeableTokens) // Filters out parsable but faulty observations - validObservations, err := validateObservations(ctx, lggr, sortedChainTokens, r.F, parsableObservations, r.offchainConfig.PriceReportingDisabled) + validObservations, err := validateObservations(ctx, lggr, destTokens, r.F, parsableObservations, r.offchainConfig.PriceReportingDisabled) if err != nil { return false, nil, err } diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go index 34babb6b0b..39b167ffcb 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go @@ -2,12 +2,10 @@ package ccipcommit import ( "context" - "encoding/json" "fmt" "math/big" "math/rand" "reflect" - "slices" "sort" "testing" "time" @@ -38,7 +36,6 @@ import ( ccipcachemocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" @@ -51,28 +48,7 @@ import ( func TestCommitReportingPlugin_Observation(t *testing.T) { sourceNativeTokenAddr := ccipcalc.HexToAddress("1000") - - bridgedTokens := []cciptypes.Address{ - ccipcalc.HexToAddress("2000"), - ccipcalc.HexToAddress("3000"), - } - - // Token price in 1e18 USD precision - bridgedTokenPrices := map[cciptypes.Address]*big.Int{ - bridgedTokens[0]: big.NewInt(1), - bridgedTokens[1]: big.NewInt(2e18), - } - - bridgedTokenDecimals := map[cciptypes.Address]uint8{ - bridgedTokens[0]: 8, - bridgedTokens[1]: 18, - } - - // Token price of 1e18 token amount in 1e18 USD precision - expectedEncodedTokenPrice := map[cciptypes.Address]*big.Int{ - bridgedTokens[0]: big.NewInt(1e10), - bridgedTokens[1]: big.NewInt(2e18), - } + someTokenAddr := ccipcalc.HexToAddress("2000") testCases := []struct { name string @@ -85,7 +61,6 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { tokenDecimals map[cciptypes.Address]uint8 fee *big.Int priceReportingDisabled bool - multiOffRamps bool expErr bool expObs ccip.CommitObservation @@ -94,42 +69,21 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { name: "base report", commitStoreSeqNum: 54, tokenPrices: map[cciptypes.Address]*big.Int{ - bridgedTokens[0]: bridgedTokenPrices[bridgedTokens[0]], - bridgedTokens[1]: bridgedTokenPrices[bridgedTokens[1]], + someTokenAddr: big.NewInt(2), sourceNativeTokenAddr: big.NewInt(2e18), }, sendReqs: []cciptypes.EVM2EVMMessageWithTxMeta{ {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 54}}, {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 55}}, }, - fee: big.NewInt(2e18), - tokenDecimals: bridgedTokenDecimals, - expObs: ccip.CommitObservation{ - TokenPricesUSD: expectedEncodedTokenPrice, - SourceGasPriceUSD: big.NewInt(4e18), - Interval: cciptypes.CommitStoreInterval{ - Min: 54, - Max: 55, - }, - }, - }, - { - name: "multiple offRamps observation", - commitStoreSeqNum: 54, - tokenPrices: map[cciptypes.Address]*big.Int{ - bridgedTokens[0]: bridgedTokenPrices[bridgedTokens[0]], - bridgedTokens[1]: bridgedTokenPrices[bridgedTokens[1]], - sourceNativeTokenAddr: big.NewInt(2e18), - }, - sendReqs: []cciptypes.EVM2EVMMessageWithTxMeta{ - {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 54}}, - {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 55}}, + fee: big.NewInt(2e18), + tokenDecimals: map[cciptypes.Address]uint8{ + someTokenAddr: 8, }, - fee: big.NewInt(2e18), - tokenDecimals: bridgedTokenDecimals, - multiOffRamps: true, expObs: ccip.CommitObservation{ - TokenPricesUSD: expectedEncodedTokenPrice, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + someTokenAddr: big.NewInt(20000000000), + }, SourceGasPriceUSD: big.NewInt(4e18), Interval: cciptypes.CommitStoreInterval{ Min: 54, @@ -141,16 +95,17 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { name: "price reporting disabled", commitStoreSeqNum: 54, tokenPrices: map[cciptypes.Address]*big.Int{ - bridgedTokens[0]: bridgedTokenPrices[bridgedTokens[0]], - bridgedTokens[1]: bridgedTokenPrices[bridgedTokens[1]], + someTokenAddr: big.NewInt(2), sourceNativeTokenAddr: big.NewInt(2e18), }, sendReqs: []cciptypes.EVM2EVMMessageWithTxMeta{ {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 54}}, {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 55}}, }, - fee: big.NewInt(2e18), - tokenDecimals: bridgedTokenDecimals, + fee: big.NewInt(2e18), + tokenDecimals: map[cciptypes.Address]uint8{ + someTokenAddr: 8, + }, priceReportingDisabled: true, expObs: ccip.CommitObservation{ TokenPricesUSD: nil, @@ -193,23 +148,13 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { Return(tc.sendReqs, nil) } - var destTokens []cciptypes.Address - for tk := range tc.tokenDecimals { - destTokens = append(destTokens, tk) - } - // ensure destTokens and destDecimals are in the same order, avoid flaky test from unordered map iteration - sort.Slice(destTokens, func(i, j int) bool { - return destTokens[i] < destTokens[j] - }) - var destDecimals []uint8 - for _, token := range destTokens { - destDecimals = append(destDecimals, tc.tokenDecimals[token]) - } - priceGet := pricegetter.NewMockPriceGetter(t) if !tc.priceReportingDisabled && len(tc.tokenPrices) > 0 { - queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{sourceNativeTokenAddr}, destTokens) - priceGet.On("TokenPricesUSD", mock.Anything, queryTokens).Return(tc.tokenPrices, nil) + addrs := []cciptypes.Address{sourceNativeTokenAddr} + for addr := range tc.tokenDecimals { + addrs = append(addrs, addr) + } + priceGet.On("TokenPricesUSD", mock.Anything, addrs).Return(tc.tokenPrices, nil) } gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) @@ -220,8 +165,15 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { gasPriceEstimator.On("DenoteInUSD", p, tc.tokenPrices[sourceNativeTokenAddr]).Return(pUSD, nil) } - offRampReaderMocks := []*ccipdatamocks.OffRampReader{ccipdatamocks.NewOffRampReader(t)} - offRampReaderMocks[0].On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ + destTokens := make([]cciptypes.Address, 0) + destDecimals := make([]uint8, 0) + for tk, d := range tc.tokenDecimals { + destTokens = append(destTokens, tk) + destDecimals = append(destDecimals, d) + } + + offRampReader := ccipdatamocks.NewOffRampReader(t) + offRampReader.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ DestinationTokens: destTokens, }, nil).Maybe() @@ -229,26 +181,11 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { destPriceRegReader.On("GetFeeTokens", ctx).Return(nil, nil).Maybe() destPriceRegReader.On("GetTokensDecimals", ctx, destTokens).Return(destDecimals, nil).Maybe() - if tc.multiOffRamps { - offRampReaderMocks = append(offRampReaderMocks, ccipdatamocks.NewOffRampReader(t)) - offRampReaderMocks = append(offRampReaderMocks, ccipdatamocks.NewOffRampReader(t)) - offRampReaderMocks[1].On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ - DestinationTokens: destTokens[0:1], - }, nil).Once() - offRampReaderMocks[2].On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ - DestinationTokens: destTokens[1:2], - }, nil).Once() - } - var offRampReaders []ccipdata.OffRampReader - for _, offRamp := range offRampReaderMocks { - offRampReaders = append(offRampReaders, offRamp) - } - p := &CommitReportingPlugin{} p.lggr = logger.TestLogger(t) p.commitStoreReader = commitStoreReader p.onRampReader = onRampReader - p.offRampReaders = offRampReaders + p.offRampReader = offRampReader p.destPriceRegistryReader = destPriceRegReader p.priceGetter = priceGet p.sourceNative = sourceNativeTokenAddr @@ -265,19 +202,9 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { } assert.NoError(t, err) - if tc.expObs.TokenPricesUSD != nil { - // field ordering in mapping is not guaranteed, if TokenPricesUSD exists, unmarshal to compare mapping - var obsStuct ccip.CommitObservation - err = json.Unmarshal(obs, &obsStuct) - assert.NoError(t, err) - - assert.Equal(t, tc.expObs, obsStuct) - } else { - // if TokenPricesUSD is nil, compare the bytes directly, marshal then unmarshal turns nil map to empty - expObsBytes, err := tc.expObs.Marshal() - assert.NoError(t, err) - assert.Equal(t, expObsBytes, []byte(obs)) - } + expObsBytes, err := tc.expObs.Marshal() + assert.NoError(t, err) + assert.Equal(t, expObsBytes, []byte(obs)) }) } } @@ -295,7 +222,7 @@ func TestCommitReportingPlugin_Report(t *testing.T) { offRampReader := ccipdatamocks.NewOffRampReader(t) destPriceRegReader := ccipdatamocks.NewPriceRegistryReader(t) - p.offRampReaders = []ccipdata.OffRampReader{offRampReader} + p.offRampReader = offRampReader p.destPriceRegistryReader = destPriceRegReader offRampReader.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{}, nil).Maybe() destPriceRegReader.On("GetFeeTokens", ctx).Return(nil, nil).Maybe() @@ -324,7 +251,6 @@ func TestCommitReportingPlugin_Report(t *testing.T) { tokenPriceUpdates []cciptypes.TokenPriceUpdateWithTxMeta sendRequests []cciptypes.EVM2EVMMessageWithTxMeta priceReportingDisabled bool - multiOffRamps bool expCommitReport *cciptypes.CommitStoreReport expSeqNumRange cciptypes.CommitStoreInterval expErr bool @@ -363,62 +289,6 @@ func TestCommitReportingPlugin_Report(t *testing.T) { }, expErr: false, }, - { - name: "multiple offRamps report with token prices", - observations: []ccip.CommitObservation{ - { - Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, - SourceGasPriceUSD: gasPrice, - TokenPricesUSD: map[cciptypes.Address]*big.Int{ - ccipcalc.HexToAddress("2000"): big.NewInt(2000), - ccipcalc.HexToAddress("3000"): big.NewInt(3000), - }, - }, - { - Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, - SourceGasPriceUSD: gasPrice, - TokenPricesUSD: map[cciptypes.Address]*big.Int{ - ccipcalc.HexToAddress("2000"): big.NewInt(2000), - ccipcalc.HexToAddress("3000"): big.NewInt(3000), - }, - }, - }, - tokenDecimals: map[cciptypes.Address]uint8{ - ccipcalc.HexToAddress("2000"): 8, - ccipcalc.HexToAddress("3000"): 18, - }, - f: 1, - sendRequests: []cciptypes.EVM2EVMMessageWithTxMeta{ - { - EVM2EVMMessage: cciptypes.EVM2EVMMessage{ - SequenceNumber: 1, - }, - }, - }, - gasPriceUpdates: []cciptypes.GasPriceUpdateWithTxMeta{ - { - GasPriceUpdate: cciptypes.GasPriceUpdate{ - GasPrice: cciptypes.GasPrice{ - DestChainSelector: sourceChainSelector, - Value: big.NewInt(1), - }, - TimestampUnixSec: big.NewInt(time.Now().Add(-2 * gasPriceHeartBeat.Duration()).Unix()), - }, - }, - }, - multiOffRamps: true, - expSeqNumRange: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, - expCommitReport: &cciptypes.CommitStoreReport{ - MerkleRoot: [32]byte{}, - Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, - TokenPrices: []cciptypes.TokenPrice{ - {Token: ccipcalc.HexToAddress("2000"), Value: big.NewInt(2000)}, - {Token: ccipcalc.HexToAddress("3000"), Value: big.NewInt(3000)}, - }, - GasPrices: []cciptypes.GasPrice{{DestChainSelector: sourceChainSelector, Value: gasPrice}}, - }, - expErr: false, - }, { name: "empty", observations: []ccip.CommitObservation{ @@ -509,47 +379,20 @@ func TestCommitReportingPlugin_Report(t *testing.T) { gasPriceEstimator.On("Deviates", mock.Anything, mock.Anything, mock.Anything).Return(false, nil) } - var destTokens []cciptypes.Address - for tk := range tc.tokenDecimals { + destTokens := make([]cciptypes.Address, 0) + destDecimals := make([]uint8, 0) + for tk, d := range tc.tokenDecimals { destTokens = append(destTokens, tk) - } - sort.Slice(destTokens, func(i, j int) bool { - return destTokens[i] < destTokens[j] - }) - var destDecimals []uint8 - for _, token := range destTokens { - destDecimals = append(destDecimals, tc.tokenDecimals[token]) + destDecimals = append(destDecimals, d) } - offRampReaderMocks := []*ccipdatamocks.OffRampReader{ccipdatamocks.NewOffRampReader(t)} - offRampReaderMocks[0].On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ + offRampReader := ccipdatamocks.NewOffRampReader(t) + offRampReader.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ DestinationTokens: destTokens, }, nil).Maybe() destPriceRegistryReader.On("GetFeeTokens", ctx).Return(nil, nil).Maybe() - destPriceRegistryReader.On("GetTokensDecimals", ctx, mock.MatchedBy(func(tokens []cciptypes.Address) bool { - for _, token := range tokens { - if !slices.Contains(destTokens, token) { - return false - } - } - return true - })).Return(destDecimals, nil).Maybe() - - if tc.multiOffRamps { - offRampReaderMocks = append(offRampReaderMocks, ccipdatamocks.NewOffRampReader(t)) - offRampReaderMocks = append(offRampReaderMocks, ccipdatamocks.NewOffRampReader(t)) - offRampReaderMocks[1].On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ - DestinationTokens: destTokens[0:1], - }, nil).Once() - offRampReaderMocks[2].On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ - DestinationTokens: destTokens[1:2], - }, nil).Once() - } - var offRampReaders []ccipdata.OffRampReader - for _, offRamp := range offRampReaderMocks { - offRampReaders = append(offRampReaders, offRamp) - } + destPriceRegistryReader.On("GetTokensDecimals", ctx, destTokens).Return(destDecimals, nil).Maybe() lp := mocks2.NewLogPoller(t) commitStoreReader, err := v1_2_0.NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil, nil) @@ -563,7 +406,7 @@ func TestCommitReportingPlugin_Report(t *testing.T) { p.destPriceRegistryReader = destPriceRegistryReader p.onRampReader = onRampReader p.sourceChainSelector = sourceChainSelector - p.offRampReaders = offRampReaders + p.offRampReader = offRampReader p.gasPriceEstimator = gasPriceEstimator p.offchainConfig.GasPriceHeartBeat = gasPriceHeartBeat.Duration() p.commitStoreReader = commitStoreReader @@ -1410,22 +1253,15 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) defer gasPriceEstimator.AssertExpectations(t) - var destTokens []cciptypes.Address + tokens := make([]cciptypes.Address, 0, len(tc.tokenDecimals)) for tk := range tc.tokenDecimals { - destTokens = append(destTokens, tk) + tokens = append(tokens, tk) } - sort.Slice(destTokens, func(i, j int) bool { - return destTokens[i] < destTokens[j] - }) - var destDecimals []uint8 - for _, token := range destTokens { - destDecimals = append(destDecimals, tc.tokenDecimals[token]) - } - - queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{tc.sourceNativeToken}, destTokens) + tokens = ccipcommon.FlattenUniqueSlice(tokens, []cciptypes.Address{tc.sourceNativeToken}) + sort.Slice(tokens, func(i, j int) bool { return tokens[i] < tokens[j] }) - if len(queryTokens) > 0 { - priceGetter.On("TokenPricesUSD", mock.Anything, queryTokens).Return(tc.priceGetterRespData, tc.priceGetterRespErr) + if len(tokens) > 0 { + priceGetter.On("TokenPricesUSD", mock.Anything, tokens).Return(tc.priceGetterRespData, tc.priceGetterRespErr) } if tc.maxGasPrice > 0 { @@ -1442,6 +1278,13 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { gasPriceEstimator: gasPriceEstimator, } + destTokens := make([]cciptypes.Address, 0, len(tc.tokenDecimals)) + destDecimals := make([]uint8, 0, len(tc.tokenDecimals)) + for tk, d := range tc.tokenDecimals { + destTokens = append(destTokens, tk) + destDecimals = append(destDecimals, d) + } + destPriceReg := ccipdatamocks.NewPriceRegistryReader(t) destPriceReg.On("GetTokensDecimals", mock.Anything, destTokens).Return(destDecimals, nil).Maybe() p.destPriceRegistryReader = destPriceReg diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go index d46c6750b6..1016a23c98 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go @@ -4,22 +4,15 @@ import ( "context" "encoding/hex" "fmt" - "sort" "strings" - "sync" "golang.org/x/sync/errgroup" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) -const ( - offRampBatchSizeLimit = 30 -) - func GetMessageIDsAsHexString(messages []cciptypes.EVM2EVMMessage) []string { messageIDs := make([]string, 0, len(messages)) for _, m := range messages { @@ -33,63 +26,6 @@ type BackfillArgs struct { SourceStartBlock, DestStartBlock uint64 } -func GetSortedChainTokens(ctx context.Context, offRamps []ccipdata.OffRampReader, priceRegistry cciptypes.PriceRegistryReader) (chainTokens []cciptypes.Address, err error) { - return getSortedChainTokensWithBatchLimit(ctx, offRamps, priceRegistry, offRampBatchSizeLimit) -} - -// GetChainTokens returns union of all tokens supported on the destination chain, including fee tokens from the provided price registry -// and the bridgeable tokens from all the offRamps living on the chain. -func getSortedChainTokensWithBatchLimit(ctx context.Context, offRamps []ccipdata.OffRampReader, priceRegistry cciptypes.PriceRegistryReader, batchSize int) (chainTokens []cciptypes.Address, err error) { - if batchSize == 0 { - return nil, fmt.Errorf("batch size must be greater than 0") - } - - eg := new(errgroup.Group) - eg.SetLimit(batchSize) - - var destFeeTokens []cciptypes.Address - var destBridgeableTokens []cciptypes.Address - mu := &sync.RWMutex{} - - eg.Go(func() error { - tokens, err := priceRegistry.GetFeeTokens(ctx) - if err != nil { - return fmt.Errorf("get dest fee tokens: %w", err) - } - destFeeTokens = tokens - return nil - }) - - for _, o := range offRamps { - offRamp := o - eg.Go(func() error { - tokens, err := offRamp.GetTokens(ctx) - if err != nil { - return fmt.Errorf("get dest bridgeable tokens: %w", err) - } - mu.Lock() - destBridgeableTokens = append(destBridgeableTokens, tokens.DestinationTokens...) - mu.Unlock() - return nil - }) - } - - if err := eg.Wait(); err != nil { - return nil, err - } - - // same token can be returned by multiple offRamps, and fee token can overlap with bridgeable tokens, - // we need to dedup them to arrive at chain token set - chainTokens = FlattenUniqueSlice(destFeeTokens, destBridgeableTokens) - - // return the tokens in deterministic order to aid with testing and debugging - sort.Slice(chainTokens, func(i, j int) bool { - return chainTokens[i] < chainTokens[j] - }) - - return chainTokens, nil -} - // GetDestinationTokens returns the destination chain fee tokens from the provided price registry // and the bridgeable tokens from the offramp. func GetDestinationTokens(ctx context.Context, offRamp ccipdata.OffRampReader, priceRegistry cciptypes.PriceRegistryReader) (fee, bridged []cciptypes.Address, err error) { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go index 529a49307f..c3623b7f75 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go @@ -1,9 +1,7 @@ package ccipcommon import ( - "fmt" "math/rand" - "sort" "strconv" "testing" @@ -11,12 +9,6 @@ import ( "github.com/stretchr/testify/assert" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" ) func TestGetMessageIDsAsHexString(t *testing.T) { @@ -67,178 +59,3 @@ func TestFlattenUniqueSlice(t *testing.T) { }) } } - -func TestGetChainTokens(t *testing.T) { - var tokens []cciptypes.Address - for i := 0; i < 6; i++ { - tokens = append(tokens, ccipcalc.EvmAddrToGeneric(utils.RandomAddress())) - } - - testCases := []struct { - name string - feeTokens []cciptypes.Address - destTokens [][]cciptypes.Address - expectedChainTokens []cciptypes.Address - }{ - { - name: "empty", - feeTokens: []cciptypes.Address{}, - destTokens: [][]cciptypes.Address{{}}, - expectedChainTokens: []cciptypes.Address{}, - }, - { - name: "single offRamp", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: [][]cciptypes.Address{ - {tokens[1], tokens[2], tokens[3]}, - }, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3]}, - }, - { - name: "multiple offRamps with distinct tokens", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: [][]cciptypes.Address{ - {tokens[1], tokens[2]}, - {tokens[3], tokens[4]}, - {tokens[5]}, - }, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, - }, - { - name: "overlapping tokens", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: [][]cciptypes.Address{ - {tokens[0], tokens[1], tokens[2], tokens[3]}, - {tokens[0], tokens[2], tokens[3], tokens[4], tokens[5]}, - {tokens[5]}, - }, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, - }, - } - - ctx := testutils.Context(t) - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - priceRegistry := ccipdatamocks.NewPriceRegistryReader(t) - priceRegistry.On("GetFeeTokens", ctx).Return(tc.feeTokens, nil).Once() - - var offRamps []ccipdata.OffRampReader - for _, destTokens := range tc.destTokens { - offRamp := ccipdatamocks.NewOffRampReader(t) - offRamp.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{DestinationTokens: destTokens}, nil).Once() - offRamps = append(offRamps, offRamp) - } - - chainTokens, err := GetSortedChainTokens(ctx, offRamps, priceRegistry) - assert.NoError(t, err) - - sort.Slice(tc.expectedChainTokens, func(i, j int) bool { - return tc.expectedChainTokens[i] < tc.expectedChainTokens[j] - }) - assert.Equal(t, tc.expectedChainTokens, chainTokens) - }) - } -} - -func TestGetChainTokensWithBatchLimit(t *testing.T) { - numTokens := 100 - var tokens []cciptypes.Address - for i := 0; i < numTokens; i++ { - tokens = append(tokens, ccipcalc.EvmAddrToGeneric(utils.RandomAddress())) - } - - expectedTokens := make([]cciptypes.Address, numTokens) - copy(expectedTokens, tokens) - sort.Slice(expectedTokens, func(i, j int) bool { - return expectedTokens[i] < expectedTokens[j] - }) - - testCases := []struct { - name string - batchSize int - numOffRamps uint - expectError bool - }{ - { - name: "default case", - batchSize: offRampBatchSizeLimit, - numOffRamps: 20, - expectError: false, - }, - { - name: "limit of 0 expects error", - batchSize: 0, - numOffRamps: 20, - expectError: true, - }, - { - name: "low limit of 1 with 1 offRamps", - batchSize: 1, - numOffRamps: 1, - expectError: false, - }, - { - name: "low limit of 1 with many offRamps", - batchSize: 1, - numOffRamps: 200, - expectError: false, - }, - { - name: "high limit of 1000 with few offRamps", - batchSize: 1000, - numOffRamps: 20, - expectError: false, - }, - { - name: "high limit of 1000 with many offRamps", - batchSize: 1000, - numOffRamps: 200, - expectError: false, - }, - } - - ctx := testutils.Context(t) - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - priceRegistry := ccipdatamocks.NewPriceRegistryReader(t) - priceRegistry.On("GetFeeTokens", ctx).Return(tokens[0:10], nil).Maybe() - - var offRamps []ccipdata.OffRampReader - for i := 0; i < int(tc.numOffRamps); i++ { - offRamp := ccipdatamocks.NewOffRampReader(t) - offRamp.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{DestinationTokens: tokens[i%numTokens:]}, nil).Maybe() - offRamps = append(offRamps, offRamp) - } - - chainTokens, err := getSortedChainTokensWithBatchLimit(ctx, offRamps, priceRegistry, tc.batchSize) - if tc.expectError { - assert.Error(t, err) - return - } - - assert.NoError(t, err) - assert.Equal(t, expectedTokens, chainTokens) - }) - } -} - -func TestIsTxRevertError(t *testing.T) { - testCases := []struct { - name string - inputError error - expectedOutput bool - }{ - {name: "empty", inputError: nil, expectedOutput: false}, - {name: "non-revert error", inputError: fmt.Errorf("nothing"), expectedOutput: false}, - {name: "geth error", inputError: fmt.Errorf("execution reverted"), expectedOutput: true}, - {name: "nethermind error", inputError: fmt.Errorf("VM execution error"), expectedOutput: true}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.expectedOutput, IsTxRevertError(tc.inputError)) - }) - } -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go index 9c22cea6d8..1947758c73 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go @@ -270,34 +270,6 @@ func (_m *OffRampReader) GetExecutionStateChangesBetweenSeqNums(ctx context.Cont return r0, r1 } -// GetRouter provides a mock function with given fields: ctx -func (_m *OffRampReader) GetRouter(ctx context.Context) (ccip.Address, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetRouter") - } - - var r0 ccip.Address - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(ccip.Address) - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetSenderNonce provides a mock function with given fields: ctx, sender func (_m *OffRampReader) GetSenderNonce(ctx context.Context, sender ccip.Address) (uint64, error) { ret := _m.Called(ctx, sender) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go index 79fa78d355..bbdeb76182 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go index c9b2697251..fea303e5c2 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go @@ -367,14 +367,6 @@ func (o *OffRamp) GetTokens(ctx context.Context) (cciptypes.OffRampTokens, error }) } -func (o *OffRamp) GetRouter(ctx context.Context) (cciptypes.Address, error) { - dynamicConfig, err := o.offRampV100.GetDynamicConfig(&bind.CallOpts{Context: ctx}) - if err != nil { - return "", err - } - return ccipcalc.EvmAddrToGeneric(dynamicConfig.Router), nil -} - func (o *OffRamp) getPoolsByDestTokens(ctx context.Context, tokenAddrs []common.Address) ([]common.Address, error) { evmCalls := make([]rpclib.EvmCall, 0, len(tokenAddrs)) for _, tk := range tokenAddrs { @@ -457,10 +449,7 @@ func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, o InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, } - onchainConfig := cciptypes.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds), - Router: cciptypes.Address(onchainConfigParsed.Router.String()), - } + onchainConfig := cciptypes.ExecOnchainConfig{PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds)} gasPriceEstimator := prices.NewExecGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0) o.UpdateDynamicConfig(onchainConfig, offchainConfig, gasPriceEstimator) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go index 2914a0097b..cfbdd86bb8 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go @@ -12,12 +12,10 @@ import ( "github.com/stretchr/testify/require" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks/v1_0_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -212,24 +210,3 @@ func Test_LogsAreProperlyMarkedAsFinalized(t *testing.T) { }) } } - -func TestGetRouter(t *testing.T) { - routerAddr := utils.RandomAddress() - - mockOffRamp := mock_contracts.NewEVM2EVMOffRampInterface(t) - mockOffRamp.On("GetDynamicConfig", mock.Anything).Return(evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig{ - Router: routerAddr, - }, nil) - - offRamp := OffRamp{ - offRampV100: mockOffRamp, - } - - ctx := testutils.Context(t) - gotRouterAddr, err := offRamp.GetRouter(ctx) - require.NoError(t, err) - - gotRouterEvmAddr, err := ccipcalc.GenericAddrToEvm(gotRouterAddr) - require.NoError(t, err) - assert.Equal(t, routerAddr, gotRouterEvmAddr) -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go index d6b142e946..9c787e32c4 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go index fcb18ffe2d..42609f72c6 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go @@ -151,9 +151,9 @@ func TestCommitStoreV120ffchainConfigDecodingCompatibility(t *testing.T) { t.Parallel() tests := []struct { - name string - config []byte - priceReportingDisabled bool + name string + config []byte + priceReporting bool }{ { name: "with MaxGasPrice", @@ -169,7 +169,7 @@ func TestCommitStoreV120ffchainConfigDecodingCompatibility(t *testing.T) { "SourceMaxGasPrice": 100000000, "InflightCacheExpiry": "180s" }`), - priceReportingDisabled: false, + priceReporting: false, }, { name: "without MaxGasPrice", @@ -183,7 +183,7 @@ func TestCommitStoreV120ffchainConfigDecodingCompatibility(t *testing.T) { "TokenPriceDeviationPPB": 12, "InflightCacheExpiry": "180s" }`), - priceReportingDisabled: false, + priceReporting: false, }, { name: "with PriceReportingDisabled", @@ -198,7 +198,7 @@ func TestCommitStoreV120ffchainConfigDecodingCompatibility(t *testing.T) { "InflightCacheExpiry": "180s", "PriceReportingDisabled": true }`), - priceReportingDisabled: true, + priceReporting: true, }, } for _, tc := range tests { @@ -214,7 +214,7 @@ func TestCommitStoreV120ffchainConfigDecodingCompatibility(t *testing.T) { TokenPriceHeartBeat: *config.MustNewDuration(2 * time.Minute), TokenPriceDeviationPPB: 12, InflightCacheExpiry: *config.MustNewDuration(3 * time.Minute), - PriceReportingDisabled: tc.priceReportingDisabled, + PriceReportingDisabled: tc.priceReporting, }, decoded) }) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go index b66ae8aef2..76c02de83b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -123,7 +122,7 @@ func (c JSONExecOffchainConfig) Validate() error { // OffRamp In 1.2 we have a different estimator impl type OffRamp struct { *v1_0_0.OffRamp - offRampV120 evm_2_evm_offramp.EVM2EVMOffRampInterface + offRampV120 *evm_2_evm_offramp.EVM2EVMOffRamp } func (o *OffRamp) CurrentRateLimiterState(ctx context.Context) (cciptypes.TokenBucketRateLimit, error) { @@ -140,14 +139,6 @@ func (o *OffRamp) CurrentRateLimiterState(ctx context.Context) (cciptypes.TokenB }, nil } -func (o *OffRamp) GetRouter(ctx context.Context) (cciptypes.Address, error) { - dynamicConfig, err := o.offRampV120.GetDynamicConfig(&bind.CallOpts{Context: ctx}) - if err != nil { - return "", err - } - return ccipcalc.EvmAddrToGeneric(dynamicConfig.Router), nil -} - func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, offchainConfigBytes []byte) (cciptypes.Address, cciptypes.Address, error) { // Same as the v1.0.0 method, except for the ExecOnchainConfig type. onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfig](onchainConfigBytes) @@ -174,10 +165,7 @@ func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, o InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, } - onchainConfig := cciptypes.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds), - Router: cciptypes.Address(onchainConfigParsed.Router.String()), - } + onchainConfig := cciptypes.ExecOnchainConfig{PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds)} priceEstimator := prices.NewDAGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0, 0) o.UpdateDynamicConfig(onchainConfig, offchainConfig, priceEstimator) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go deleted file mode 100644 index 838a9d1aec..0000000000 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package v1_2_0 - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" -) - -func TestGetRouter(t *testing.T) { - routerAddr := utils.RandomAddress() - - mockOffRamp := mock_contracts.NewEVM2EVMOffRampInterface(t) - mockOffRamp.On("GetDynamicConfig", mock.Anything).Return(evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig{ - Router: routerAddr, - }, nil) - - offRamp := OffRamp{ - offRampV120: mockOffRamp, - } - - ctx := testutils.Context(t) - gotRouterAddr, err := offRamp.GetRouter(ctx) - require.NoError(t, err) - - gotRouterEvmAddr, err := ccipcalc.GenericAddrToEvm(gotRouterAddr) - require.NoError(t, err) - assert.Equal(t, routerAddr, gotRouterEvmAddr) -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go index 573eb60e88..d5c732af01 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" diff --git a/go.mod b/go.mod index af4683e74a..86b749a720 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chain-selectors v1.0.13 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 5e00381550..450d7a14cb 100644 --- a/go.sum +++ b/go.sum @@ -1163,8 +1163,8 @@ github.com/smartcontractkit/chain-selectors v1.0.13 h1:vHMbh7Wu+W+/DSD88feiwMMSX github.com/smartcontractkit/chain-selectors v1.0.13/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 h1:GNhRKD3izyzAoGMXDvVUAwEuzz4Atdj3U3RH7eak5Is= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35/go.mod h1:2I0dWdYdK6jHPnSYYy7Y7Xp7L0YTnJ3KZtkhLQflsTU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 h1:+ncHpL0jLpdCXXOm4JanT1NJVXimysKhyQbK4X22A9g= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 h1:SmnFGUhzfyHS8WdekapbVypFCAXXRqiBdTp6I4oFCV0= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a76c050b5a..6e54dae389 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -27,7 +27,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.13 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 github.com/smartcontractkit/chainlink-testing-framework v1.28.1-0.20240402041143-d05d8fef4769 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 84d586a64a..3e084b1c2f 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1512,8 +1512,8 @@ github.com/smartcontractkit/chain-selectors v1.0.13 h1:vHMbh7Wu+W+/DSD88feiwMMSX github.com/smartcontractkit/chain-selectors v1.0.13/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 h1:GNhRKD3izyzAoGMXDvVUAwEuzz4Atdj3U3RH7eak5Is= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35/go.mod h1:2I0dWdYdK6jHPnSYYy7Y7Xp7L0YTnJ3KZtkhLQflsTU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 h1:+ncHpL0jLpdCXXOm4JanT1NJVXimysKhyQbK4X22A9g= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 h1:SmnFGUhzfyHS8WdekapbVypFCAXXRqiBdTp6I4oFCV0= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f5e15ac5f2..e2365c6ef7 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,7 +15,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 github.com/smartcontractkit/chainlink-testing-framework v1.28.1-0.20240402041143-d05d8fef4769 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 2c6aa1f3ab..3099fea64f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1495,8 +1495,8 @@ github.com/smartcontractkit/chain-selectors v1.0.13 h1:vHMbh7Wu+W+/DSD88feiwMMSX github.com/smartcontractkit/chain-selectors v1.0.13/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35 h1:GNhRKD3izyzAoGMXDvVUAwEuzz4Atdj3U3RH7eak5Is= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240311111125-22812a072c35/go.mod h1:2I0dWdYdK6jHPnSYYy7Y7Xp7L0YTnJ3KZtkhLQflsTU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116 h1:+ncHpL0jLpdCXXOm4JanT1NJVXimysKhyQbK4X22A9g= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240326183122-8012c0f08116/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04 h1:SmnFGUhzfyHS8WdekapbVypFCAXXRqiBdTp6I4oFCV0= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240319231131-2d0d99220a04/go.mod h1://xWphjmC6GWJtT8l86J2VpnG21xNwFCb0thzz4ItEk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo=