From e61d25606cca6598d104da2fa35781ca4aeaf4b4 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 25 Jun 2024 11:56:42 +0200 Subject: [PATCH] [TT-1209] use the same CL node config in k8s as in docker (#13411) * play around * remove hardcoded configs for k8s, use TOML test config instead * adjust Makefile * fix ocr forwarders panic * add function for getting correct ocr config for soak tests * lower chainlink node funding to something reasonable * warn when no events were collected * disable forwarder ocr soak tests until fixed --------- Co-authored-by: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> --- integration-tests/Makefile | 31 ++-- integration-tests/actions/actions.go | 39 +++- .../actions/vrf/common/actions.go | 8 +- integration-tests/benchmark/keeper_test.go | 36 +--- integration-tests/chaos/ocr2vrf_chaos_test.go | 27 ++- integration-tests/chaos/ocr_chaos_test.go | 12 +- integration-tests/config/config.go | 76 -------- .../automationv2_1/automationv2_1_test.go | 24 +-- integration-tests/load/functions/setup.go | 14 +- .../reorg/automation_reorg_test.go | 71 ++++---- integration-tests/smoke/ocr2vrf_test.go | 25 +-- integration-tests/soak/forwarder_ocr_test.go | 36 ++-- integration-tests/soak/ocr_test.go | 52 ++++-- .../testconfig/automation/automation.toml | 14 ++ .../forwarder_ocr/forwarder_ocr.toml | 53 ++++++ .../forwarder_ocr2/forwarder_ocr2.toml | 50 ++++++ .../testconfig/keeper/keeper.toml | 47 ++++- integration-tests/testconfig/ocr/example.toml | 3 +- integration-tests/testconfig/ocr/ocr.go | 4 - integration-tests/testconfig/ocr/ocr.toml | 12 +- .../testconfig/ocr2/example.toml | 13 +- integration-tests/testconfig/ocr2/ocr2.go | 6 +- integration-tests/testconfig/ocr2/ocr2.toml | 23 ++- .../testconfig/ocr2vrf/example.toml | 167 ++++++++++++++++++ .../testconfig/ocr2vrf/ocr2vrf.toml | 93 ++++++++++ integration-tests/testconfig/testconfig.go | 32 +++- integration-tests/testsetups/ocr.go | 135 +++++++------- integration-tests/types/config/node/core.go | 6 - 28 files changed, 742 insertions(+), 367 deletions(-) delete mode 100644 integration-tests/config/config.go create mode 100644 integration-tests/testconfig/ocr2vrf/example.toml create mode 100644 integration-tests/testconfig/ocr2vrf/ocr2vrf.toml diff --git a/integration-tests/Makefile b/integration-tests/Makefile index 9a85d52125c..1e6828fd35c 100644 --- a/integration-tests/Makefile +++ b/integration-tests/Makefile @@ -143,20 +143,35 @@ test_node_migrations_simulated_verbose: go test -timeout 1h -count=1 -v $(args) ./migration # Soak -.PHONY: test_soak_ocr -test_soak_ocr: +.PHONY: test_soak_ocr1 +test_soak_ocr1: . ./scripts/check_base64_env_var.sh - go test -v -count=1 -run ^TestOCRSoak$$ ./soak + go test -v -count=1 -run TestOCRv1Soak ./soak + +.PHONY: test_soak_ocr2 +test_soak_ocr2: + . ./scripts/check_base64_env_var.sh + go test -v -count=1 -run TestOCRv2Soak ./soak + +.PHONY: test_soak_forwarder_ocr1 +test_soak_forwarder_ocr1: + . ./scripts/check_base64_env_var.sh + go test -v -count=1 -run TestForwarderOCRv1Soak ./soak + +.PHONY: test_soak_forwarder_ocr2 +test_soak_forwarder_ocr2: + . ./scripts/check_base64_env_var.sh + go test -v -count=1 -run TestForwarderOCRv2Soak ./soak .PHONY: test_soak_ocr_reorg_1 test_soak_ocr_reorg_1: . ./scripts/check_base64_env_var.sh - go test -v -count=1 -run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$$ ./soak + go test -v -count=1 -run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$$ ./soak .PHONY: test_soak_ocr_reorg_2 test_soak_ocr_reorg_2: . ./scripts/check_base64_env_var.sh - go test -v -count=1 -run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$$ ./soak + go test -v -count=1 -run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$$ ./soak .PHONY: test_soak_ocr_gas_spike test_soak_ocr_gas_spike: @@ -178,10 +193,6 @@ test_soak_ocr_rpc_down_half_cl_nodes: . ./scripts/check_base64_env_var.sh go test -v -count=1 -run ^TestOCRSoak_RPCDownForHalfCLNodes$$ ./soak -.PHONY: test_soak_forwarder_ocr -test_soak_forwarder_ocr: - . ./scripts/check_base64_env_var.sh - go test -v -count=1 -run TestForwarderOCRSoak ./soak .PHONY: test_soak_automation test_soak_automation: @@ -226,4 +237,4 @@ run_test_with_local_image: build_docker_image # removes all occurrences of .run.id file in current folder and it's subdirectories # before making any changes lists all file locations and awaits user confirmation remove_test_execution_artefacts: - ./scripts/search_and_delete.sh .run.id \ No newline at end of file + ./scripts/search_and_delete.sh .run.id diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 6c3ae0f6069..bdca411c1d8 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -11,6 +11,8 @@ import ( "testing" "time" + "github.com/pelletier/go-toml/v2" + geth "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/rpc" @@ -22,12 +24,13 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/testreporters" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + ethContracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/rs/zerolog" "github.com/ethereum/go-ethereum/common" @@ -39,8 +42,11 @@ import ( "github.com/test-go/testify/require" "math" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_factory" ) @@ -1069,7 +1075,7 @@ func SendLinkFundsToDeploymentAddresses( // GenerateUpkeepReport generates a report of performed, successful, reverted and stale upkeeps for a given registry contract based on transaction logs. In case of test failure it can help us // to triage the issue by providing more context. -func GenerateUpkeepReport(t *testing.T, chainClient *seth.Client, startBlock, endBlock *big.Int, instance contracts.KeeperRegistry, registryVersion ethereum.KeeperRegistryVersion) (performedUpkeeps, successfulUpkeeps, revertedUpkeeps, staleUpkeeps int, err error) { +func GenerateUpkeepReport(t *testing.T, chainClient *seth.Client, startBlock, endBlock *big.Int, instance contracts.KeeperRegistry, registryVersion ethContracts.KeeperRegistryVersion) (performedUpkeeps, successfulUpkeeps, revertedUpkeeps, staleUpkeeps int, err error) { registryLogs := []gethtypes.Log{} l := logging.GetTestLogger(t) @@ -1150,7 +1156,7 @@ func GenerateUpkeepReport(t *testing.T, chainClient *seth.Client, startBlock, en return } -func GetStalenessReportCleanupFn(t *testing.T, logger zerolog.Logger, chainClient *seth.Client, startBlock uint64, registry contracts.KeeperRegistry, registryVersion ethereum.KeeperRegistryVersion) func() { +func GetStalenessReportCleanupFn(t *testing.T, logger zerolog.Logger, chainClient *seth.Client, startBlock uint64, registry contracts.KeeperRegistry, registryVersion ethContracts.KeeperRegistryVersion) func() { return func() { if t.Failed() { endBlock, err := chainClient.Client.BlockNumber(context.Background()) @@ -1166,3 +1172,30 @@ func GetStalenessReportCleanupFn(t *testing.T, logger zerolog.Logger, chainClien } } } + +func BuildTOMLNodeConfigForK8s(testConfig ctfconfig.GlobalTestConfig, testNetwork blockchain.EVMNetwork) (string, error) { + nodeConfigInToml := testConfig.GetNodeConfig() + + nodeConfig, _, err := node.BuildChainlinkNodeConfig( + []blockchain.EVMNetwork{testNetwork}, + nodeConfigInToml.BaseConfigTOML, + nodeConfigInToml.CommonChainConfigTOML, + nodeConfigInToml.ChainConfigTOMLByChainID, + ) + + if err != nil { + return "", err + } + + if testConfig.GetPyroscopeConfig() != nil && *testConfig.GetPyroscopeConfig().Enabled { + nodeConfig.Pyroscope.Environment = testConfig.GetPyroscopeConfig().Environment + nodeConfig.Pyroscope.ServerAddress = testConfig.GetPyroscopeConfig().ServerUrl + } + + asStr, err := toml.Marshal(nodeConfig) + if err != nil { + return "", err + } + + return string(asStr), nil +} diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index db8b44efe95..e599c705ef0 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -10,19 +10,17 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" - + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/go-resty/resty/v2" - - "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index a0dcad721f3..8c1d5bdac38 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -29,34 +29,6 @@ import ( ) var ( - keeperBenchmarkBaseTOML = `[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[P2P] -[P2P.V2] -Enabled = true -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"] -[Keeper] -TurnLookBack = 0 -[WebServer] -HTTPWriteTimeout = '1h'` - - simulatedEVMNonDevTOML = ` -Enabled = true -FinalityDepth = 50 -LogPollInterval = '1s' - -[EVM.HeadTracker] -HistoryDepth = 100 - -[EVM.GasEstimator] -Mode = 'FixedPrice' -LimitDefault = 5_000_000` - performanceChainlinkResources = map[string]interface{}{ "resources": map[string]interface{}{ "requests": map[string]interface{}{ @@ -322,8 +294,6 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc l := logging.GetTestLogger(t) testNetwork := networks.MustGetSelectedNetworkConfig(keeperTestConfig.GetNetworkConfig())[0] // Environment currently being used to run benchmark test on blockTime := "1" - networkDetailTOML := `MinIncomingConfirmations = 1` - numberOfNodes := *keeperTestConfig.GetKeeperConfig().Common.NumberOfNodes if strings.Contains(*keeperTestConfig.GetKeeperConfig().Common.RegistryToTest, "2_") { @@ -355,7 +325,6 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc // Test can run on simulated, simulated-non-dev, testnets if testNetwork.Name == networks.SimulatedEVMNonDev.Name { - networkDetailTOML = simulatedEVMNonDevTOML testEnvironment. AddHelm(reorg.New(&reorg.Props{ NetworkName: testNetwork.Name, @@ -447,8 +416,11 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc ctf_config.MightConfigOverridePyroscopeKey(keeperTestConfig.GetPyroscopeConfig(), target) } + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(keeperTestConfig, testNetwork) + require.NoError(t, err, "Error building TOML config") + cd := chainlink.NewWithOverride(i, map[string]any{ - "toml": networks.AddNetworkDetailedConfig(keeperBenchmarkBaseTOML, keeperTestConfig.GetPyroscopeConfig(), networkDetailTOML, testNetwork), + "toml": tomlConfig, "chainlink": chainlinkResources, "db": dbResources, }, keeperTestConfig.GetChainlinkImageConfig(), overrideFn) diff --git a/integration-tests/chaos/ocr2vrf_chaos_test.go b/integration-tests/chaos/ocr2vrf_chaos_test.go index 2800e763f1c..95b8373dc20 100644 --- a/integration-tests/chaos/ocr2vrf_chaos_test.go +++ b/integration-tests/chaos/ocr2vrf_chaos_test.go @@ -26,28 +26,25 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions/ocr2vrf_constants" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) func TestOCR2VRFChaos(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) - testconfig, err := tc.GetConfig("Chaos", tc.OCR2VRF) + testConfig, err := tc.GetConfig("Chaos", tc.OCR2VRF) if err != nil { t.Fatal(err) } - loadedNetwork := networks.MustGetSelectedNetworkConfig(testconfig.Network)[0] + loadedNetwork := networks.MustGetSelectedNetworkConfig(testConfig.Network)[0] + + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(&testConfig, loadedNetwork) + require.NoError(t, err, "Error building TOML config") defaultOCR2VRFSettings := map[string]interface{}{ "replicas": 6, - "toml": networks.AddNetworkDetailedConfig( - config.BaseOCR2Config, - testconfig.Pyroscope, - config.DefaultOCR2VRFNetworkDetailTomlConfig, - loadedNetwork, - ), + "toml": tomlConfig, } defaultOCR2VRFEthereumSettings := ðereum.Props{ @@ -57,11 +54,11 @@ func TestOCR2VRFChaos(t *testing.T) { } var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(testconfig.GetChainlinkImageConfig(), target) - ctf_config.MightConfigOverridePyroscopeKey(testconfig.GetPyroscopeConfig(), target) + ctf_config.MustConfigOverrideChainlinkVersion(testConfig.GetChainlinkImageConfig(), target) + ctf_config.MightConfigOverridePyroscopeKey(testConfig.GetPyroscopeConfig(), target) } - chainlinkCfg := chainlink.NewWithOverride(0, defaultOCR2VRFSettings, testconfig.ChainlinkImage, overrideFn) + chainlinkCfg := chainlink.NewWithOverride(0, defaultOCR2VRFSettings, testConfig.ChainlinkImage, overrideFn) testCases := map[string]struct { networkChart environment.ConnectedChart @@ -134,7 +131,7 @@ func TestOCR2VRFChaos(t *testing.T) { testCase := tc t.Run(fmt.Sprintf("OCR2VRF_%s", testCaseName), func(t *testing.T) { t.Parallel() - testNetwork := networks.MustGetSelectedNetworkConfig(testconfig.Network)[0] // Need a new copy of the network for each test + testNetwork := networks.MustGetSelectedNetworkConfig(testConfig.Network)[0] // Need a new copy of the network for each test testEnvironment := environment. New(&environment.Config{ NamespacePrefix: fmt.Sprintf( @@ -156,7 +153,7 @@ func TestOCR2VRFChaos(t *testing.T) { require.NoError(t, err) testNetwork = seth_utils.MustReplaceSimulatedNetworkUrlWithK8(l, testNetwork, *testEnvironment) - chainClient, err := seth_utils.GetChainClientWithConfigFunction(testconfig, testNetwork, seth_utils.OneEphemeralKeysLiveTestnetCheckFn) + chainClient, err := seth_utils.GetChainClientWithConfigFunction(testConfig, testNetwork, seth_utils.OneEphemeralKeysLiveTestnetCheckFn) require.NoError(t, err, "Error creating seth client") chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) @@ -165,7 +162,7 @@ func TestOCR2VRFChaos(t *testing.T) { require.NoError(t, err, "Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail") t.Cleanup(func() { - err := actions.TeardownSuite(t, chainClient, testEnvironment, chainlinkNodes, nil, zapcore.PanicLevel, &testconfig) + err := actions.TeardownSuite(t, chainClient, testEnvironment, chainlinkNodes, nil, zapcore.PanicLevel, &testConfig) require.NoError(t, err, "Error tearing down environment") }) diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 99cc9869849..3b7eeac888c 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -51,11 +51,6 @@ var ( chaosEndRound int64 = 4 ) -func getDefaultOcrSettings(config *tc.TestConfig) map[string]interface{} { - defaultOCRSettings["toml"] = networks.AddNetworksConfig(baseTOML, config.Pyroscope, networks.MustGetSelectedNetworkConfig(config.Network)[0]) - return defaultAutomationSettings -} - func TestOCRChaos(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) @@ -67,7 +62,12 @@ func TestOCRChaos(t *testing.T) { ctf_config.MightConfigOverridePyroscopeKey(config.GetPyroscopeConfig(), target) } - chainlinkCfg := chainlink.NewWithOverride(0, getDefaultOcrSettings(&config), config.ChainlinkImage, overrideFn) + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(&config, networks.MustGetSelectedNetworkConfig(config.Network)[0]) + require.NoError(t, err, "Error building TOML config") + + defaultOCRSettings["toml"] = tomlConfig + + chainlinkCfg := chainlink.NewWithOverride(0, defaultOCRSettings, config.ChainlinkImage, overrideFn) testCases := map[string]struct { networkChart environment.ConnectedChart diff --git a/integration-tests/config/config.go b/integration-tests/config/config.go deleted file mode 100644 index 6d00ceb32bc..00000000000 --- a/integration-tests/config/config.go +++ /dev/null @@ -1,76 +0,0 @@ -package config - -var ( - BaseOCR1Config = `[OCR] -Enabled = true - -[P2P] -[P2P.V2] -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"]` - - BaseOCR2Config = `[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[P2P] -[P2P.V2] -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"]` - - ForwarderNetworkDetailConfig = `[EVM.Transactions] -ForwardersEnabled = true` - - BaseVRFV2NetworkDetailTomlConfig = `BlockBackfillDepth = 500 -MinIncomingConfirmations = 3 -[EVM.GasEstimator] -LimitDefault = 3500000 -[EVM.Transactions] -MaxQueued = 10000 -` - - DefaultOCR2VRFNetworkDetailTomlConfig = `FinalityDepth = 5 -[EVM.GasEstimator] -LimitDefault = 3_500_000 -PriceMax = 100000000000 -FeeCapDefault = 100000000000` - - BaseMercuryTomlConfig = `[Feature] -LogPoller = true - -[Log] -Level = 'debug' -JSONConsole = true - -[WebServer] -AllowOrigins = '*' -HTTPPort = 6688 -SecureCookies = false - -[WebServer.TLS] -HTTPSPort = 0 - -[WebServer.RateLimit] -Authenticated = 2000 -Unauthenticated = 100 - -[JobPipeline] -MaxSuccessfulRuns = 0 - -[OCR2] -Enabled = true -CaptureEATelemetry = true - -[P2P] -[P2P.V2] -ListenAddresses = ['0.0.0.0:6690']` - - TelemetryIngressConfig = `[TelemetryIngress] -UniConn = false -Logging = true -ServerPubKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' -URL = 'oti:1337' -` -) diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index 1761e58f861..c1b6a6d4a87 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -59,17 +59,6 @@ const ( ) var ( - baseTOML = `[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[P2P] -[P2P.V2] -Enabled = true -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"]` secretsTOML = `[Mercury.Credentials.%s] LegacyURL = '%s' URL = '%s' @@ -292,21 +281,16 @@ Load Config: numberOfUpkeeps := *loadedTestConfig.Automation.General.NumberOfNodes for i := 0; i < numberOfUpkeeps+1; i++ { // +1 for the OCR boot node - var nodeTOML string - if i == 1 || i == 3 { - nodeTOML = fmt.Sprintf("%s\n\n[Log]\nLevel = \"%s\"", baseTOML, *loadedTestConfig.Automation.General.ChainlinkNodeLogLevel) - } else { - nodeTOML = fmt.Sprintf("%s\n\n[Log]\nLevel = \"info\"", baseTOML) - } - nodeTOML = networks.AddNetworksConfig(nodeTOML, loadedTestConfig.Pyroscope, testNetwork) - var overrideFn = func(_ interface{}, target interface{}) { ctfconfig.MustConfigOverrideChainlinkVersion(loadedTestConfig.GetChainlinkImageConfig(), target) ctfconfig.MightConfigOverridePyroscopeKey(loadedTestConfig.GetPyroscopeConfig(), target) } + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(&loadedTestConfig, testNetwork) + require.NoError(t, err, "Error building TOML config") + cd := chainlink.NewWithOverride(i, map[string]any{ - "toml": nodeTOML, + "toml": tomlConfig, "chainlink": nodeSpec, "db": dbSpec, "prometheus": *loadedTestConfig.Automation.General.UsePrometheus, diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go index bf1cc54f009..5519c90846b 100644 --- a/integration-tests/load/functions/setup.go +++ b/integration-tests/load/functions/setup.go @@ -54,30 +54,30 @@ type S4SecretsCfg struct { func SetupLocalLoadTestEnv(globalConfig ctf_config.GlobalTestConfig, functionsConfig types.FunctionsTestConfig) (*FunctionsTest, error) { selectedNetwork := networks.MustGetSelectedNetworkConfig(globalConfig.GetNetworkConfig())[0] - seth, err := seth_utils.GetChainClient(globalConfig, selectedNetwork) + sethClient, err := seth_utils.GetChainClient(globalConfig, selectedNetwork) if err != nil { return nil, err } cfg := functionsConfig.GetFunctionsConfig() - lt, err := contracts.DeployLinkTokenContract(log.Logger, seth) + lt, err := contracts.DeployLinkTokenContract(log.Logger, sethClient) if err != nil { return nil, err } - coord, err := contracts.LoadFunctionsCoordinator(seth, *cfg.Common.Coordinator) + coord, err := contracts.LoadFunctionsCoordinator(sethClient, *cfg.Common.Coordinator) if err != nil { return nil, err } - router, err := contracts.LoadFunctionsRouter(log.Logger, seth, *cfg.Common.Router) + router, err := contracts.LoadFunctionsRouter(log.Logger, sethClient, *cfg.Common.Router) if err != nil { return nil, err } var loadTestClient contracts.FunctionsLoadTestClient if cfg.Common.LoadTestClient != nil && *cfg.Common.LoadTestClient != "" { - loadTestClient, err = contracts.LoadFunctionsLoadTestClient(seth, *cfg.Common.LoadTestClient) + loadTestClient, err = contracts.LoadFunctionsLoadTestClient(sethClient, *cfg.Common.LoadTestClient) } else { - loadTestClient, err = contracts.DeployFunctionsLoadTestClient(seth, *cfg.Common.Router) + loadTestClient, err = contracts.DeployFunctionsLoadTestClient(sethClient, *cfg.Common.Router) } if err != nil { return nil, err @@ -144,7 +144,7 @@ func SetupLocalLoadTestEnv(globalConfig ctf_config.GlobalTestConfig, functionsCo Msg("Set new secret") } return &FunctionsTest{ - SethClient: *seth, + SethClient: *sethClient, LinkToken: lt, Coordinator: coord, Router: router, diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index e41244e55e1..958923327ae 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -4,6 +4,8 @@ package reorg import ( "fmt" "math/big" + "regexp" + "strconv" "testing" "time" @@ -30,37 +32,15 @@ import ( ) var ( - baseTOML = ` -[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[P2P] -[P2P.V2] -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"] - ` - finalityDepth = 20 - historyDepth = 30 - reorgBlockCount = 10 // Number of blocks to reorg (less than finalityDepth) - networkTOML = fmt.Sprintf(` -Enabled = true -FinalityDepth = %d - -[EVM.HeadTracker] -HistoryDepth = %d - -[EVM.GasEstimator] -Mode = 'FixedPrice' -LimitDefault = 5_000_000 - `, finalityDepth, historyDepth) - upkeepCount = 2 - nodeCount = 6 - nodeFundsAmount = new(big.Float).SetFloat64(2) // Each node will have 2 ETH - defaultUpkeepGasLimit = uint32(2500000) - defaultLinkFunds = int64(9e18) + reorgBlockCount = 10 // Number of blocks to reorg (should be less than finalityDepth) + upkeepCount = 2 + nodeCount = 6 + nodeFundsAmount = new(big.Float).SetFloat64(2) // Each node will have 2 ETH + defaultUpkeepGasLimit = uint32(2500000) + defaultLinkFunds = int64(9e18) + finalityDepth int + historyDepth int + defaultAutomationSettings = map[string]interface{}{ "toml": "", "db": map[string]interface{}{ @@ -104,6 +84,30 @@ LimitDefault = 5_000_000 * Upkeeps are expected to be performed during the reorg. */ func TestAutomationReorg(t *testing.T) { + c, err := tc.GetConfig("Reorg", tc.Automation) + require.NoError(t, err, "Error getting config") + + findIntValue := func(text string, substring string) (int, error) { + re := regexp.MustCompile(fmt.Sprintf(`%s\s*=\s*(\d+)`, substring)) + + match := re.FindStringSubmatch(text) + if len(match) > 1 { + asInt, err := strconv.Atoi(match[1]) + if err != nil { + return 0, err + } + return asInt, nil + } + + return 0, fmt.Errorf("no match found for %s", substring) + } + + finalityDepth, err = findIntValue(c.NodeConfig.CommonChainConfigTOML, "FinalityDepth") + require.NoError(t, err, "Error getting finality depth") + + historyDepth, err = findIntValue(c.NodeConfig.CommonChainConfigTOML, "HistoryDepth") + require.NoError(t, err, "Error getting history depth") + require.Less(t, reorgBlockCount, finalityDepth, "Reorg block count should be less than finality depth") t.Parallel() @@ -129,8 +133,11 @@ func TestAutomationReorg(t *testing.T) { network := networks.MustGetSelectedNetworkConfig(config.Network)[0] + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(&config, network) + require.NoError(t, err, "Error building TOML config") + defaultAutomationSettings["replicas"] = nodeCount - defaultAutomationSettings["toml"] = networks.AddNetworkDetailedConfig(baseTOML, config.Pyroscope, networkTOML, network) + defaultAutomationSettings["toml"] = tomlConfig var overrideFn = func(_ interface{}, target interface{}) { ctf_config.MustConfigOverrideChainlinkVersion(config.GetChainlinkImageConfig(), target) diff --git a/integration-tests/smoke/ocr2vrf_test.go b/integration-tests/smoke/ocr2vrf_test.go index b99e313a026..5b263dc1445 100644 --- a/integration-tests/smoke/ocr2vrf_test.go +++ b/integration-tests/smoke/ocr2vrf_test.go @@ -23,7 +23,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/ocr2vrf_actions/ocr2vrf_constants" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) @@ -35,10 +34,8 @@ func TestOCR2VRFRedeemModel(t *testing.T) { // remember to add TOML testConfig for Chainlink node before trying to run this test in future t.Skip("VRFv3 is on pause, skipping") l := logging.GetTestLogger(t) - testConfig, err := testconfig.GetConfig("Smoke", testconfig.OCR2) - if err != nil { - t.Fatal(err) - } + testConfig, err := testconfig.GetConfig("Smoke", testconfig.OCR2VRF) + require.NoError(t, err, "Error getting config") testEnvironment, testNetwork := setupOCR2VRFEnvironment(t) if testEnvironment.WillUseRemoteRunner() { @@ -98,10 +95,8 @@ func TestOCR2VRFFulfillmentModel(t *testing.T) { t.Parallel() t.Skip("VRFv3 is on pause, skipping") l := logging.GetTestLogger(t) - testConfig, err := testconfig.GetConfig("Smoke", testconfig.OCR2) - if err != nil { - t.Fatal(err) - } + testConfig, err := testconfig.GetConfig("Smoke", testconfig.OCR2VRF) + require.NoError(t, err, "Error getting config") testEnvironment, testNetwork := setupOCR2VRFEnvironment(t) if testEnvironment.WillUseRemoteRunner() { @@ -178,14 +173,12 @@ func setupOCR2VRFEnvironment(t *testing.T) (testEnvironment *environment.Environ ctf_config.MightConfigOverridePyroscopeKey(ocr2vrfSmokeConfig.GetPyroscopeConfig(), target) } + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(ocr2vrfSmokeConfig, testNetwork) + require.NoError(t, err, "Error building TOML config") + cd := chainlink.NewWithOverride(0, map[string]interface{}{ "replicas": 6, - "toml": networks.AddNetworkDetailedConfig( - config.BaseOCR2Config, - ocr2vrfSmokeConfig.Pyroscope, - config.DefaultOCR2VRFNetworkDetailTomlConfig, - testNetwork, - ), + "toml": tomlConfig, }, ocr2vrfSmokeConfig.ChainlinkImage, overrideFn) testEnvironment = environment.New(&environment.Config{ @@ -194,7 +187,7 @@ func setupOCR2VRFEnvironment(t *testing.T) (testEnvironment *environment.Environ }). AddHelm(evmConfig). AddHelm(cd) - err := testEnvironment.Run() + err = testEnvironment.Run() require.NoError(t, err, "Error running test environment") diff --git a/integration-tests/soak/forwarder_ocr_test.go b/integration-tests/soak/forwarder_ocr_test.go index 37837c666aa..fa9752a9a9c 100644 --- a/integration-tests/soak/forwarder_ocr_test.go +++ b/integration-tests/soak/forwarder_ocr_test.go @@ -12,22 +12,30 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) -func TestForwarderOCRSoak(t *testing.T) { - l := logging.GetTestLogger(t) - // Use this variable to pass in any custom EVM specific TOML values to your Chainlink nodes - customNetworkTOML := `[EVM.Transactions] -ForwardersEnabled = true` - // Uncomment below for debugging TOML issues on the node - // fmt.Println("Using Chainlink TOML\n---------------------") - // fmt.Println(networks.AddNetworkDetailedConfig(config.BaseOCRP2PV1Config, customNetworkTOML, network)) - // fmt.Println("---------------------") - - config, err := tc.GetConfig("Soak", tc.OCR) +func TestForwarderOCRv1Soak(t *testing.T) { + //nolint:revive + t.Fatalf("This test is disabled because the implementation is broken") + config, err := tc.GetConfig("Soak", tc.ForwarderOcr) + require.NoError(t, err, "Error getting config") + + executeForwarderOCRSoakTest(t, &config) +} + +func TestForwarderOCRv2Soak(t *testing.T) { + //nolint:revive + t.Fatalf("This test is disabled because the implementation is broken") + config, err := tc.GetConfig("Soak", tc.ForwarderOcr2) require.NoError(t, err, "Error getting config") - ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config, testsetups.WithForwarderFlow(true)) + executeForwarderOCRSoakTest(t, &config) +} + +func executeForwarderOCRSoakTest(t *testing.T, config *tc.TestConfig) { + l := logging.GetTestLogger(t) + + ocrSoakTest, err := testsetups.NewOCRSoakTest(t, config, testsetups.WithForwarderFlow(true)) require.NoError(t, err, "Error creating soak test") - ocrSoakTest.DeployEnvironment(customNetworkTOML, &config) + ocrSoakTest.DeployEnvironment(config) if ocrSoakTest.Environment().WillUseRemoteRunner() { return } @@ -36,6 +44,6 @@ ForwardersEnabled = true` l.Error().Err(err).Msg("Error tearing down environment") } }) - ocrSoakTest.Setup(&config) + ocrSoakTest.Setup(config) ocrSoakTest.Run() } diff --git a/integration-tests/soak/ocr_test.go b/integration-tests/soak/ocr_test.go index 290cc00255c..0e7b50d15b5 100644 --- a/integration-tests/soak/ocr_test.go +++ b/integration-tests/soak/ocr_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/logging" @@ -15,25 +17,28 @@ import ( "github.com/smartcontractkit/havoc/k8schaos" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" "github.com/smartcontractkit/chainlink/integration-tests/actions" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) -func TestOCRSoak(t *testing.T) { - // Use this variable to pass in any custom EVM specific TOML values to your Chainlink nodes - customNetworkTOML := `` - // Uncomment below for debugging TOML issues on the node - // network := networks.MustGetSelectedNetworksFromEnv()[0] - // fmt.Println("Using Chainlink TOML\n---------------------") - // fmt.Println(networks.AddNetworkDetailedConfig(config.BaseOCR1Config, customNetworkTOML, network)) - // fmt.Println("---------------------") +func TestOCRv1Soak(t *testing.T) { config, err := tc.GetConfig("Soak", tc.OCR) require.NoError(t, err, "Error getting config") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, customNetworkTOML) + executeOCRSoakTest(t, ocrSoakTest, &config) +} + +func TestOCRv2Soak(t *testing.T) { + config, err := tc.GetConfig("Soak", tc.OCR2) + require.NoError(t, err, "Error getting config") + + ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config) + require.NoError(t, err, "Error creating OCR soak test") + executeOCRSoakTest(t, ocrSoakTest, &config) } func TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled(t *testing.T) { @@ -41,7 +46,7 @@ func TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled(t *testing.T) { require.NoError(t, err, "Error getting config") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, "") + executeOCRSoakTest(t, ocrSoakTest, &config) } func TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled(t *testing.T) { @@ -49,7 +54,7 @@ func TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled(t *testing.T) { require.NoError(t, err, "Error getting config") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, "") + executeOCRSoakTest(t, ocrSoakTest, &config) } func TestOCRSoak_GasSpike(t *testing.T) { @@ -57,7 +62,7 @@ func TestOCRSoak_GasSpike(t *testing.T) { require.NoError(t, err, "Error getting config") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, "") + executeOCRSoakTest(t, ocrSoakTest, &config) } // TestOCRSoak_ChangeBlockGasLimit changes next block gas limit and sets it to percentage of last gasUsed in previous block creating congestion @@ -66,7 +71,7 @@ func TestOCRSoak_ChangeBlockGasLimit(t *testing.T) { require.NoError(t, err, "Error getting config") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, "") + executeOCRSoakTest(t, ocrSoakTest, &config) } // TestOCRSoak_RPCDownForAllCLNodes simulates a network chaos by bringing down network to RPC node for all Chainlink Nodes @@ -98,7 +103,7 @@ func TestOCRSoak_RPCDownForAllCLNodes(t *testing.T) { testsetups.WithChaos([]*k8schaos.Chaos{chaos}), ) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, "") + executeOCRSoakTest(t, ocrSoakTest, &config) } // TestOCRSoak_RPCDownForAllCLNodes simulates a network chaos by bringing down network to RPC node for 50% of Chainlink Nodes @@ -131,16 +136,27 @@ func TestOCRSoak_RPCDownForHalfCLNodes(t *testing.T) { testsetups.WithChaos([]*k8schaos.Chaos{chaos}), ) require.NoError(t, err, "Error creating OCR soak test") - runOCRSoakTest(t, ocrSoakTest, config, "") + executeOCRSoakTest(t, ocrSoakTest, &config) } -func runOCRSoakTest(t *testing.T, test *testsetups.OCRSoakTest, config tc.TestConfig, customNetworkTOML string) { +func executeOCRSoakTest(t *testing.T, test *testsetups.OCRSoakTest, config *tc.TestConfig) { l := logging.GetTestLogger(t) + // validate Seth config before anything else, but only for live networks (simulated will fail, since there's no chain started yet) + network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] + if !network.Simulated { + _, err := seth_utils.GetChainClient(config, network) + require.NoError(t, err, "Error creating seth client") + } + + if !test.Interrupted() { + test.DeployEnvironment(config) + } l.Info().Str("test", t.Name()).Msg("Starting OCR soak test") if !test.Interrupted() { - test.DeployEnvironment(customNetworkTOML, &config) + test.DeployEnvironment(config) } + if test.Environment().WillUseRemoteRunner() { return } @@ -154,7 +170,7 @@ func runOCRSoakTest(t *testing.T, test *testsetups.OCRSoakTest, config tc.TestCo require.NoError(t, err, "Error loading state") test.Resume() } else { - test.Setup(&config) + test.Setup(config) test.Run() } } diff --git a/integration-tests/testconfig/automation/automation.toml b/integration-tests/testconfig/automation/automation.toml index cf158301127..2ebe2b7b37c 100644 --- a/integration-tests/testconfig/automation/automation.toml +++ b/integration-tests/testconfig/automation/automation.toml @@ -95,6 +95,20 @@ max_revert_data_size=5_000 # reorg test specific overrides [Reorg.Automation] + +[Reorg.NodeConfig] +CommonChainConfigTOML = """ +FinalityDepth = 20 +LogPollInterval = '1s' + +[HeadTracker] +HistoryDepth = 30 + +[GasEstimator] +Mode = 'FixedPrice' +LimitDefault = 5_000_000 +""" + [Reorg.Automation.General] number_of_nodes=6 duration=100 diff --git a/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml b/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml index 79e6763e24f..344736cf90e 100644 --- a/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml +++ b/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml @@ -44,6 +44,20 @@ DeltaDial = '500ms' DeltaReconcile = '5s' """ +CommonChainConfigTOML = """ +AutoCreateKey = true +FinalityDepth = 1 +MinContractPayment = 0 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' + +[Transactions] +ForwardersEnabled = true +""" + [NodeConfig.ChainConfigTOMLByChainID] 1337 = """ AutoCreateKey = true @@ -54,4 +68,43 @@ MinContractPayment = 0 ForwardersEnabled = true """ +# load test specific configuration +[Load.OCR] +[Load.OCR.Common] +eth_funds = 3 + +[Load.OCR.Load] +test_duration = "3m" +rate_limit_unit_duration = "1m" +rate = 3 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# volume test specific configuration +[Volume.OCR] +[Volume.OCR.Common] +eth_funds = 3 + +[Volume.OCR.Volume] +test_duration = "3m" +rate_limit_unit_duration = "1m" +vu_requests_per_unit = 10 +rate = 1 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# soak test specific configuration +[Soak.Common] +chainlink_node_funding = 0.5 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration="15m" + +[Soak.OCR.Soak] +number_of_contracts=2 +time_between_rounds="1m" + diff --git a/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml b/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml index f95b56f17cf..c7f0084c726 100644 --- a/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml +++ b/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml @@ -40,6 +40,20 @@ DefaultTransactionQueueDepth = 0 ListenAddresses = ['0.0.0.0:6690'] """ +CommonChainConfigTOML = """ +AutoCreateKey = true +FinalityDepth = 1 +MinContractPayment = 0 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' + +[Transactions] +ForwardersEnabled = true +""" + [NodeConfig.ChainConfigTOMLByChainID] 1337 = """ AutoCreateKey = true @@ -50,4 +64,40 @@ MinContractPayment = 0 ForwardersEnabled = true """ +# load test specific configuration +[Load.OCR2.Common] +eth_funds = 3 + +[Load.OCR2.Load] +test_duration = "3m" +rate_limit_unit_duration = "1m" +rate = 3 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# volume test specific configuration +[Volume.OCR2.Common] +eth_funds = 3 + +[Volume.OCR2.Volume] +test_duration = "3m" +rate_limit_unit_duration = "1m" +vu_requests_per_unit = 10 +rate = 1 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# soak test specific configuration +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR2.Common] +test_duration="15m" + +[Soak.OCR2.Soak] +number_of_contracts=2 +time_between_rounds="1m" + diff --git a/integration-tests/testconfig/keeper/keeper.toml b/integration-tests/testconfig/keeper/keeper.toml index 9b2a1a65891..c69f5a5cf7d 100644 --- a/integration-tests/testconfig/keeper/keeper.toml +++ b/integration-tests/testconfig/keeper/keeper.toml @@ -62,4 +62,49 @@ contract_call_interval = "4s" [Seth] # keeper benchmark running on simulated network requires 100k per node -root_key_funds_buffer = 700_000 \ No newline at end of file +root_key_funds_buffer = 700_000 + +[Benchmark.NodeConfig] +BaseConfigTOML = """ +[Feature] +LogPoller = true + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +Enabled = true +AnnounceAddresses = ["0.0.0.0:6690"] +ListenAddresses = ["0.0.0.0:6690"] +[Keeper] +TurnLookBack = 0 +[WebServer] +HTTPWriteTimeout = '1h' +""" + +CommonChainConfigTOML = """ +AutoCreateKey = true +FinalityDepth = 1 +MinContractPayment = 0 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +""" + +[Benchmark.NodeConfig.ChainConfigTOMLByChainID] +# applicable for simulated chain +1337 = """ +FinalityDepth = 50 +LogPollInterval = '1s' +MinIncomingConfirmations = 1 + +[HeadTracker] +HistoryDepth = 100 + +[GasEstimator] +Mode = 'FixedPrice' +LimitDefault = 5_000_000 +""" \ No newline at end of file diff --git a/integration-tests/testconfig/ocr/example.toml b/integration-tests/testconfig/ocr/example.toml index f9c6453bc5e..92262241dff 100644 --- a/integration-tests/testconfig/ocr/example.toml +++ b/integration-tests/testconfig/ocr/example.toml @@ -164,6 +164,5 @@ chainlink_node_funding = 100 test_duration="15m" [Soak.OCR.Soak] -ocr_version="1" number_of_contracts=2 -time_between_rounds="1m" \ No newline at end of file +time_between_rounds="1m" diff --git a/integration-tests/testconfig/ocr/ocr.go b/integration-tests/testconfig/ocr/ocr.go index 0fd995a96f1..f23d6473643 100644 --- a/integration-tests/testconfig/ocr/ocr.go +++ b/integration-tests/testconfig/ocr/ocr.go @@ -117,15 +117,11 @@ func (o *Volume) Validate() error { } type SoakConfig struct { - OCRVersion *string `toml:"ocr_version"` NumberOfContracts *int `toml:"number_of_contracts"` TimeBetweenRounds *blockchain.StrDuration `toml:"time_between_rounds"` } func (o *SoakConfig) Validate() error { - if o.OCRVersion == nil || *o.OCRVersion == "" { - return errors.New("ocr_version must be set to either 1 or 2") - } if o.NumberOfContracts == nil || *o.NumberOfContracts <= 1 { return errors.New("number_of_contracts must be set and be greater than 1") } diff --git a/integration-tests/testconfig/ocr/ocr.toml b/integration-tests/testconfig/ocr/ocr.toml index 4e280e88f04..ac0249334da 100644 --- a/integration-tests/testconfig/ocr/ocr.toml +++ b/integration-tests/testconfig/ocr/ocr.toml @@ -72,14 +72,13 @@ ea_change_interval = "5s" # soak test specific configuration [Soak.Common] -chainlink_node_funding = 100 +chainlink_node_funding = 0.5 [Soak.OCR] [Soak.OCR.Common] test_duration="15m" [Soak.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" @@ -105,7 +104,6 @@ chainlink_node_funding = 0.5 [TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled.OCR.Common] test_duration="15m" [TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" @@ -133,17 +131,16 @@ chainlink_node_funding = 0.5 [TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled.OCR.Common] test_duration="15m" [TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" + # OCR soak test configuration with gas spike on Anvil network [TestOCRSoak_GasSpike.Common] chainlink_node_funding = 0.5 [TestOCRSoak_GasSpike.OCR.Common] test_duration="15m" [TestOCRSoak_GasSpike.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" [TestOCRSoak_GasSpike.Network] @@ -162,7 +159,6 @@ chainlink_node_funding = 0.5 [TestOCRSoak_ChangeBlockGasLimit.OCR.Common] test_duration="15m" [TestOCRSoak_ChangeBlockGasLimit.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" [TestOCRSoak_ChangeBlockGasLimit.Network] @@ -178,7 +174,6 @@ chainlink_node_funding = 0.5 [TestOCRSoak_RPCDownForAllCLNodes.OCR.Common] test_duration="15m" [TestOCRSoak_RPCDownForAllCLNodes.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" [TestOCRSoak_RPCDownForAllCLNodes.Network] @@ -189,8 +184,7 @@ chainlink_node_funding = 0.5 [TestOCRSoak_RPCDownForHalfCLNodes.OCR.Common] test_duration="15m" [TestOCRSoak_RPCDownForHalfCLNodes.OCR.Soak] -ocr_version="1" number_of_contracts=2 time_between_rounds="1m" [TestOCRSoak_RPCDownForHalfCLNodes.Network] -selected_networks=["simulated"] \ No newline at end of file +selected_networks=["simulated"] diff --git a/integration-tests/testconfig/ocr2/example.toml b/integration-tests/testconfig/ocr2/example.toml index bdbd06d0a96..36e3105f219 100644 --- a/integration-tests/testconfig/ocr2/example.toml +++ b/integration-tests/testconfig/ocr2/example.toml @@ -143,11 +143,11 @@ BumpMin = '100 gwei' """ # load test specific configuration -[Load.OCR] -[Load.OCR.Common] +[Load.OCR2] +[Load.OCR2.Common] eth_funds = 3 -[Load.OCR.Load] +[Load.OCR2.Load] test_duration = "3m" rate_limit_unit_duration = "1m" rate = 3 @@ -159,11 +159,10 @@ ea_change_interval = "5s" [Soak.Common] chainlink_node_funding = 100 -[Soak.OCR] +[Soak.OCR2] [Soak.OCR.Common] test_duration="15m" -[Soak.OCR.Soak] -ocr_version="1" +[Soak.OCR2.Soak] number_of_contracts=2 -time_between_rounds="1m" \ No newline at end of file +time_between_rounds="1m" diff --git a/integration-tests/testconfig/ocr2/ocr2.go b/integration-tests/testconfig/ocr2/ocr2.go index c039de0ff6f..73c9cd10056 100644 --- a/integration-tests/testconfig/ocr2/ocr2.go +++ b/integration-tests/testconfig/ocr2/ocr2.go @@ -1,4 +1,4 @@ -package ocr +package ocr2 import ( "errors" @@ -38,15 +38,11 @@ func (o *Common) Validate() error { } type SoakConfig struct { - OCRVersion *string `toml:"ocr_version"` NumberOfContracts *int `toml:"number_of_contracts"` TimeBetweenRounds *blockchain.StrDuration `toml:"time_between_rounds"` } func (o *SoakConfig) Validate() error { - if o.OCRVersion == nil || *o.OCRVersion == "" { - return errors.New("ocr_version must be set to either 1 or 2") - } if o.NumberOfContracts == nil || *o.NumberOfContracts <= 1 { return errors.New("number_of_contracts must be set and be greater than 1") } diff --git a/integration-tests/testconfig/ocr2/ocr2.toml b/integration-tests/testconfig/ocr2/ocr2.toml index 856dd73beb3..ad195913bd0 100644 --- a/integration-tests/testconfig/ocr2/ocr2.toml +++ b/integration-tests/testconfig/ocr2/ocr2.toml @@ -44,11 +44,11 @@ ListenAddresses = ['0.0.0.0:6690'] """ # load test specific configuration -[Load.OCR] -[Load.OCR.Common] +[Load.OCR2] +[Load.OCR2.Common] eth_funds = 3 -[Load.OCR.Load] +[Load.OCR2.Load] test_duration = "3m" rate_limit_unit_duration = "1m" rate = 3 @@ -57,11 +57,11 @@ verification_timeout = "3m" ea_change_interval = "5s" # volume test specific configuration -[Volume.OCR] -[Volume.OCR.Common] +[Volume.OCR2] +[Volume.OCR2.Common] eth_funds = 3 -[Volume.OCR.Volume] +[Volume.OCR2.Volume] test_duration = "3m" rate_limit_unit_duration = "1m" vu_requests_per_unit = 10 @@ -72,13 +72,12 @@ ea_change_interval = "5s" # soak test specific configuration [Soak.Common] -chainlink_node_funding = 100 +chainlink_node_funding = 0.5 -[Soak.OCR] -[Soak.OCR.Common] +[Soak.OCR2] +[Soak.OCR2.Common] test_duration="15m" -[Soak.OCR.Soak] -ocr_version="1" +[Soak.OCR2.Soak] number_of_contracts=2 -time_between_rounds="1m" \ No newline at end of file +time_between_rounds="1m" diff --git a/integration-tests/testconfig/ocr2vrf/example.toml b/integration-tests/testconfig/ocr2vrf/example.toml new file mode 100644 index 00000000000..6e7138aeda3 --- /dev/null +++ b/integration-tests/testconfig/ocr2vrf/example.toml @@ -0,0 +1,167 @@ +# Example of full config with all fields +# General part +[ChainlinkImage] +image="public.ecr.aws/chainlink/chainlink" +version="2.7.0" + +[Logging] +# if set to true will save logs even if test did not fail +test_log_collect=false + +[Logging.LogStream] +# supported targets: file, loki, in-memory. if empty no logs will be persistet +log_targets=["file"] +# context timeout for starting log producer and also time-frame for requesting logs +log_producer_timeout="10s" +# number of retries before log producer gives up and stops listening to logs +log_producer_retry_limit=10 + +[Logging.Loki] +tenant_id="tenant_id" +# full URL of Loki ingest endpoint +endpoint="https://loki.url/api/v3/push" +# currently only needed when using public instance +basic_auth_secret="loki-basic-auth" +# only needed for cloud grafana +bearer_token_secret="bearer_token" + +# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) +[Logging.Grafana] +# grafana url (trailing "/" will be stripped) +base_url="http://grafana.url" +# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard +dashboard_url="/d/your-dashboard" +bearer_token_secret="my-awesome-token" + +# if you want to use polygon_mumbial +[Network] +selected_networks=["polygon_mumbai"] + +[Network.RpcHttpUrls] +polygon_mumbai = ["https://my-rpc-endpoint.io"] + +[Network.RpcWsUrls] +polygon_mumbai = ["https://my-rpc-endpoint.io"] + +[Network.WalletKeys] +polygon_mumbai = ["change-me-to-your-PK"] + +[PrivateEthereumNetwork] +# pos or pow +consensus_type="pos" +# only prysm supported currently +consensus_layer="prysm" +# geth, besu, nethermind or erigon +execution_layer="geth" +# if true after env started it will wait for at least 1 epoch to be finalised before continuing +wait_for_finalization=false + +[PrivateEthereumNetwork.EthereumChainConfig] +# duration of single slot, lower => faster block production, must be >= 4 +seconds_per_slot=12 +# numer of slots in epoch, lower => faster epoch finalisation, must be >= 4 +slots_per_epoch=6 +# extra genesis gelay, no need to modify, but it should be after all validators/beacon chain starts +genesis_delay=15 +# number of validators in the network +validator_count=8 +chain_id=1337 +# list of addresses to be prefunded in genesis +addresses_to_fund=["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"] + +[PrivateEthereumNetwork.EthereumChainConfig.HardForkEpochs] +# hardforks to be applied (fork_name = epoch) +Deneb=500 + +# Chainlink node TOML config +[NodeConfig] +BaseConfigTOML = """ +[Feature] +FeedsManager = true +LogPoller = true +UICSAKeys = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '3m' +SessionTimeout = '999h0m0s' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 40 +MigrateOnStartup = true + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +ListenAddresses = ['0.0.0.0:6690'] +""" + +# override config toml related to EVMNode configs for chainlink nodes; applicable to all EVM node configs in chainlink toml +CommonChainConfigTOML = """ +AutoCreateKey = true +FinalityDepth = 1 +MinContractPayment = 0 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +""" + +# chainlink override config toml for EVMNode config specific to EVM chains with chain id as mentioned in the key +[NodeConfig.ChainConfigTOMLByChainID] +# applicable for arbitrum-goerli chain +421613 = """ +[GasEstimator] +PriceMax = '400 gwei' +LimitDefault = 100000000 +FeeCapDefault = '200 gwei' +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 gwei' +""" + +# load test specific configuration +[Load.OCR] +[Load.OCR.Common] +eth_funds = 3 + +[Load.OCR.Load] +test_duration = "3m" +rate_limit_unit_duration = "1m" +rate = 3 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# soak test specific configuration +[Soak.Common] +chainlink_node_funding = 100 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration="15m" + +[Soak.OCR.Soak] +ocr_version="1" +number_of_contracts=2 +time_between_rounds="1m" \ No newline at end of file diff --git a/integration-tests/testconfig/ocr2vrf/ocr2vrf.toml b/integration-tests/testconfig/ocr2vrf/ocr2vrf.toml new file mode 100644 index 00000000000..884a51736da --- /dev/null +++ b/integration-tests/testconfig/ocr2vrf/ocr2vrf.toml @@ -0,0 +1,93 @@ +# product defaults +[Common] +chainlink_node_funding = 0.5 + +[NodeConfig] +BaseConfigTOML = """ +[Feature] +FeedsManager = true +LogPoller = true +UICSAKeys = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '3m' +SessionTimeout = '999h0m0s' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 40 +MigrateOnStartup = true + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +ListenAddresses = ['0.0.0.0:6690'] +""" + +CommonChainConfigTOML = """ +FinalityDepth = 5 + +[GasEstimator] +LimitDefault = 3_500_000 +PriceMax = 100000000000 +FeeCapDefault = 100000000000 +""" + +# load test specific configuration +[Load.OCR] +[Load.OCR.Common] +eth_funds = 3 + +[Load.OCR.Load] +test_duration = "3m" +rate_limit_unit_duration = "1m" +rate = 3 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# volume test specific configuration +[Volume.OCR] +[Volume.OCR.Common] +eth_funds = 3 + +[Volume.OCR.Volume] +test_duration = "3m" +rate_limit_unit_duration = "1m" +vu_requests_per_unit = 10 +rate = 1 +verification_interval = "5s" +verification_timeout = "3m" +ea_change_interval = "5s" + +# soak test specific configuration +[Soak.Common] +chainlink_node_funding = 100 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration="15m" + +[Soak.OCR.Soak] +ocr_version="2" +number_of_contracts=2 +time_between_rounds="1m" diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 624c374491b..939645306b5 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -28,7 +28,6 @@ import ( keeper_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/keeper" lp_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/log_poller" ocr_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr" - ocr2_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr2" vrf_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrf" vrfv2_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2" vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" @@ -63,11 +62,11 @@ type AutomationTestConfig interface { } type OcrTestConfig interface { - GetOCRConfig() *ocr_config.Config + GetActiveOCRConfig() *ocr_config.Config } type Ocr2TestConfig interface { - GetOCR2Config() *ocr2_config.Config + GetOCR2Config() *ocr_config.Config } type TestConfig struct { @@ -79,7 +78,8 @@ type TestConfig struct { Keeper *keeper_config.Config `toml:"Keeper"` LogPoller *lp_config.Config `toml:"LogPoller"` OCR *ocr_config.Config `toml:"OCR"` - OCR2 *ocr2_config.Config `toml:"OCR2"` + OCR2 *ocr_config.Config `toml:"OCR2"` + OCR2VRF *ocr_config.Config `toml:"OCRR2VRF"` VRF *vrf_config.Config `toml:"VRF"` VRFv2 *vrfv2_config.Config `toml:"VRFv2"` VRFv2Plus *vrfv2plus_config.Config `toml:"VRFv2Plus"` @@ -204,6 +204,18 @@ func (c TestConfig) GetSethConfig() *seth.Config { return c.Seth } +func (c TestConfig) GetActiveOCRConfig() *ocr_config.Config { + if c.OCR != nil { + return c.OCR + } + + if c.OCR2 != nil { + return c.OCR2 + } + + return c.OCR2VRF +} + func (c *TestConfig) AsBase64() (string, error) { content, err := toml.Marshal(*c) if err != nil { @@ -526,6 +538,18 @@ func (c *TestConfig) Validate() error { } } + if c.OCR2 != nil { + if err := c.OCR2.Validate(); err != nil { + return errors.Wrapf(err, "OCR2 config validation failed") + } + } + + if c.OCR2VRF != nil { + if err := c.OCR2VRF.Validate(); err != nil { + return errors.Wrapf(err, "OCR2VRF config validation failed") + } + } + if c.VRF != nil { if err := c.VRF.Validate(); err != nil { return errors.Wrapf(err, "VRF config validation failed") diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index f143ad2568e..fe4d15fc96f 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -48,7 +48,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" @@ -66,6 +65,7 @@ type OCRSoakTest struct { TestReporter testreporters.OCRSoakTestReporter OperatorForwarderFlow bool seth *seth.Client + OCRVersion string t *testing.T startTime time.Time @@ -120,17 +120,25 @@ func NewOCRSoakTest(t *testing.T, config *tc.TestConfig, opts ...OCRSoakTestOpti test := &OCRSoakTest{ Config: config, TestReporter: testreporters.OCRSoakTestReporter{ - OCRVersion: *config.OCR.Soak.OCRVersion, - StartTime: time.Now(), + StartTime: time.Now(), }, t: t, startTime: time.Now(), - timeLeft: config.OCR.Common.TestDuration.Duration, + timeLeft: config.GetActiveOCRConfig().Common.TestDuration.Duration, log: logging.GetTestLogger(t), ocrRoundStates: make([]*testreporters.OCRRoundState, 0), ocrV1InstanceMap: make(map[string]contracts.OffchainAggregator), ocrV2InstanceMap: make(map[string]contracts.OffchainAggregatorV2), } + + ocrVersion := "1" + if config.OCR2 != nil { + ocrVersion = "2" + } + + test.TestReporter.OCRVersion = ocrVersion + test.OCRVersion = ocrVersion + for _, opt := range opts { opt(test) } @@ -141,12 +149,12 @@ func NewOCRSoakTest(t *testing.T, config *tc.TestConfig, opts ...OCRSoakTestOpti } // DeployEnvironment deploys the test environment, starting all Chainlink nodes and other components for the test -func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string, ocrTestConfig tt.OcrTestConfig) { +func (o *OCRSoakTest) DeployEnvironment(ocrTestConfig tt.OcrTestConfig) { nodeNetwork := networks.MustGetSelectedNetworkConfig(ocrTestConfig.GetNetworkConfig())[0] // Environment currently being used to soak test on // Define namespace if default not set if o.namespace == "" { - nsPre := fmt.Sprintf("soak-ocr-v%s-", *ocrTestConfig.GetOCRConfig().Soak.OCRVersion) + nsPre := fmt.Sprintf("soak-ocr-v%s-", o.OCRVersion) if o.OperatorForwarderFlow { nsPre = fmt.Sprintf("%sforwarder-", nsPre) } @@ -207,21 +215,17 @@ func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string, ocrTe })) } - var conf string - if *ocrTestConfig.GetOCRConfig().Soak.OCRVersion == "1" { - conf = config.BaseOCR1Config - } else if *ocrTestConfig.GetOCRConfig().Soak.OCRVersion == "2" { - conf = config.BaseOCR2Config - } - var overrideFn = func(_ interface{}, target interface{}) { ctf_config.MustConfigOverrideChainlinkVersion(ocrTestConfig.GetChainlinkImageConfig(), target) ctf_config.MightConfigOverridePyroscopeKey(ocrTestConfig.GetPyroscopeConfig(), target) } + tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(ocrTestConfig, nodeNetwork) + require.NoError(o.t, err, "Error building TOML config for Chainlink nodes") + cd := chainlink.NewWithOverride(0, map[string]any{ "replicas": 6, - "toml": networks.AddNetworkDetailedConfig(conf, ocrTestConfig.GetPyroscopeConfig(), customChainlinkNetworkTOML, nodeNetwork), + "toml": tomlConfig, "db": map[string]any{ "stateful": true, // stateful DB by default for soak tests }, @@ -229,7 +233,7 @@ func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string, ocrTe }, ocrTestConfig.GetChainlinkImageConfig(), overrideFn) testEnv.AddHelm(cd) - err := testEnv.Run() + err = testEnv.Run() require.NoError(o.t, err, "Error launching test environment") o.testEnvironment = testEnv o.namespace = testEnv.Cfg.Namespace @@ -256,8 +260,8 @@ func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string, ocrTe o.rpcNetwork.URLs = blockchain.SimulatedEVMNetwork.URLs } else { // Test is running locally, set forwarded URL of Geth blockchain node - wsURLs := o.testEnvironment.URLs[blockchain.SimulatedEVMNetwork.Name+"_internal"] - httpURLs := o.testEnvironment.URLs[blockchain.SimulatedEVMNetwork.Name+"_internal_http"] + wsURLs := o.testEnvironment.URLs[blockchain.SimulatedEVMNetwork.Name] + httpURLs := o.testEnvironment.URLs[blockchain.SimulatedEVMNetwork.Name+"_http"] require.NotEmpty(o.t, wsURLs, "Forwarded Geth URLs should not be empty") require.NotEmpty(o.t, httpURLs, "Forwarded Geth URLs should not be empty") o.rpcNetwork.URLs = wsURLs @@ -272,9 +276,9 @@ func (o *OCRSoakTest) Environment() *environment.Environment { } func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { - seth, err := seth_utils.GetChainClient(o.Config, o.rpcNetwork) + sethClient, err := seth_utils.GetChainClient(o.Config, o.rpcNetwork) require.NoError(o.t, err, "Error creating seth client") - o.seth = seth + o.seth = sethClient nodes, err := client.ConnectChainlinkNodes(o.testEnvironment) require.NoError(o.t, err, "Connecting to chainlink nodes shouldn't fail") @@ -282,12 +286,12 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { o.mockServer, err = ctf_client.ConnectMockServer(o.testEnvironment) require.NoError(o.t, err, "Creating mockserver clients shouldn't fail") - linkContract, err := contracts.DeployLinkTokenContract(o.log, seth) + linkContract, err := contracts.DeployLinkTokenContract(o.log, sethClient) require.NoError(o.t, err, "Error deploying LINK contract") // Fund Chainlink nodes, excluding the bootstrap node o.log.Info().Float64("ETH amount per node", *o.Config.Common.ChainlinkNodeFunding).Msg("Funding Chainlink nodes") - err = actions.FundChainlinkNodesFromRootAddress(o.log, seth, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(o.workerNodes), big.NewFloat(*o.Config.Common.ChainlinkNodeFunding)) + err = actions.FundChainlinkNodesFromRootAddress(o.log, sethClient, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(o.workerNodes), big.NewFloat(*o.Config.Common.ChainlinkNodeFunding)) require.NoError(o.t, err, "Error funding Chainlink nodes") var forwarders []common.Address @@ -305,15 +309,14 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { actions.AcceptAuthorizedReceiversOperator( o.t, o.log, o.seth, operators[i], forwarders[i], []common.Address{forwarderNodesAddresses[i]}) require.NoError(o.t, err, "Accepting Authorize Receivers on Operator shouldn't fail") - actions.TrackForwarder(o.t, o.seth, forwarders[i], o.workerNodes[i]) } - } else if *ocrTestConfig.GetOCRConfig().Soak.OCRVersion == "1" { + } else if o.OCRVersion == "1" { if o.OperatorForwarderFlow { o.ocrV1Instances, err = actions.DeployOCRContractsForwarderFlow( o.log, o.seth, - *o.Config.OCR.Soak.NumberOfContracts, + *o.Config.GetActiveOCRConfig().Soak.NumberOfContracts, common.HexToAddress(linkContract.Address()), contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(o.workerNodes), forwarders, @@ -322,14 +325,14 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { } else { o.ocrV1Instances, err = actions.DeployOCRv1Contracts( o.log, - seth, - *o.Config.OCR.Soak.NumberOfContracts, + sethClient, + *o.Config.GetActiveOCRConfig().Soak.NumberOfContracts, common.HexToAddress(linkContract.Address()), contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(o.workerNodes), ) require.NoError(o.t, err) } - } else if *ocrTestConfig.GetOCRConfig().Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { var transmitters []string if o.OperatorForwarderFlow { @@ -348,7 +351,7 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { o.ocrV2Instances, err = actions.DeployOCRv2Contracts( o.log, o.seth, - *ocrTestConfig.GetOCRConfig().Soak.NumberOfContracts, + *ocrTestConfig.GetActiveOCRConfig().Soak.NumberOfContracts, common.HexToAddress(linkContract.Address()), transmitters, ocrOffchainOptions, @@ -360,11 +363,11 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { require.NoError(o.t, err, "Error configuring OCRv2 aggregator contracts") } - if *ocrTestConfig.GetOCRConfig().Soak.OCRVersion == "1" { + if o.OCRVersion == "1" { for _, ocrInstance := range o.ocrV1Instances { o.ocrV1InstanceMap[ocrInstance.Address()] = ocrInstance } - } else if *ocrTestConfig.GetOCRConfig().Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { for _, ocrInstance := range o.ocrV2Instances { o.ocrV2InstanceMap[ocrInstance.Address()] = ocrInstance } @@ -387,25 +390,25 @@ func (o *OCRSoakTest) Run() { startingValue := 5 if o.OperatorForwarderFlow { actions.CreateOCRJobsWithForwarder(o.t, o.ocrV1Instances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer, o.seth.ChainID) - } else if *config.OCR.Soak.OCRVersion == "1" { + } else if o.OCRVersion == "1" { ctx, cancel := context.WithTimeout(testcontext.Get(o.t), time.Second*5) chainId, err := o.seth.Client.ChainID(ctx) cancel() require.NoError(o.t, err, "Error getting chain ID") err = actions.CreateOCRJobs(o.ocrV1Instances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer, chainId.String()) require.NoError(o.t, err, "Error creating OCR jobs") - } else if *config.OCR.Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { err := actions.CreateOCRv2Jobs(o.ocrV2Instances, o.bootstrapNode, o.workerNodes, o.mockServer, startingValue, o.seth.ChainID, o.OperatorForwarderFlow) require.NoError(o.t, err, "Error creating OCR jobs") } o.log.Info(). - Str("Test Duration", o.Config.OCR.Common.TestDuration.Duration.Truncate(time.Second).String()). - Int("Number of OCR Contracts", *config.OCR.Soak.NumberOfContracts). - Str("OCR Version", *config.OCR.Soak.OCRVersion). + Str("Test Duration", o.Config.GetActiveOCRConfig().Common.TestDuration.Duration.Truncate(time.Second).String()). + Int("Number of OCR Contracts", *config.GetActiveOCRConfig().Soak.NumberOfContracts). + Str("OCR Version", o.OCRVersion). Msg("Starting OCR Soak Test") - o.testLoop(o.Config.OCR.Common.TestDuration.Duration, startingValue) + o.testLoop(o.Config.GetActiveOCRConfig().Common.TestDuration.Duration, startingValue) o.complete() } @@ -459,9 +462,9 @@ func (o *OCRSoakTest) SaveState() error { StartingBlockNum: o.startingBlockNum, StartTime: o.startTime, TimeRunning: time.Since(o.startTime), - TestDuration: o.Config.OCR.Common.TestDuration.Duration, + TestDuration: o.Config.GetActiveOCRConfig().Common.TestDuration.Duration, OCRContractAddresses: ocrAddresses, - OCRVersion: *o.Config.OCR.Soak.OCRVersion, + OCRVersion: o.OCRVersion, MockServerURL: "http://mockserver:1080", // TODO: Make this dynamic BootStrapNodeURL: o.bootstrapNode.URL(), @@ -513,12 +516,12 @@ func (o *OCRSoakTest) LoadState() error { duration := blockchain.StrDuration{Duration: testState.TestDuration} o.ocrRoundStates = testState.OCRRoundStates o.testIssues = testState.TestIssues - o.Config.OCR.Common.TestDuration = &duration + o.Config.GetActiveOCRConfig().Common.TestDuration = &duration o.timeLeft = testState.TestDuration - testState.TimeRunning o.startTime = testState.StartTime o.startingBlockNum = testState.StartingBlockNum o.reorgHappened = testState.ReorgHappened - o.Config.OCR.Soak.OCRVersion = &testState.OCRVersion + o.OCRVersion = testState.OCRVersion o.bootstrapNode, err = client.ConnectChainlinkNodeURL(testState.BootStrapNodeURL) if err != nil { @@ -563,13 +566,13 @@ func (o *OCRSoakTest) Resume() { Message: "Test Resumed", }) o.log.Info(). - Str("Total Duration", o.Config.OCR.Common.TestDuration.String()). + Str("Total Duration", o.Config.GetActiveOCRConfig().Common.TestDuration.String()). Str("Time Left", o.timeLeft.String()). Msg("Resuming OCR Soak Test") - ocrAddresses := make([]common.Address, *o.Config.OCR.Soak.NumberOfContracts) + ocrAddresses := make([]common.Address, *o.Config.GetActiveOCRConfig().Soak.NumberOfContracts) - if *o.Config.OCR.Soak.OCRVersion == "1" { + if o.OCRVersion == "1" { for i, ocrInstance := range o.ocrV1Instances { ocrAddresses[i] = common.HexToAddress(ocrInstance.Address()) } @@ -580,7 +583,7 @@ func (o *OCRSoakTest) Resume() { Topics: [][]common.Hash{{contractABI.Events["AnswerUpdated"].ID}}, FromBlock: big.NewInt(0).SetUint64(o.startingBlockNum), } - } else if *o.Config.OCR.Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { for i, ocrInstance := range o.ocrV2Instances { ocrAddresses[i] = common.HexToAddress(ocrInstance.Address()) } @@ -716,7 +719,7 @@ func (o *OCRSoakTest) testLoop(testDuration time.Duration, newValue int) { return case <-newRoundTrigger.C: err := o.triggerNewRound(newValue) - timerReset := o.Config.OCR.Soak.TimeBetweenRounds.Duration + timerReset := o.Config.GetActiveOCRConfig().Soak.TimeBetweenRounds.Duration if err != nil { timerReset = time.Second * 5 o.log.Error().Err(err). @@ -843,7 +846,7 @@ func (o *OCRSoakTest) observeOCREvents() error { for { select { case event := <-eventLogs: - if *o.Config.OCR.Soak.OCRVersion == "1" { + if o.OCRVersion == "1" { answerUpdated, err := o.ocrV1Instances[0].ParseEventAnswerUpdated(event) if err != nil { o.log.Warn(). @@ -859,7 +862,7 @@ func (o *OCRSoakTest) observeOCREvents() error { Uint64("Round ID", answerUpdated.RoundId.Uint64()). Int64("Answer", answerUpdated.Current.Int64()). Msg("Answer Updated Event") - } else if *o.Config.OCR.Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { answerUpdated, err := o.ocrV2Instances[0].ParseEventAnswerUpdated(event) if err != nil { o.log.Warn(). @@ -906,9 +909,9 @@ func (o *OCRSoakTest) triggerNewRound(newValue int) error { } var err error - if *o.Config.OCR.Soak.OCRVersion == "1" { + if o.OCRVersion == "1" { err = actions.SetAllAdapterResponsesToTheSameValue(newValue, o.ocrV1Instances, o.workerNodes, o.mockServer) - } else if *o.Config.OCR.Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { err = actions.SetOCR2AllAdapterResponsesToTheSameValue(newValue, o.ocrV2Instances, o.workerNodes, o.mockServer) } if err != nil { @@ -920,11 +923,11 @@ func (o *OCRSoakTest) triggerNewRound(newValue int) error { Answer: int64(newValue), FoundEvents: make(map[string][]*testreporters.FoundEvent), } - if *o.Config.OCR.Soak.OCRVersion == "1" { + if o.OCRVersion == "1" { for _, ocrInstance := range o.ocrV1Instances { expectedState.FoundEvents[ocrInstance.Address()] = make([]*testreporters.FoundEvent, 0) } - } else if *o.Config.OCR.Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { for _, ocrInstance := range o.ocrV2Instances { expectedState.FoundEvents[ocrInstance.Address()] = make([]*testreporters.FoundEvent, 0) } @@ -965,7 +968,7 @@ func (o *OCRSoakTest) collectEvents() error { sortedFoundEvents := make([]*testreporters.FoundEvent, 0) for _, event := range contractEvents { - if *o.Config.OCR.Soak.OCRVersion == "1" { + if o.OCRVersion == "1" { answerUpdated, err := o.ocrV1Instances[0].ParseEventAnswerUpdated(event) if err != nil { return fmt.Errorf("error parsing EventAnswerUpdated for event: %v, %w", event, err) @@ -977,7 +980,7 @@ func (o *OCRSoakTest) collectEvents() error { RoundID: answerUpdated.RoundId.Uint64(), BlockNumber: event.BlockNumber, }) - } else if *o.Config.OCR.Soak.OCRVersion == "2" { + } else if o.OCRVersion == "2" { answerUpdated, err := o.ocrV2Instances[0].ParseEventAnswerUpdated(event) if err != nil { return fmt.Errorf("error parsing EventAnswerUpdated for event: %v, %w", event, err) @@ -1015,30 +1018,36 @@ func (o *OCRSoakTest) collectEvents() error { o.log.Info(). Str("Time", time.Since(start).String()). + Int("Events collected", len(contractEvents)). Msg("Collected on-chain events") + + if len(contractEvents) == 0 { + return fmt.Errorf("no events were collected") + } + return nil } // ensureValues ensures that all values needed to run the test are present func (o *OCRSoakTest) ensureInputValues() error { - ocrConfig := o.Config.OCR.Soak - if *ocrConfig.OCRVersion != "1" && *ocrConfig.OCRVersion != "2" { - return fmt.Errorf("OCR version must be 1 or 2, found %s", *ocrConfig.OCRVersion) + ocrConfig := o.Config.GetActiveOCRConfig().Soak + if o.OCRVersion != "1" && o.OCRVersion != "2" { + return fmt.Errorf("OCR version must be 1 or 2, found %s", o.OCRVersion) } if ocrConfig.NumberOfContracts != nil && *ocrConfig.NumberOfContracts <= 0 { - return fmt.Errorf("Number of OCR contracts must be set and greater than 0, found %d", ocrConfig.NumberOfContracts) + return fmt.Errorf("number of OCR contracts must be set and greater than 0, found %d", ocrConfig.NumberOfContracts) } if o.Config.Common.ChainlinkNodeFunding != nil && *o.Config.Common.ChainlinkNodeFunding <= 0 { - return fmt.Errorf("Chainlink node funding must be greater than 0, found %f", *o.Config.Common.ChainlinkNodeFunding) + return fmt.Errorf("chainlink node funding must be greater than 0, found %f", *o.Config.Common.ChainlinkNodeFunding) } - if o.Config.OCR.Common.TestDuration != nil && o.Config.OCR.Common.TestDuration.Duration <= time.Minute { - return fmt.Errorf("Test duration must be greater than 1 minute, found %s", o.Config.OCR.Common.TestDuration) + if o.Config.GetActiveOCRConfig().Common.TestDuration != nil && o.Config.GetActiveOCRConfig().Common.TestDuration.Duration <= time.Minute { + return fmt.Errorf("test duration must be greater than 1 minute, found %s", o.Config.GetActiveOCRConfig().Common.TestDuration) } if ocrConfig.TimeBetweenRounds != nil && ocrConfig.TimeBetweenRounds.Duration >= time.Hour { - return fmt.Errorf("Time between rounds must be less than 1 hour, found %s", ocrConfig.TimeBetweenRounds) + return fmt.Errorf("time between rounds must be less than 1 hour, found %s", ocrConfig.TimeBetweenRounds) } if ocrConfig.TimeBetweenRounds != nil && ocrConfig.TimeBetweenRounds.Duration < time.Second*30 { - return fmt.Errorf("Time between rounds must be greater or equal to 30 seconds, found %s", ocrConfig.TimeBetweenRounds) + return fmt.Errorf("time between rounds must be greater or equal to 30 seconds, found %s", ocrConfig.TimeBetweenRounds) } return nil @@ -1064,7 +1073,7 @@ func (o *OCRSoakTest) getContractAddressesString() []string { // getContractAddresses returns the addresses of all OCR contracts deployed func (o *OCRSoakTest) getContractAddresses() []common.Address { - contractAddresses := []common.Address{} + var contractAddresses []common.Address if len(o.ocrV1Instances) != 0 { for _, ocrInstance := range o.ocrV1Instances { contractAddresses = append(contractAddresses, common.HexToAddress(ocrInstance.Address())) diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go index 290d3e57dfb..181d57a17ed 100644 --- a/integration-tests/types/config/node/core.go +++ b/integration-tests/types/config/node/core.go @@ -133,12 +133,6 @@ func WithKeySpecificMaxGasPrice(addresses []string, maxGasPriceGWei int64) NodeC } } -func WithLogPollInterval(interval time.Duration) NodeConfigOpt { - return func(c *chainlink.Config) { - c.EVM[0].Chain.LogPollInterval = commonconfig.MustNewDuration(interval) - } -} - func BuildChainlinkNodeConfig(nets []blockchain.EVMNetwork, nodeConfig, commonChain string, configByChain map[string]string) (*corechainlink.Config, string, error) { var tomlCfg *corechainlink.Config var err error