diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index f1845804677..8159427699c 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -6,6 +6,10 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/common" + + tt "github.com/smartcontractkit/chainlink/integration-tests/types" + "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-testing-framework/seth" @@ -32,9 +36,9 @@ func DeployAutoOCRRegistryAndRegistrar( return registry, registrar } -// DeployConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means +// DeployLegacyConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means // that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. -func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) ([]contracts.KeeperConsumer, []*big.Int) { +func DeployLegacyConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) ([]contracts.KeeperConsumer, []*big.Int) { // Fund deployers with LINK, no need to do this for Native token if !isBillingTokenNative { err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) @@ -54,6 +58,28 @@ func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts. return upkeeps, upkeepIds } +// DeployConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means +// that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. +func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken, config tt.AutomationTestConfig) ([]contracts.KeeperConsumer, []*big.Int) { + // Fund deployers with LINK, no need to do this for Native token + if !isBillingTokenNative { + err := SetupMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, config) + require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") + } + + upkeeps := DeployKeeperConsumers(t, chainClient, numberOfUpkeeps, isLogTrigger, isMercury) + require.Equal(t, numberOfUpkeeps, len(upkeeps), "Number of upkeeps should match") + var upkeepsAddresses []string + for _, upkeep := range upkeeps { + upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) + } + upkeepIds := RegisterUpkeepContracts( + t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, isMercury, isBillingTokenNative, wethToken, + ) + require.Equal(t, numberOfUpkeeps, len(upkeepIds), "Number of upkeepIds should match") + return upkeeps, upkeepIds +} + // DeployPerformanceConsumers deploys and registers keeper performance consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkeep will be registered with root key address as the admin. // that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. func DeployPerformanceConsumers( @@ -69,12 +95,13 @@ func DeployPerformanceConsumers( blockInterval, // Interval of blocks that upkeeps are expected to be performed checkGasToBurn, // How much gas should be burned on checkUpkeep() calls performGasToBurn int64, // How much gas should be burned on performUpkeep() calls + config tt.AutomationTestConfig, ) ([]contracts.KeeperConsumerPerformance, []*big.Int) { upkeeps := DeployKeeperConsumersPerformance( t, chainClient, numberOfUpkeeps, blockRange, blockInterval, checkGasToBurn, performGasToBurn, ) - err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) + err := SetupMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, config) require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") var upkeepsAddresses []string @@ -97,10 +124,11 @@ func DeployPerformDataCheckerConsumers( linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, expectedData []byte, + config tt.AutomationTestConfig, ) ([]contracts.KeeperPerformDataChecker, []*big.Int) { upkeeps := DeployPerformDataChecker(t, chainClient, numberOfUpkeeps, expectedData) - err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) + err := SetupMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, config) require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") var upkeepsAddresses []string @@ -111,6 +139,45 @@ func DeployPerformDataCheckerConsumers( return upkeeps, upkeepIds } +func SetupMultiCallAddress(chainClient *seth.Client, testConfig tt.AutomationTestConfig) (common.Address, error) { + if testConfig.GetAutomationConfig().UseExistingMultiCallContract() { + multiCallAddress, err := testConfig.GetAutomationConfig().MultiCallContractAddress() + if err != nil { + return common.Address{}, errors.Wrap(err, "Error getting existing multicall contract address") + } + return multiCallAddress, nil + } + + multicallAddress, err := contracts.DeployMultiCallContract(chainClient) + if err != nil { + return common.Address{}, errors.Wrap(err, "Error deploying multicall contract") + } + return multicallAddress, nil +} + +// SetupMultiCallAndFundDeploymentAddresses setups multicall contract and sends link funds to each deployment address +func SetupMultiCallAndFundDeploymentAddresses( + chainClient *seth.Client, + linkToken contracts.LinkToken, + numberOfUpkeeps int, + linkFundsForEachUpkeep *big.Int, + testConfig tt.AutomationTestConfig, +) error { + concurrency, err := GetAndAssertCorrectConcurrency(chainClient, 1) + if err != nil { + return err + } + + operationsPerAddress := numberOfUpkeeps / concurrency + + multicallAddress, err := SetupMultiCallAddress(chainClient, testConfig) + if err != nil { + return errors.Wrap(err, "Error deploying multicall contract") + } + + return SendLinkFundsToDeploymentAddresses(chainClient, concurrency, numberOfUpkeeps, operationsPerAddress, multicallAddress, linkFundsForEachUpkeep, linkToken) +} + // DeployMultiCallAndFundDeploymentAddresses deploys multicall contract and sends link funds to each deployment address func DeployMultiCallAndFundDeploymentAddresses( chainClient *seth.Client, diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index 6ce35873d88..9b3013f778e 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -12,6 +12,8 @@ import ( "testing" "time" + tt "github.com/smartcontractkit/chainlink/integration-tests/types" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" @@ -45,7 +47,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/models" ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/lib/concurrency" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" ) @@ -61,6 +63,8 @@ type NodeDetails struct { type AutomationTest struct { ChainClient *seth.Client + TestConfig tt.AutomationTestConfig + LinkToken contracts.LinkToken Transcoder contracts.UpkeepTranscoder LINKETHFeed contracts.MockLINKETHFeed @@ -110,9 +114,11 @@ func NewAutomationTestK8s( l zerolog.Logger, chainClient *seth.Client, chainlinkNodes []*client.ChainlinkK8sClient, + config tt.AutomationTestConfig, ) *AutomationTest { return &AutomationTest{ ChainClient: chainClient, + TestConfig: config, ChainlinkNodesk8s: chainlinkNodes, IsOnk8s: true, TransmitterKeyIndex: 0, @@ -126,9 +132,11 @@ func NewAutomationTestDocker( l zerolog.Logger, chainClient *seth.Client, chainlinkNodes []*client.ChainlinkClient, + config tt.AutomationTestConfig, ) *AutomationTest { return &AutomationTest{ ChainClient: chainClient, + TestConfig: config, ChainlinkNodes: chainlinkNodes, IsOnk8s: false, TransmitterKeyIndex: 0, @@ -173,6 +181,7 @@ func (a *AutomationTest) LoadLINK(address string) error { return err } a.LinkToken = linkToken + a.Logger.Info().Str("LINK Token Address", a.LinkToken.Address()).Msg("Successfully loaded LINK Token") return nil } @@ -191,6 +200,7 @@ func (a *AutomationTest) LoadTranscoder(address string) error { return err } a.Transcoder = transcoder + a.Logger.Info().Str("Transcoder Address", a.Transcoder.Address()).Msg("Successfully loaded Transcoder") return nil } @@ -209,6 +219,7 @@ func (a *AutomationTest) LoadLinkEthFeed(address string) error { return err } a.LINKETHFeed = ethLinkFeed + a.Logger.Info().Str("LINK/ETH Feed Address", a.LINKETHFeed.Address()).Msg("Successfully loaded LINK/ETH Feed") return nil } @@ -227,6 +238,7 @@ func (a *AutomationTest) LoadEthUSDFeed(address string) error { return err } a.ETHUSDFeed = ethUSDFeed + a.Logger.Info().Str("ETH/USD Feed Address", a.ETHUSDFeed.Address()).Msg("Successfully loaded ETH/USD Feed") return nil } @@ -245,6 +257,7 @@ func (a *AutomationTest) LoadLinkUSDFeed(address string) error { return err } a.LINKUSDFeed = linkUSDFeed + a.Logger.Info().Str("LINK/USD Feed Address", a.LINKUSDFeed.Address()).Msg("Successfully loaded LINK/USD Feed") return nil } @@ -263,6 +276,7 @@ func (a *AutomationTest) LoadWETH(address string) error { return err } a.WETHToken = wethToken + a.Logger.Info().Str("WETH Token Address", a.WETHToken.Address()).Msg("Successfully loaded WETH Token") return nil } @@ -281,6 +295,7 @@ func (a *AutomationTest) LoadEthGasFeed(address string) error { return err } a.GasFeed = gasFeed + a.Logger.Info().Str("Gas Feed Address", a.GasFeed.Address()).Msg("Successfully loaded Gas Feed") return nil } @@ -305,12 +320,13 @@ func (a *AutomationTest) DeployRegistry() error { return nil } -func (a *AutomationTest) LoadRegistry(address string) error { - registry, err := contracts.LoadKeeperRegistry(a.Logger, a.ChainClient, common.HexToAddress(address), a.RegistrySettings.RegistryVersion) +func (a *AutomationTest) LoadRegistry(registryAddress, chainModuleAddress string) error { + registry, err := contracts.LoadKeeperRegistry(a.Logger, a.ChainClient, common.HexToAddress(registryAddress), a.RegistrySettings.RegistryVersion, common.HexToAddress(chainModuleAddress)) if err != nil { return err } a.Registry = registry + a.Logger.Info().Str("ChainModule Address", chainModuleAddress).Str("Registry Address", a.Registry.Address()).Msg("Successfully loaded Registry") return nil } @@ -337,6 +353,7 @@ func (a *AutomationTest) LoadRegistrar(address string) error { if err != nil { return err } + a.Logger.Info().Str("Registrar Address", registrar.Address()).Msg("Successfully loaded Registrar") a.Registrar = registrar return nil } @@ -597,6 +614,7 @@ func (a *AutomationTest) SetConfigOnRegistry() error { }, } } + a.Logger.Debug().Interface("ocrConfig", ocrConfig).Msg("Setting OCR3 config") err = a.Registry.SetConfigTypeSafe(ocrConfig) if err != nil { return errors.Join(err, fmt.Errorf("failed to set config on registry")) @@ -846,7 +864,7 @@ func (a *AutomationTest) AddJobsAndSetConfig(t *testing.T) { l.Info().Str("Registry Address", a.Registry.Address()).Msg("Successfully setConfig on registry") } -func (a *AutomationTest) SetupMercuryMock(t *testing.T, imposters []ctfTestEnv.KillgraveImposter) { +func (a *AutomationTest) SetupMercuryMock(t *testing.T, imposters []ctftestenv.KillgraveImposter) { if a.IsOnk8s { t.Error("mercury mock is not supported on k8s") } @@ -874,61 +892,104 @@ func (a *AutomationTest) setupDeployment(t *testing.T, addJobs bool) { l.Info().Msg("Collected Node Details") l.Debug().Interface("Node Details", a.NodeDetails).Msg("Node Details") - err = a.DeployLINK() - require.NoError(t, err, "Error deploying link token contract") + if a.TestConfig.GetAutomationConfig().UseExistingLinkTokenContract() { + linkAddress, err := a.TestConfig.GetAutomationConfig().LinkTokenContractAddress() + require.NoError(t, err, "Error getting link token contract address") + err = a.LoadLINK(linkAddress.String()) + require.NoError(t, err, "Error loading link token contract") + } else { + err = a.DeployLINK() + require.NoError(t, err, "Error deploying link token contract") + } - err = a.DeployWETH() - require.NoError(t, err, "Error deploying weth token contract") + if a.TestConfig.GetAutomationConfig().UseExistingWethContract() { + wethAddress, err := a.TestConfig.GetAutomationConfig().WethContractAddress() + require.NoError(t, err, "Error getting weth token contract address") + err = a.LoadWETH(wethAddress.String()) + require.NoError(t, err, "Error loading weth token contract") + } else { + err = a.DeployWETH() + require.NoError(t, err, "Error deploying weth token contract") + } - err = a.DeployLinkEthFeed() - require.NoError(t, err, "Error deploying link eth feed contract") - err = a.DeployGasFeed() - require.NoError(t, err, "Error deploying gas feed contract") + if a.TestConfig.GetAutomationConfig().UseExistingLinkEthFeedContract() { + linkEthFeedAddress, err := a.TestConfig.GetAutomationConfig().LinkEthFeedContractAddress() + require.NoError(t, err, "Error getting link eth feed contract address") + err = a.LoadLinkEthFeed(linkEthFeedAddress.String()) + require.NoError(t, err, "Error loading link eth feed contract") + } else { + err = a.DeployLinkEthFeed() + require.NoError(t, err, "Error deploying link eth feed contract") + } - err = a.DeployEthUSDFeed() - require.NoError(t, err, "Error deploying eth usd feed contract") + if a.TestConfig.GetAutomationConfig().UseExistingEthGasFeedContract() { + gasFeedAddress, err := a.TestConfig.GetAutomationConfig().EthGasFeedContractAddress() + require.NoError(t, err, "Error getting gas feed contract address") + err = a.LoadEthGasFeed(gasFeedAddress.String()) + require.NoError(t, err, "Error loading gas feed contract") + } else { + err = a.DeployGasFeed() + require.NoError(t, err, "Error deploying gas feed contract") + } - err = a.DeployLinkUSDFeed() - require.NoError(t, err, "Error deploying link usd feed contract") + if a.TestConfig.GetAutomationConfig().UseExistingEthUSDFeedContract() { + ethUsdFeedAddress, err := a.TestConfig.GetAutomationConfig().EthUSDFeedContractAddress() + require.NoError(t, err, "Error getting eth usd feed contract address") + err = a.LoadEthUSDFeed(ethUsdFeedAddress.String()) + require.NoError(t, err, "Error loading eth usd feed contract") + } else { + err = a.DeployEthUSDFeed() + require.NoError(t, err, "Error deploying eth usd feed contract") + } - err = a.DeployTranscoder() - require.NoError(t, err, "Error deploying transcoder contract") + if a.TestConfig.GetAutomationConfig().UseExistingLinkUSDFeedContract() { + linkUsdFeedAddress, err := a.TestConfig.GetAutomationConfig().LinkUSDFeedContractAddress() + require.NoError(t, err, "Error getting link usd feed contract address") + err = a.LoadLinkUSDFeed(linkUsdFeedAddress.String()) + require.NoError(t, err, "Error loading link usd feed contract") + } else { + err = a.DeployLinkUSDFeed() + require.NoError(t, err, "Error deploying link usd feed contract") + } - err = a.DeployRegistry() - require.NoError(t, err, "Error deploying registry contract") - err = a.DeployRegistrar() - require.NoError(t, err, "Error deploying registrar contract") + if a.TestConfig.GetAutomationConfig().UseExistingTranscoderContract() { + transcoderAddress, err := a.TestConfig.GetAutomationConfig().TranscoderContractAddress() + require.NoError(t, err, "Error getting transcoder contract address") + err = a.LoadTranscoder(transcoderAddress.String()) + require.NoError(t, err, "Error loading transcoder contract") + } else { + err = a.DeployTranscoder() + require.NoError(t, err, "Error deploying transcoder contract") + } + + if a.TestConfig.GetAutomationConfig().UseExistingRegistryContract() { + chainModuleAddress, err := a.TestConfig.GetAutomationConfig().ChainModuleContractAddress() + require.NoError(t, err, "Error getting chain module contract address") + registryAddress, err := a.TestConfig.GetAutomationConfig().RegistryContractAddress() + require.NoError(t, err, "Error getting registry contract address") + err = a.LoadRegistry(registryAddress.String(), chainModuleAddress.String()) + require.NoError(t, err, "Error loading registry contract") + if a.Registry.RegistryOwnerAddress().String() != a.ChainClient.MustGetRootKeyAddress().String() { + l.Debug().Str("RootKeyAddress", a.ChainClient.MustGetRootKeyAddress().String()).Str("Registry Owner Address", a.Registry.RegistryOwnerAddress().String()).Msg("Registry owner address is not the root key address") + t.Error("Registry owner address is not the root key address") + t.FailNow() + } + } else { + err = a.DeployRegistry() + require.NoError(t, err, "Error deploying registry contract") + } + + if a.TestConfig.GetAutomationConfig().UseExistingRegistrarContract() { + registrarAddress, err := a.TestConfig.GetAutomationConfig().RegistrarContractAddress() + require.NoError(t, err, "Error getting registrar contract address") + err = a.LoadRegistrar(registrarAddress.String()) + require.NoError(t, err, "Error loading registrar contract") + } else { + err = a.DeployRegistrar() + require.NoError(t, err, "Error deploying registrar contract") + } if addJobs { a.AddJobsAndSetConfig(t) } } - -func (a *AutomationTest) LoadAutomationDeployment(t *testing.T, linkTokenAddress, - linkEthFeedAddress, linkUsdFeedAddress, EthUsdFeedAddress, gasFeedAddress, transcoderAddress, registryAddress, registrarAddress string) { - l := logging.GetTestLogger(t) - err := a.CollectNodeDetails() - require.NoError(t, err, "Error collecting node details") - l.Info().Msg("Collected Node Details") - l.Debug().Interface("Node Details", a.NodeDetails).Msg("Node Details") - - err = a.LoadLINK(linkTokenAddress) - require.NoError(t, err, "Error loading link token contract") - - err = a.LoadLinkEthFeed(linkEthFeedAddress) - require.NoError(t, err, "Error loading link eth feed contract") - err = a.LoadEthGasFeed(gasFeedAddress) - require.NoError(t, err, "Error loading gas feed contract") - err = a.LoadEthUSDFeed(EthUsdFeedAddress) - require.NoError(t, err, "Error loading eth usd feed contract") - err = a.LoadLinkUSDFeed(linkUsdFeedAddress) - require.NoError(t, err, "Error loading link usd feed contract") - err = a.LoadTranscoder(transcoderAddress) - require.NoError(t, err, "Error loading transcoder contract") - err = a.LoadRegistry(registryAddress) - require.NoError(t, err, "Error loading registry contract") - err = a.LoadRegistrar(registrarAddress) - require.NoError(t, err, "Error loading registrar contract") - - a.AddJobsAndSetConfig(t) -} diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index 80822a95af4..c7694946cf9 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -117,7 +117,7 @@ func DeployKeeperContracts( } registrar := DeployKeeperRegistrar(t, client, registryVersion, linkToken, registrarSettings, registry) - upkeeps, upkeepIds := DeployConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false, false, nil) + upkeeps, upkeepIds := DeployLegacyConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false, false, nil) return registry, registrar, upkeeps, upkeepIds } diff --git a/integration-tests/benchmark/automation_test.go b/integration-tests/benchmark/automation_test.go index 534fca2f513..0a63ff2c27a 100644 --- a/integration-tests/benchmark/automation_test.go +++ b/integration-tests/benchmark/automation_test.go @@ -120,13 +120,15 @@ func TestAutomationBenchmark(t *testing.T) { if err = actions.TeardownRemoteSuite(keeperBenchmarkTest.TearDownVals(t)); err != nil { l.Error().Err(err).Msg("Error when tearing down remote suite") } else { - err := testEnvironment.Client.RemoveNamespace(testEnvironment.Cfg.Namespace) - if err != nil { - l.Error().Err(err).Msg("Error removing namespace") + if *config.GetAutomationConfig().Benchmark.DeleteJobsOnEnd { + err := testEnvironment.Client.RemoveNamespace(testEnvironment.Cfg.Namespace) + if err != nil { + l.Error().Err(err).Msg("Error removing namespace") + } } } }) - keeperBenchmarkTest.Setup(testEnvironment, &config) + keeperBenchmarkTest.Setup(testEnvironment, config) keeperBenchmarkTest.Run() } @@ -314,18 +316,19 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.Automation }, })) } - - // TODO we need to update the image in CTF, the old one is not available anymore - // deploy blockscout if running on simulated - // if testNetwork.Simulated { - // testEnvironment. - // AddChart(blockscout.New(&blockscout.Props{ - // Name: "geth-blockscout", - // WsURL: testNetwork.URLs[0], - // HttpURL: testNetwork.HTTPURLs[0]})) - // } - err := testEnvironment.Run() - require.NoError(t, err, "Error launching test environment") + var err error + if testNetwork.Simulated { + // TODO we need to update the image in CTF, the old one is not available anymore + // deploy blockscout if running on simulated + //testEnvironment. + // AddChart(blockscout.New(&blockscout.Props{ + // Name: "geth-blockscout", + // WsURL: testNetwork.URLs[0], + // HttpURL: testNetwork.HTTPURLs[0]})) + // Need to setup geth node before setting up chainlink nodes + err = testEnvironment.Run() + require.NoError(t, err, "Error launching test environment") + } if testEnvironment.WillUseRemoteRunner() { return testEnvironment, testNetwork diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index cde5962390a..c0823f482ad 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -240,7 +240,7 @@ func TestAutomationChaos(t *testing.T) { require.NoError(t, err, "Error tearing down environment") }) - a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes) + a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes, &config) a.SetMercuryCredentialName("cred1") a.RegistrySettings = actions.ReadRegistryConfig(config) a.RegistrySettings.RegistryVersion = rv @@ -259,11 +259,11 @@ func TestAutomationChaos(t *testing.T) { var consumersLogTrigger, consumersConditional []contracts.KeeperConsumer var upkeepidsConditional, upkeepidsLogTrigger []*big.Int - consumersConditional, upkeepidsConditional = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil) + consumersConditional, upkeepidsConditional = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil, &config) consumers := consumersConditional upkeepIDs := upkeepidsConditional if rv >= eth_contracts.RegistryVersion_2_1 { - consumersLogTrigger, upkeepidsLogTrigger = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil) + consumersLogTrigger, upkeepidsLogTrigger = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil, &config) consumers = append(consumersConditional, consumersLogTrigger...) upkeepIDs = append(upkeepidsConditional, upkeepidsLogTrigger...) diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index d9d4a730c3c..5a3e405d92f 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -194,10 +194,11 @@ func (v *EthereumKeeperRegistry) RegistryOwnerAddress() common.Address { func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error { txOpts := v.client.NewTXOpts() var err error + var decodedTx *seth.DecodedTransaction switch v.version { case ethereum.RegistryVersion_2_1: - _, err = v.client.Decode(v.registry2_1.SetConfigTypeSafe(txOpts, + decodedTx, err = v.client.Decode(v.registry2_1.SetConfigTypeSafe(txOpts, ocrConfig.Signers, ocrConfig.Transmitters, ocrConfig.F, @@ -206,7 +207,7 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error ocrConfig.OffchainConfig, )) case ethereum.RegistryVersion_2_2: - _, err = v.client.Decode(v.registry2_2.SetConfigTypeSafe(txOpts, + decodedTx, err = v.client.Decode(v.registry2_2.SetConfigTypeSafe(txOpts, ocrConfig.Signers, ocrConfig.Transmitters, ocrConfig.F, @@ -215,7 +216,7 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error ocrConfig.OffchainConfig, )) case ethereum.RegistryVersion_2_3: - _, err = v.client.Decode(v.registry2_3.SetConfigTypeSafe(txOpts, + decodedTx, err = v.client.Decode(v.registry2_3.SetConfigTypeSafe(txOpts, ocrConfig.Signers, ocrConfig.Transmitters, ocrConfig.F, @@ -228,7 +229,7 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error default: return fmt.Errorf("SetConfigTypeSafe is not supported in keeper registry version %d", v.version) } - + v.l.Debug().Interface("decodedTx", decodedTx).Msg("SetConfigTypeSafe") return err } @@ -1528,7 +1529,7 @@ func deployRegistry23(client *seth.Client, opts *KeeperRegistryOpts) (KeeperRegi } // LoadKeeperRegistry returns deployed on given address EthereumKeeperRegistry -func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Address, registryVersion eth_contracts.KeeperRegistryVersion) (KeeperRegistry, error) { +func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Address, registryVersion eth_contracts.KeeperRegistryVersion, chainModuleAddress common.Address) (KeeperRegistry, error) { var keeper *EthereumKeeperRegistry var err error switch registryVersion { @@ -1545,7 +1546,7 @@ func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Ad case eth_contracts.RegistryVersion_2_2: // why the contract name is not the same as the actual contract name? keeper, err = loadRegistry2_2(client, address) case eth_contracts.RegistryVersion_2_3: - keeper, err = loadRegistry2_3(client, address) + keeper, err = loadRegistry2_3(client, address, chainModuleAddress) default: return nil, fmt.Errorf("keeper registry version %d is not supported", registryVersion) } @@ -1685,24 +1686,24 @@ func loadRegistry2_2(client *seth.Client, address common.Address) (*EthereumKeep }, nil } -func loadRegistry2_3(client *seth.Client, address common.Address) (*EthereumKeeperRegistry, error) { - abi, err := iregistry23.IAutomationRegistryMaster23MetaData.GetAbi() +func loadRegistry2_3(client *seth.Client, address, chainModuleAddress common.Address) (*EthereumKeeperRegistry, error) { + + loader := seth.NewContractLoader[iregistry23.IAutomationRegistryMaster23](client) + instance, err := loader.LoadContract("AutomationRegistry2_3", address, iregistry23.IAutomationRegistryMaster23MetaData.GetAbi, iregistry23.NewIAutomationRegistryMaster23) if err != nil { - return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistry2_3 ABI: %w", err) + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to load AutomationRegistry2_3 instance: %w", err) } - client.ContractStore.AddABI("AutomationRegistry2_3", *abi) - client.ContractStore.AddBIN("AutomationRegistry2_3", common.FromHex(iregistry23.IAutomationRegistryMaster23MetaData.Bin)) - - instance, err := iregistry23.NewIAutomationRegistryMaster23(address, wrappers.MustNewWrappedContractBackend(nil, client)) + chainModule, err := loadChainModule(client, chainModuleAddress) if err != nil { - return &EthereumKeeperRegistry{}, fmt.Errorf("failed to instantiate AutomationRegistry2_3 instance: %w", err) + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to load chain module: %w", err) } return &EthereumKeeperRegistry{ address: &address, client: client, registry2_3: instance, + chainModule: chainModule, }, nil } @@ -1758,6 +1759,26 @@ func deployOptimismModule(client *seth.Client) (common.Address, error) { return data.Address, nil } +func loadChainModule(client *seth.Client, address common.Address) (*i_chain_module.IChainModule, error) { + abi, err := i_chain_module.IChainModuleMetaData.GetAbi() + if err != nil { + return &i_chain_module.IChainModule{}, fmt.Errorf("failed to get IChainModule ABI: %w", err) + } + + client.ContractStore.AddABI("IChainModule", *abi) + client.ContractStore.AddBIN("IChainModule", common.FromHex(i_chain_module.IChainModuleMetaData.Bin)) + + chainModule, err := i_chain_module.NewIChainModule( + address, + wrappers.MustNewWrappedContractBackend(nil, client), + ) + if err != nil { + return &i_chain_module.IChainModule{}, fmt.Errorf("failed to instantiate IChainModule instance: %w", err) + } + + return chainModule, nil +} + func deployBaseModule(client *seth.Client) (common.Address, error) { abi, err := chain_module_base.ChainModuleBaseMetaData.GetAbi() if err != nil { @@ -2193,17 +2214,10 @@ func LoadKeeperRegistrar(client *seth.Client, address common.Address, registryVe if registryVersion == eth_contracts.RegistryVersion_1_1 || registryVersion == eth_contracts.RegistryVersion_1_2 || registryVersion == eth_contracts.RegistryVersion_1_3 { - abi, err := keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.GetAbi() - if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar1_2 ABI: %w", err) - } - - client.ContractStore.AddABI("KeeperRegistrar1_2", *abi) - client.ContractStore.AddBIN("KeeperRegistrar1_2", common.FromHex(keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.Bin)) - - instance, err := keeper_registrar_wrapper1_2.NewKeeperRegistrar(address, wrappers.MustNewWrappedContractBackend(nil, client)) + loader := seth.NewContractLoader[keeper_registrar_wrapper1_2.KeeperRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar1_2", address, keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.GetAbi, keeper_registrar_wrapper1_2.NewKeeperRegistrar) if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar1_2 instance: %w", err) + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar1_2 instance: %w", err) } return &EthereumKeeperRegistrar{ @@ -2212,44 +2226,43 @@ func LoadKeeperRegistrar(client *seth.Client, address common.Address, registryVe registrar: instance, }, err } else if registryVersion == eth_contracts.RegistryVersion_2_0 { - abi, err := keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.GetAbi() + loader := seth.NewContractLoader[keeper_registrar_wrapper2_0.KeeperRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar2_0", address, keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.GetAbi, keeper_registrar_wrapper2_0.NewKeeperRegistrar) if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar2_0 ABI: %w", err) + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar2_0 instance: %w", err) } - client.ContractStore.AddABI("KeeperRegistrar2_0", *abi) - client.ContractStore.AddBIN("KeeperRegistrar2_0", common.FromHex(keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.Bin)) - - instance, err := keeper_registrar_wrapper2_0.NewKeeperRegistrar(address, wrappers.MustNewWrappedContractBackend(nil, client)) + return &EthereumKeeperRegistrar{ + address: &address, + client: client, + registrar20: instance, + }, nil + } else if registryVersion == eth_contracts.RegistryVersion_2_1 || registryVersion == eth_contracts.RegistryVersion_2_2 { + loader := seth.NewContractLoader[registrar21.AutomationRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar2_1", address, registrar21.AutomationRegistrarMetaData.GetAbi, registrar21.NewAutomationRegistrar) if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar2_0 instance: %w", err) + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar2_1 instance: %w", err) } return &EthereumKeeperRegistrar{ address: &address, client: client, - registrar20: instance, + registrar21: instance, }, nil - } - - abi, err := registrar21.AutomationRegistrarMetaData.GetAbi() - if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar2_1 ABI: %w", err) - } - - client.ContractStore.AddABI("KeeperRegistrar2_1", *abi) - client.ContractStore.AddBIN("KeeperRegistrar2_1", common.FromHex(registrar21.AutomationRegistrarMetaData.Bin)) + } else if registryVersion == eth_contracts.RegistryVersion_2_3 { + loader := seth.NewContractLoader[registrar23.AutomationRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar2_3", address, registrar23.AutomationRegistrarMetaData.GetAbi, registrar23.NewAutomationRegistrar) + if err != nil { + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar2_3 instance: %w", err) + } - instance, err := registrar21.NewAutomationRegistrar(address, wrappers.MustNewWrappedContractBackend(nil, client)) - if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar2_1 instance: %w", err) + return &EthereumKeeperRegistrar{ + address: &address, + client: client, + registrar23: instance, + }, nil } - - return &EthereumKeeperRegistrar{ - address: &address, - client: client, - registrar21: instance, - }, nil + return &EthereumKeeperRegistrar{}, fmt.Errorf("unsupported registry version: %v", registryVersion) } type EthereumAutomationLogTriggeredStreamsLookupUpkeepConsumer struct { @@ -2702,21 +2715,42 @@ func (v *EthereumAutomationConsumerBenchmark) GetUpkeepCount(ctx context.Context }, id) } -// DeployKeeperConsumerBenchmark deploys a keeper consumer benchmark contract with a standard contract backend -func DeployKeeperConsumerBenchmark(client *seth.Client) (AutomationConsumerBenchmark, error) { - return deployKeeperConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { +// DeployAutomationConsumerBenchmark deploys a keeper consumer benchmark contract with a standard contract backend +func DeployAutomationConsumerBenchmark(client *seth.Client) (AutomationConsumerBenchmark, error) { + return deployAutomationConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { return wrappers.MustNewWrappedContractBackend(nil, client) }) } -// DeployKeeperConsumerBenchmarkWithRetry deploys a keeper consumer benchmark contract with a read-only operations retrying contract backend -func DeployKeeperConsumerBenchmarkWithRetry(client *seth.Client, logger zerolog.Logger, maxAttempts uint, retryDelay time.Duration) (AutomationConsumerBenchmark, error) { - return deployKeeperConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { +func LoadAutomationConsumerBenchmark(client *seth.Client, address common.Address) (*EthereumAutomationConsumerBenchmark, error) { + abi, err := automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.GetAbi() + if err != nil { + return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to get AutomationConsumerBenchmark token ABI: %w", err) + } + + client.ContractStore.AddABI("AutomationConsumerBenchmark", *abi) + client.ContractStore.AddBIN("AutomationConsumerBenchmark", common.FromHex(automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.Bin)) + + consumer, err := automation_consumer_benchmark.NewAutomationConsumerBenchmark(address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to instantiate EthereumAutomationConsumerBenchmark instance: %w", err) + } + + return &EthereumAutomationConsumerBenchmark{ + client: client, + consumer: consumer, + address: &address, + }, nil +} + +// DeployAutomationConsumerBenchmarkWithRetry deploys a keeper consumer benchmark contract with a read-only operations retrying contract backend +func DeployAutomationConsumerBenchmarkWithRetry(client *seth.Client, logger zerolog.Logger, maxAttempts uint, retryDelay time.Duration) (AutomationConsumerBenchmark, error) { + return deployAutomationConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { return wrappers.MustNewRetryingWrappedContractBackend(client, logger, maxAttempts, retryDelay) }) } -func deployKeeperConsumerBenchmarkWithWrapperFn(client *seth.Client, wrapperConstrFn func(client *seth.Client) *wrappers.WrappedContractBackend) (AutomationConsumerBenchmark, error) { +func deployAutomationConsumerBenchmarkWithWrapperFn(client *seth.Client, wrapperConstrFn func(client *seth.Client) *wrappers.WrappedContractBackend) (AutomationConsumerBenchmark, error) { abi, err := automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.GetAbi() if err != nil { return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to get AutomationConsumerBenchmark ABI: %w", err) @@ -2738,8 +2772,8 @@ func deployKeeperConsumerBenchmarkWithWrapperFn(client *seth.Client, wrapperCons }, nil } -// KeeperConsumerBenchmarkUpkeepObserver is a header subscription that awaits for a round of upkeeps -type KeeperConsumerBenchmarkUpkeepObserver struct { +// AutomationConsumerBenchmarkUpkeepObserver is a header subscription that awaits for a round of upkeeps +type AutomationConsumerBenchmarkUpkeepObserver struct { instance AutomationConsumerBenchmark registry KeeperRegistry upkeepID *big.Int @@ -2763,9 +2797,9 @@ type KeeperConsumerBenchmarkUpkeepObserver struct { l zerolog.Logger } -// NewKeeperConsumerBenchmarkUpkeepObserver provides a new instance of a NewKeeperConsumerBenchmarkUpkeepObserver +// NewAutomationConsumerBenchmarkUpkeepObserver provides a new instance of a NewAutomationConsumerBenchmarkUpkeepObserver // Used to track and log benchmark test results for keepers -func NewKeeperConsumerBenchmarkUpkeepObserver( +func NewAutomationConsumerBenchmarkUpkeepObserver( contract AutomationConsumerBenchmark, registry KeeperRegistry, upkeepID *big.Int, @@ -2775,8 +2809,8 @@ func NewKeeperConsumerBenchmarkUpkeepObserver( upkeepIndex int64, firstEligibleBuffer int64, logger zerolog.Logger, -) *KeeperConsumerBenchmarkUpkeepObserver { - return &KeeperConsumerBenchmarkUpkeepObserver{ +) *AutomationConsumerBenchmarkUpkeepObserver { + return &AutomationConsumerBenchmarkUpkeepObserver{ instance: contract, registry: registry, upkeepID: upkeepID, @@ -2798,7 +2832,7 @@ func NewKeeperConsumerBenchmarkUpkeepObserver( // ReceiveHeader will query the latest Keeper round and check to see whether upkeep was performed, it returns // true when observation has finished. -func (o *KeeperConsumerBenchmarkUpkeepObserver) ReceiveHeader(receivedHeader *blockchain.SafeEVMHeader) (bool, error) { +func (o *AutomationConsumerBenchmarkUpkeepObserver) ReceiveHeader(receivedHeader *blockchain.SafeEVMHeader) (bool, error) { if receivedHeader.Number.Uint64() <= o.lastBlockNum { // Uncle / reorg we won't count return false, nil } @@ -2901,12 +2935,12 @@ func (o *KeeperConsumerBenchmarkUpkeepObserver) ReceiveHeader(receivedHeader *bl } // Complete returns whether watching for upkeeps has completed -func (o *KeeperConsumerBenchmarkUpkeepObserver) Complete() bool { +func (o *AutomationConsumerBenchmarkUpkeepObserver) Complete() bool { return o.complete } // LogDetails logs the results of the benchmark test to testreporter -func (o *KeeperConsumerBenchmarkUpkeepObserver) LogDetails() { +func (o *AutomationConsumerBenchmarkUpkeepObserver) LogDetails() { report := testreporters.KeeperBenchmarkTestReport{ ContractAddress: o.instance.Address(), TotalEligibleCount: o.countEligible, diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index 6c49d1be44b..3cd931ecef0 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -311,7 +311,7 @@ Load Config: multicallAddress, err := contracts.DeployMultiCallContract(chainClient) require.NoError(t, err, "Error deploying multicall contract") - a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes) + a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes, &loadedTestConfig) a.RegistrySettings = actions.ReadRegistryConfig(loadedTestConfig) a.RegistrySettings.RegistryVersion = registryVersion a.PluginConfig = actions.ReadPluginConfig(loadedTestConfig) diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 85ca4b4264a..fde37d9f06f 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -132,7 +132,7 @@ func TestAutomationReorg(t *testing.T) { gethRPCClient := ctfClient.NewRPCClient(evmNetwork.HTTPURLs[0], nil) - a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients) + a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients, &config) a.SetMercuryCredentialName("cred1") a.RegistrySettings = actions.ReadRegistryConfig(config) a.RegistrySettings.RegistryVersion = registryVersion @@ -169,6 +169,7 @@ func TestAutomationReorg(t *testing.T) { false, false, a.WETHToken, + &config, ) if isLogTrigger { diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index f5a329a1a29..2e56237e9ca 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -20,7 +20,7 @@ import ( "github.com/onsi/gomega" "github.com/stretchr/testify/require" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" @@ -142,6 +142,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { isMercury, isBillingTokenNative, a.WETHToken, + &cfg, ) // Do it in two separate loops, so we don't end up setting up one upkeep, but starting the consumer for another one @@ -268,20 +269,7 @@ func TestSetUpkeepTriggerConfig(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - true, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, true, false, false, nil, &config) // Start log trigger based upkeeps for all consumers for i := 0; i < len(consumers); i++ { @@ -451,20 +439,7 @@ func TestAutomationAddFunds(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(1), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(1), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -531,20 +506,7 @@ func TestAutomationPauseUnPause(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -632,20 +594,7 @@ func TestAutomationRegisterUpkeep(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -728,20 +677,7 @@ func TestAutomationPauseRegistry(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -808,20 +744,7 @@ func TestAutomationKeeperNodesDown(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -929,6 +852,7 @@ func TestAutomationPerformSimulation(t *testing.T) { 5, // Interval of blocks that upkeeps are expected to be performed 100000, // How much gas should be burned on checkUpkeep() calls 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit + &config, ) t.Cleanup(func() { @@ -1000,6 +924,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { 5, // Interval of blocks that upkeeps are expected to be performed 100000, // How much gas should be burned on checkUpkeep() calls 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit + &config, ) t.Cleanup(func() { @@ -1152,6 +1077,7 @@ func TestUpdateCheckData(t *testing.T) { big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, []byte(automationExpectedData), + &config, ) t.Cleanup(func() { @@ -1223,20 +1149,7 @@ func TestSetOffchainConfigWithMaxGasPrice(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -1435,7 +1348,7 @@ func setupAutomationTestDocker( _ = actions.ReturnFundsFromNodes(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs())) }) - a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients) + a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients, automationTestConfig) a.SetMercuryCredentialName("cred1") a.RegistrySettings = registryConfig a.RegistrarSettings = contracts.KeeperRegistrarSettings{ @@ -1450,16 +1363,16 @@ func setupAutomationTestDocker( a.SetDockerEnv(env) if isMercuryV02 || isMercuryV03 { - var imposters []ctfTestEnv.KillgraveImposter - mercuryv03Mock200 := ctfTestEnv.KillgraveImposter{ - Request: ctfTestEnv.KillgraveRequest{ + var imposters []ctftestenv.KillgraveImposter + mercuryv03Mock200 := ctftestenv.KillgraveImposter{ + Request: ctftestenv.KillgraveRequest{ Method: http.MethodGet, Endpoint: "/api/v1/reports/bulk", SchemaFile: nil, Params: &map[string]string{"feedIDs": "0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c", "timestamp": "{[\\d+]}"}, Headers: nil, }, - Response: ctfTestEnv.KillgraveResponse{ + Response: ctftestenv.KillgraveResponse{ Status: 200, Body: `{"reports":[{"feedID":"0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c","validFromTimestamp":0,"observationsTimestamp":0,"fullReport":"0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000081401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000289ad8d367000000000000000000000000000000000000000000000000000000289acf0b38000000000000000000000000000000000000000000000000000000289b3da40000000000000000000000000000000000000000000000000000000000018ae7ce74d9fa252a8983976eab600dc7590c778d04813430841bc6e765c34cd81a168d00000000000000000000000000000000000000000000000000000000018ae7cb0000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000000000000260412b94e525ca6cedc9f544fd86f77606d52fe731a5d069dbe836a8bfc0fb8c911963b0ae7a14971f3b4621bffb802ef0605392b9a6c89c7fab1df8633a5ade00000000000000000000000000000000000000000000000000000000000000024500c2f521f83fba5efc2bf3effaaedde43d0a4adff785c1213b712a3aed0d8157642a84324db0cf9695ebd27708d4608eb0337e0dd87b0e43f0fa70c700d911"}]}`, BodyFile: nil, @@ -1468,15 +1381,15 @@ func setupAutomationTestDocker( }, } - mercuryv02Mock200 := ctfTestEnv.KillgraveImposter{ - Request: ctfTestEnv.KillgraveRequest{ + mercuryv02Mock200 := ctftestenv.KillgraveImposter{ + Request: ctftestenv.KillgraveRequest{ Method: http.MethodGet, Endpoint: "/client", SchemaFile: nil, Params: &map[string]string{"feedIdHex": "{0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c|0x4554482d5553442d415242495452554d2d544553544e45540000000000000000}", "blockNumber": "{[\\d+]}"}, Headers: nil, }, - Response: ctfTestEnv.KillgraveResponse{ + Response: ctftestenv.KillgraveResponse{ Status: 200, Body: `{"chainlinkBlob":"0x0001c38d71fed6c320b90e84b6f559459814d068e2a1700adc931ca9717d4fe70000000000000000000000000000000000000000000000000000000001a80b52b4bf1233f9cb71144a253a1791b202113c4ab4a92fa1b176d684b4959666ff8200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004254432d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000645570be000000000000000000000000000000000000000000000000000002af2b818dc5000000000000000000000000000000000000000000000000000002af2426faf3000000000000000000000000000000000000000000000000000002af32dc209700000000000000000000000000000000000000000000000000000000012130f8df0a9745bb6ad5e2df605e158ba8ad8a33ef8a0acf9851f0f01668a3a3f2b68600000000000000000000000000000000000000000000000000000000012130f60000000000000000000000000000000000000000000000000000000000000002c4a7958dce105089cf5edb68dad7dcfe8618d7784eb397f97d5a5fade78c11a58275aebda478968e545f7e3657aba9dcbe8d44605e4c6fde3e24edd5e22c94270000000000000000000000000000000000000000000000000000000000000002459c12d33986018a8959566d145225f0c4a4e61a9a3f50361ccff397899314f0018162cf10cd89897635a0bb62a822355bd199d09f4abe76e4d05261bb44733d"}`, BodyFile: nil, diff --git a/integration-tests/smoke/log_poller_test.go b/integration-tests/smoke/log_poller_test.go index c7f5483ac15..b5891e7a3e8 100644 --- a/integration-tests/smoke/log_poller_test.go +++ b/integration-tests/smoke/log_poller_test.go @@ -306,20 +306,7 @@ func prepareEnvironment(l zerolog.Logger, t *testing.T, testConfig *tc.TestConfi logScannerSettings, ) - _, upkeepIDs := actions.DeployConsumers( - t, - chainClient, - registry, - registrar, - linkToken, - upKeepsNeeded, - big.NewInt(int64(9e18)), - uint32(2500000), - true, - false, - false, - nil, - ) + _, upkeepIDs := actions.DeployLegacyConsumers(t, chainClient, registry, registrar, linkToken, upKeepsNeeded, big.NewInt(int64(9e18)), uint32(2500000), true, false, false, nil) err = logpoller.AssertUpkeepIdsUniqueness(upkeepIDs) require.NoError(t, err, "Error asserting upkeep ids uniqueness") diff --git a/integration-tests/testconfig/automation/config.go b/integration-tests/testconfig/automation/config.go index 2dc68ebf8f8..e462ff15c17 100644 --- a/integration-tests/testconfig/automation/config.go +++ b/integration-tests/testconfig/automation/config.go @@ -2,9 +2,12 @@ package automation import ( "errors" + "fmt" "math/big" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) @@ -15,6 +18,7 @@ type Config struct { AutomationConfig *AutomationConfig `toml:"AutomationConfig"` Resiliency *ResiliencyConfig `toml:"Resiliency"` Benchmark *Benchmark `toml:"Benchmark"` + Contracts *Contracts `toml:"Contracts"` } func (c *Config) Validate() error { @@ -417,3 +421,429 @@ func (c *ResiliencyConfig) Validate() error { return nil } + +type Contracts struct { + ShouldBeUsed *bool `toml:"use"` + LinkTokenAddress *string `toml:"link_token"` + WethAddress *string `toml:"weth"` + TranscoderAddress *string `toml:"transcoder"` + ChainModuleAddress *string `toml:"chain_module"` + RegistryAddress *string `toml:"registry"` + RegistrarAddress *string `toml:"registrar"` + LinkEthFeedAddress *string `toml:"link_eth_feed"` + EthGasFeedAddress *string `toml:"eth_gas_feed"` + EthUSDFeedAddress *string `toml:"eth_usd_feed"` + LinkUSDFeedAddress *string `toml:"link_usd_feed"` + UpkeepContractAddresses []string `toml:"upkeep_contracts"` + MultiCallAddress *string `toml:"multicall"` + Settings map[string]ContractSetting `toml:"Settings"` +} + +func (o *Contracts) Validate() error { + if o.LinkTokenAddress != nil && !common.IsHexAddress(*o.LinkTokenAddress) { + return errors.New("link_token must be a valid ethereum address") + } + if o.WethAddress != nil && !common.IsHexAddress(*o.WethAddress) { + return errors.New("weth must be a valid ethereum address") + } + if o.TranscoderAddress != nil && !common.IsHexAddress(*o.TranscoderAddress) { + return errors.New("transcoder must be a valid ethereum address") + } + if o.ChainModuleAddress != nil && !common.IsHexAddress(*o.ChainModuleAddress) { + return errors.New("chain_module must be a valid ethereum address") + } + if o.RegistryAddress != nil && !common.IsHexAddress(*o.RegistryAddress) { + return errors.New("registry must be a valid ethereum address") + } + if o.RegistrarAddress != nil && !common.IsHexAddress(*o.RegistrarAddress) { + return errors.New("registrar must be a valid ethereum address") + } + if o.LinkEthFeedAddress != nil && !common.IsHexAddress(*o.LinkEthFeedAddress) { + return errors.New("link_eth_feed must be a valid ethereum address") + } + if o.EthGasFeedAddress != nil && !common.IsHexAddress(*o.EthGasFeedAddress) { + return errors.New("eth_gas_feed must be a valid ethereum address") + } + if o.EthUSDFeedAddress != nil && !common.IsHexAddress(*o.EthUSDFeedAddress) { + return errors.New("eth_usd_feed must be a valid ethereum address") + } + if o.LinkUSDFeedAddress != nil && !common.IsHexAddress(*o.LinkUSDFeedAddress) { + return errors.New("link_usd_feed must be a valid ethereum address") + } + if o.MultiCallAddress != nil && !common.IsHexAddress(*o.MultiCallAddress) { + return errors.New("multicall must be a valid ethereum address") + } + if o.UpkeepContractAddresses != nil { + allEnabled := make(map[bool]int) + allConfigure := make(map[bool]int) + for _, address := range o.UpkeepContractAddresses { + if !common.IsHexAddress(address) { + return fmt.Errorf("upkeep_contracts must be valid ethereum addresses, but %s is not", address) + } + + if v, ok := o.Settings[address]; ok { + if v.ShouldBeUsed != nil { + allEnabled[*v.ShouldBeUsed]++ + } else { + allEnabled[true]++ + } + if v.Configure != nil { + allConfigure[*v.Configure]++ + } else { + allConfigure[true]++ + } + } + } + + if allEnabled[true] > 0 && allEnabled[false] > 0 { + return errors.New("either all or none offchain_aggregators must be used") + } + + if allConfigure[true] > 0 && allConfigure[false] > 0 { + return errors.New("either all or none offchain_aggregators must be configured") + } + } + + return nil +} + +func (c *Config) UseExistingContracts() bool { + if c.Contracts == nil { + return false + } + + if c.Contracts.ShouldBeUsed != nil { + return *c.Contracts.ShouldBeUsed + } + + return false +} + +func (c *Config) LinkTokenContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.LinkTokenAddress != nil { + return common.HexToAddress(*c.Contracts.LinkTokenAddress), nil + } + + return common.Address{}, errors.New("link token address must be set") +} + +func (c *Config) WethContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.WethAddress != nil { + return common.HexToAddress(*c.Contracts.WethAddress), nil + } + + return common.Address{}, errors.New("weth address must be set") +} + +func (c *Config) TranscoderContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.TranscoderAddress != nil { + return common.HexToAddress(*c.Contracts.TranscoderAddress), nil + } + + return common.Address{}, errors.New("transcoder address must be set") +} + +func (c *Config) ChainModuleContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.ChainModuleAddress != nil { + return common.HexToAddress(*c.Contracts.ChainModuleAddress), nil + } + + return common.Address{}, errors.New("chain module address must be set") +} + +func (c *Config) RegistryContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.RegistryAddress != nil { + return common.HexToAddress(*c.Contracts.RegistryAddress), nil + } + + return common.Address{}, errors.New("registry address must be set") +} + +func (c *Config) RegistrarContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.RegistrarAddress != nil { + return common.HexToAddress(*c.Contracts.RegistrarAddress), nil + } + + return common.Address{}, errors.New("registrar address must be set") +} + +func (c *Config) LinkEthFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.LinkEthFeedAddress != nil { + return common.HexToAddress(*c.Contracts.LinkEthFeedAddress), nil + } + + return common.Address{}, errors.New("link eth feed address must be set") +} + +func (c *Config) EthGasFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.EthGasFeedAddress != nil { + return common.HexToAddress(*c.Contracts.EthGasFeedAddress), nil + } + + return common.Address{}, errors.New("eth gas feed address must be set") +} + +func (c *Config) EthUSDFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.EthUSDFeedAddress != nil { + return common.HexToAddress(*c.Contracts.EthUSDFeedAddress), nil + } + + return common.Address{}, errors.New("eth usd feed address must be set") +} + +func (c *Config) LinkUSDFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.LinkUSDFeedAddress != nil { + return common.HexToAddress(*c.Contracts.LinkUSDFeedAddress), nil + } + + return common.Address{}, errors.New("link usd feed address must be set") +} + +func (c *Config) UpkeepContractAddresses() ([]common.Address, error) { + if c.Contracts != nil && c.Contracts.UpkeepContractAddresses != nil { + addresses := make([]common.Address, len(c.Contracts.UpkeepContractAddresses)) + for i, address := range c.Contracts.UpkeepContractAddresses { + addresses[i] = common.HexToAddress(address) + } + return addresses, nil + } + + return nil, errors.New("upkeep contract addresses must be set") +} + +func (c *Config) MultiCallContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.MultiCallAddress != nil { + return common.HexToAddress(*c.Contracts.MultiCallAddress), nil + } + + return common.Address{}, errors.New("multicall address must be set") +} + +func (c *Config) UseExistingLinkTokenContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.LinkTokenAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.LinkTokenAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingWethContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.WethAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.WethAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingTranscoderContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.TranscoderAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.TranscoderAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingRegistryContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.RegistryAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.RegistryAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingRegistrarContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.RegistrarAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.RegistrarAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingLinkEthFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.LinkEthFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.LinkEthFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingEthGasFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.EthGasFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.EthGasFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingEthUSDFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.EthUSDFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.EthUSDFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingLinkUSDFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.LinkUSDFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.LinkUSDFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingUpkeepContracts() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.UpkeepContractAddresses == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + for _, address := range c.Contracts.UpkeepContractAddresses { + if v, ok := c.Contracts.Settings[address]; ok { + if v.ShouldBeUsed != nil && *v.ShouldBeUsed { + return true + } + } + } + + return false +} + +func (c *Config) UseExistingMultiCallContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.MultiCallAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.MultiCallAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +type ContractSetting struct { + ShouldBeUsed *bool `toml:"use"` + Configure *bool `toml:"configure"` +} diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/automation_benchmark.go similarity index 94% rename from integration-tests/testsetups/keeper_benchmark.go rename to integration-tests/testsetups/automation_benchmark.go index 40a56ba73c8..ff8100ea437 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/automation_benchmark.go @@ -12,6 +12,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" geth "github.com/ethereum/go-ethereum" @@ -105,14 +107,14 @@ func NewKeeperBenchmarkTest(t *testing.T, inputs KeeperBenchmarkTestInputs) *Kee } // Setup prepares contracts for the test -func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.AutomationBenchmarkTestConfig) { +func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config testconfig.TestConfig) { startTime := time.Now() k.TestReporter.Summary.StartTime = startTime.UnixMilli() k.ensureInputValues() k.env = env k.namespace = k.env.Cfg.Namespace inputs := k.Inputs - k.testConfig = config + k.testConfig = &config k.automationTests = make([]automationv2.AutomationTest, len(inputs.RegistryVersions)) k.keeperRegistries = make([]contracts.KeeperRegistry, len(inputs.RegistryVersions)) @@ -146,7 +148,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto for index := range inputs.RegistryVersions { k.log.Info().Int("Index", index).Msg("Starting Test Setup") - a := automationv2.NewAutomationTestK8s(k.log, k.chainClient, k.chainlinkNodes) + a := automationv2.NewAutomationTestK8s(k.log, k.chainClient, k.chainlinkNodes, &config) a.RegistrySettings = *k.Inputs.KeeperRegistrySettings a.RegistrySettings.RegistryVersion = inputs.RegistryVersions[index] a.RegistrarSettings = contracts.KeeperRegistrarSettings{ @@ -159,7 +161,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto a.SetupAutomationDeploymentWithoutJobs(k.t) err = a.SetConfigOnRegistry() require.NoError(k.t, err, "Setting initial config on registry shouldn't fail") - k.DeployBenchmarkKeeperContracts(index, a) + k.SetupBenchmarkKeeperContracts(index, a) } var keysToFund = inputs.RegistryVersions @@ -178,7 +180,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto } k.log.Info().Str("Setup Time", time.Since(startTime).String()).Msg("Finished Keeper Benchmark Test Setup") - err = k.SendSlackNotification(nil, config) + err = k.SendSlackNotification(nil, &config) if err != nil { k.log.Warn().Msg("Sending test start slack notification failed") } @@ -301,7 +303,7 @@ func (k *KeeperBenchmarkTest) Run() { startedObservations.Add(1) k.log.Info().Int("Channel index", chIndex).Str("UpkeepID", upkeepIDCopy.String()).Msg("Starting upkeep observation") - confirmer := contracts.NewKeeperConsumerBenchmarkUpkeepObserver( + confirmer := contracts.NewAutomationConsumerBenchmarkUpkeepObserver( k.keeperConsumerContracts[registryIndex], k.keeperRegistries[registryIndex], upkeepIDCopy, @@ -650,8 +652,8 @@ func (k *KeeperBenchmarkTest) SendSlackNotification(slackClient *slack.Client, c return err } -// DeployBenchmarkKeeperContracts deploys a set amount of keeper Benchmark contracts registered to a single registry -func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *automationv2.AutomationTest) { +// SetupBenchmarkKeeperContracts deploys a set amount of keeper Benchmark contracts registered to a single registry +func (k *KeeperBenchmarkTest) SetupBenchmarkKeeperContracts(index int, a *automationv2.AutomationTest) { registryVersion := k.Inputs.RegistryVersions[index] k.Inputs.KeeperRegistrySettings.RegistryVersion = registryVersion upkeep := k.Inputs.Upkeeps @@ -659,7 +661,15 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *autom err error ) - consumer := k.DeployKeeperConsumersBenchmark() + var consumer contracts.AutomationConsumerBenchmark + if a.TestConfig.GetAutomationConfig().UseExistingUpkeepContracts() { + benchmarkAddresses, err := a.TestConfig.GetAutomationConfig().UpkeepContractAddresses() + require.NoError(k.t, err, "Getting upkeep contract addresses shouldn't fail") + consumer, err = contracts.LoadAutomationConsumerBenchmark(k.chainClient, benchmarkAddresses[0]) + require.NoError(k.t, err, "Loading KeeperConsumerBenchmark shouldn't fail") + } else { + consumer = k.DeployKeeperConsumersBenchmark() + } var upkeepAddresses []string @@ -710,7 +720,7 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *autom linkFunds = big.NewInt(0).Add(linkFunds, minLinkBalance) k.linkToken = a.LinkToken - err = actions.DeployMultiCallAndFundDeploymentAddresses(k.chainClient, k.linkToken, upkeep.NumberOfUpkeeps, linkFunds) + err = actions.SetupMultiCallAndFundDeploymentAddresses(k.chainClient, k.linkToken, upkeep.NumberOfUpkeeps, linkFunds, a.TestConfig) require.NoError(k.t, err, "Sending link funds to deployment addresses shouldn't fail") upkeepIds := actions.RegisterUpkeepContractsWithCheckData(k.t, k.chainClient, k.linkToken, linkFunds, uint32(upkeep.UpkeepGasLimit), a.Registry, a.Registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false, false, false, nil) @@ -729,17 +739,17 @@ func (k *KeeperBenchmarkTest) DeployKeeperConsumersBenchmark() contracts.Automat if *k.testConfig.GetAutomationConfig().Resiliency.ContractCallLimit != 0 && k.testConfig.GetAutomationConfig().Resiliency.ContractCallInterval.Duration != 0 { maxRetryAttempts := *k.testConfig.GetAutomationConfig().Resiliency.ContractCallLimit callRetryDelay := k.testConfig.GetAutomationConfig().Resiliency.ContractCallInterval.Duration - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) if err != nil { k.log.Error().Err(err).Msg("Deploying AutomationConsumerBenchmark instance shouldn't fail") - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) require.NoError(k.t, err, "Error deploying AutomationConsumerBenchmark") } } else { - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmark(k.chainClient) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmark(k.chainClient) if err != nil { k.log.Error().Err(err).Msg("Deploying AutomationConsumerBenchmark instance %d shouldn't fail") - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmark(k.chainClient) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmark(k.chainClient) require.NoError(k.t, err, "Error deploying AutomationConsumerBenchmark") } }