From 374482e40c533c4b8279bcb750db08ea66fc814a Mon Sep 17 00:00:00 2001 From: Balamurali Gopalswami <167726375+b-gopalswami@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:45:12 -0400 Subject: [PATCH] CCIP-3461: Optimize mainnet soak test (#1458) ### Motivation Optimize the resource and fund consumption of the mainnet soak test. Currently, the mainnet soak test runs every six hours in Kubernetes, executing one CCIP transaction per hour for a duration of five hours across 28 bidirectional lanes. This setup is designed to provide consistent observability data on the CCIP mainnet, allowing us to differentiate between service outages and quiet periods. However, these tests are inefficient, consuming Kubernetes resources and significant mainnet funds. https://smartcontract-it.atlassian.net/browse/CCIP-3461 ### Ideas: Discussion [thread](https://chainlink-core.slack.com/archives/C02PBKHCP28/p1726678958525029) is initiated with o11y team and decided that it's not required to create txs for every hour instead create one tx if there are no activity for last 24h. Convert to smoke test as we are planning to fire only one request instead of Soak test. Converting to smoke will elevate the K8 resource consumption as the test will run using github runner. ### Solution - [x] 1. Modify the pipeline to run it as smoke test - [x] 2. Add traffic check to smoke test - [x] 3. Add new set of additional 21 lanes and resulted in total of 49 lanes. (i.e 98 unique lanes) - [x] 5. Add RPCs, Wallet key for new lanes to test secrets - [ ] 6. Load funds for new lanes - [x] 7. Schedule pipeline to run for every 6hrs ### Key outcomes: Present transaction count: 1tx * (28 * 2)lanes * 24hrs = 1344 After this change: 1tx * (49 * 2)lanes = 98 which is close to 92% reduction with additional 42 lanes coverage. As per the last [analysis](https://docs.google.com/document/d/1MqXoIyGtGE9o2usgpWdIHQUMblKTyeAvoa06MEsExpc/edit?pli=1#heading=h.8kwk6enqa4w) on the cost, we spend around 84k per quarter. I expect the fund reduction close to 90% which will give saving close to 300k annually. --------- Co-authored-by: Brandon West <3317895+Bwest981@users.noreply.github.com> --- .github/workflows/ccip-live-network-tests.yml | 130 +++++++++--- .../ccip-tests/actions/ccip_helpers.go | 25 ++- .../ccip-tests/load/ccip_loadgen.go | 8 +- .../ccip-tests/load/ccip_multicall_loadgen.go | 2 +- integration-tests/ccip-tests/load/helper.go | 2 +- .../ccip-tests/smoke/ccip_test.go | 133 ++++++++++++- .../ccip-tests/testconfig/README.md | 12 +- .../ccip-tests/testconfig/ccip.go | 92 ++++----- .../testconfig/override/mainnet.toml | 187 +++++++++++------- 9 files changed, 425 insertions(+), 166 deletions(-) diff --git a/.github/workflows/ccip-live-network-tests.yml b/.github/workflows/ccip-live-network-tests.yml index 7d908d9718..089fcf739b 100644 --- a/.github/workflows/ccip-live-network-tests.yml +++ b/.github/workflows/ccip-live-network-tests.yml @@ -15,8 +15,8 @@ on: required: false type: choice options: - - 'load' - 'smoke' + - 'load' test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false @@ -30,8 +30,6 @@ concurrency: env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink CHAINLINK_VERSION: ${{ github.sha }} - CHAINLINK_TEST_VERSION: ${{ github.sha }} - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws E2E_TEST_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink @@ -41,19 +39,21 @@ env: E2E_TEST_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} # Default private key test secret loaded from Github Secret as only security team has access to it. # this key secrets.QA_SHARED_803C_KEY has a story behind it. To know more, see CCIP-2875 and SECHD-16575 tickets. - E2E_TEST_ETHEREUM_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} E2E_TEST_ARBITRUM_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_BASE_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_WEMIX_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} E2E_TEST_AVALANCHE_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_ZKSYNC_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_MODE_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_BASE_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_BLAST_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_CELO_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_ETHEREUM_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_GNOSIS_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_KROMA_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} E2E_TEST_METIS_ANDROMEDA_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_MODE_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} E2E_TEST_OPTIMISM_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_KROMA_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_GNOSIS_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} E2E_TEST_POLYGON_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} - E2E_TEST_BSC_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_WEMIX_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + E2E_TEST_ZKSYNC_MAINNET_WALLET_KEY: ${{ secrets.QA_SHARED_803C_KEY }} + jobs: build-chainlink: @@ -99,6 +99,7 @@ jobs: build-test-image: environment: integration + if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_type == 'load' }} permissions: id-token: write contents: read @@ -133,8 +134,8 @@ jobs: matrix: config: [mainnet.toml] needs: [ build-chainlink, build-test-image ] - # if the event is a scheduled event or the test type is load and no previous job failed - if: ${{ (github.event_name == 'schedule' || inputs.test_type == 'load') && !contains(needs.*.result, 'failure') }} + # if the event is a workflow_dispatch event and the test type is load and no previous job failed + if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_type == 'load' && !contains(needs.*.result, 'failure') }} permissions: issues: read checks: write @@ -147,6 +148,8 @@ jobs: SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} TEST_LOG_LEVEL: info REF_NAME: ${{ github.head_ref || github.ref_name }} + CHAINLINK_TEST_VERSION: ${{ github.sha }} + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests steps: @@ -207,11 +210,11 @@ jobs: RR_CPU: 4 DETACH_RUNNER: true TEST_TRIGGERED_BY: ccip-load-test-ci - BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" with: - test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ^TestLoadCCIPStableRPS$ ./load 2>&1 | tee /tmp/gotest.log | gotestfmt + test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ^TestLoadCCIPStableRPS$ ./load 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_download_vendor_packages_command: cd ./integration-tests && go mod download # Other default test secrets loaded from dotenv Github Secret. test_secrets_defaults_base64: ${{ secrets.CCIP_DEFAULT_TEST_SECRETS }} @@ -229,12 +232,12 @@ jobs: should_cleanup: false ccip-smoke-test: - name: CCIP smoke Test + name: CCIP smoke Test ${{ matrix.lanes.name }} environment: integration runs-on: ubuntu-latest - needs: [ build-chainlink, build-test-image ] - # if the event is a scheduled event or the test type is load and no previous job failed - if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_type == 'smoke' && !contains(needs.*.result, 'failure') }} + needs: [ build-chainlink ] + # if the event is a scheduled event or the test type is smoke and no previous job failed + if: ${{ (github.event_name == 'schedule' || inputs.test_type == 'smoke') && !contains(needs.*.result, 'failure') }} permissions: issues: read checks: write @@ -247,10 +250,69 @@ jobs: SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} TEST_LOG_LEVEL: info REF_NAME: ${{ github.head_ref || github.ref_name }} - ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests - + strategy: + fail-fast: false + matrix: + lanes: + - name: 'ARBITRUM_MAINNET' + pairs: 'ARBITRUM_MAINNET,BSC_MAINNET;ARBITRUM_MAINNET,OPTIMISM_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'AVALANCHE_MAINNET' + pairs: 'AVALANCHE_MAINNET,ARBITRUM_MAINNET;AVALANCHE_MAINNET,BASE_MAINNET;AVALANCHE_MAINNET,BSC_MAINNET;AVALANCHE_MAINNET,OPTIMISM_MAINNET;AVALANCHE_MAINNET,POLYGON_MAINNET;AVALANCHE_MAINNET,WEMIX_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'BASE_MAINNET' + pairs: 'BASE_MAINNET,ARBITRUM_MAINNET;BASE_MAINNET,BSC_MAINNET;BASE_MAINNET,OPTIMISM_MAINNET;BASE_MAINNET,POLYGON_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'BLAST_MAINNET' + pairs: 'BLAST_MAINNET,ARBITRUM_MAINNET;BLAST_MAINNET,BASE_MAINNET;BLAST_MAINNET,BSC_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'BSC_MAINNET' + pairs: 'BSC_MAINNET,OPTIMISM_MAINNET;BSC_MAINNET,POLYGON_MAINNET;BSC_MAINNET,WEMIX_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'ETHEREUM_MAINNET 1' + pairs: 'ETHEREUM_MAINNET,ARBITRUM_MAINNET;ETHEREUM_MAINNET,AVALANCHE_MAINNET;ETHEREUM_MAINNET,BASE_MAINNET;ETHEREUM_MAINNET,BLAST_MAINNET;ETHEREUM_MAINNET,BSC_MAINNET;ETHEREUM_MAINNET,CELO_MAINNET;ETHEREUM_MAINNET,GNOSIS_MAINNET;ETHEREUM_MAINNET,OPTIMISM_MAINNET;ETHEREUM_MAINNET,POLYGON_MAINNET;ETHEREUM_MAINNET,WEMIX_MAINNET' + enabled: true + phaseTimeout: 40m + - name: 'ETHEREUM_MAINNET 2' + pairs: 'ETHEREUM_MAINNET,METIS_ANDROMEDA;ETHEREUM_MAINNET,ZKSYNC_MAINNET' + enabled: true + phaseTimeout: 90m + - name: 'GNOSIS_MAINNET' + pairs: 'GNOSIS_MAINNET,ARBITRUM_MAINNET;GNOSIS_MAINNET,AVALANCHE_MAINNET;GNOSIS_MAINNET,BASE_MAINNET;GNOSIS_MAINNET,BSC_MAINNET;GNOSIS_MAINNET,OPTIMISM_MAINNET;GNOSIS_MAINNET,POLYGON_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'METIS_ANDROMEDA' + pairs: 'METIS_ANDROMEDA,ARBITRUM_MAINNET' + enabled: true + phaseTimeout: 60m + - name: 'MODE_MAINNET' + pairs: 'MODE_MAINNET,OPTIMISM_MAINNET;MODE_MAINNET,ARBITRUM_MAINNET;MODE_MAINNET,BASE_MAINNET;MODE_MAINNET,BSC_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'OPTIMISM_MAINNET' + pairs: 'OPTIMISM_MAINNET,POLYGON_MAINNET;OPTIMISM_MAINNET,WEMIX_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'POLYGON_MAINNET' + pairs: 'POLYGON_MAINNET,ARBITRUM_MAINNET;POLYGON_MAINNET,WEMIX_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'WEMIX_MAINNET' + pairs: 'WEMIX_MAINNET,ARBITRUM_MAINNET;WEMIX_MAINNET,KROMA_MAINNET' + enabled: true + phaseTimeout: 20m + - name: 'ZKSYNC_MAINNET' + pairs: 'ZKSYNC_MAINNET,ARBITRUM_MAINNET' + enabled: true + phaseTimeout: 90m steps: - name: Collect Metrics + if: ${{ matrix.lanes.enabled == true }} id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: @@ -261,10 +323,12 @@ jobs: this-job-name: CCIP Smoke Test continue-on-error: true - name: Checkout the repo + if: ${{ matrix.lanes.enabled == true }} uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: ref: ${{ env.REF_NAME }} - name: Prepare Base64 TOML override + if: ${{ matrix.lanes.enabled == true }} id: set_override_config shell: bash run: | @@ -276,14 +340,20 @@ jobs: echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE echo "base_64_override=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT fi + if [[ "${{ github.event_name }}" == "schedule" ]]; then + BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ./integration-tests/ccip-tests/testconfig/override/mainnet.toml) + echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE + echo "base_64_override=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT + echo "SLACK_USER=${{ secrets.QA_SLACK_USER }}" >> $GITHUB_ENV + fi - name: step summary + if: ${{ matrix.lanes.enabled == true }} shell: bash run: | echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - name: Prepare Base64 TOML override for CCIP secrets + if: ${{ matrix.lanes.enabled == true }} uses: ./.github/actions/setup-create-base64-config-ccip id: setup_create_base64_config_ccip with: @@ -293,19 +363,22 @@ jobs: logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 + if: ${{ matrix.lanes.enabled == true }} env: TEST_SUITE: smoke TEST_ARGS: -test.timeout 900h - DETACH_RUNNER: true + DETACH_RUNNER: false DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable RR_MEM: 8Gi RR_CPU: 4 TEST_TRIGGERED_BY: ccip-smoke-test-ci - BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + OVERRIDE_NETWORK_PAIRS: ${{ matrix.lanes.pairs }} + OVERRIDE_PHASE_TIMEOUT: ${{ matrix.lanes.phaseTimeout }} with: - test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -p 30 -json -run ^TestSmokeCCIPForBidirectionalLane$ ./smoke 2>&1 | tee /tmp/gotest.log | gotestfmt + test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 3h -count=1 -p 30 -json -run ^TestSmokeCCIPForGivenNetworkPairs$ ./smoke 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_download_vendor_packages_command: cd ./integration-tests && go mod download # Other default test secrets loaded from dotenv Github Secret. test_secrets_defaults_base64: ${{ secrets.CCIP_DEFAULT_TEST_SECRETS }} @@ -314,7 +387,6 @@ jobs: go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} triggered_by: ${{ env.TEST_TRIGGERED_BY }} artifacts_location: ./integration-tests/smoke/logs/payload_ccip.json aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 2bbc77f1c2..eb34db40de 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -1648,7 +1648,10 @@ func (sourceCCIP *SourceCCIPModule) IsRequestTriggeredWithinTimeframe(timeframe // IsPastRequestTriggeredWithinTimeframe determines the average block time and calculates the block numbers // within the specified timeframe. It then uses FilterCCIPSendRequested to identify the past events. -func (sourceCCIP *SourceCCIPModule) IsPastRequestTriggeredWithinTimeframe(ctx context.Context, timeframe *commonconfig.Duration) (*time.Time, error) { +func (sourceCCIP *SourceCCIPModule) IsPastRequestTriggeredWithinTimeframe( + ctx context.Context, + timeframe *commonconfig.Duration, +) (*types.Log, error) { if timeframe == nil { return nil, nil } @@ -1675,17 +1678,21 @@ func (sourceCCIP *SourceCCIPModule) IsPastRequestTriggeredWithinTimeframe(ctx co return nil, fmt.Errorf("error while filtering CCIP send requested starting block number: %d. Error: %w", filterFromBlock, err) } defer func() { - _ = iterator.Close() + iterErr := iterator.Close() + if iterErr != nil { + sourceCCIP.Common.Logger.Error().Err(iterErr).Msg("Error closing iterator") + } }() - if iterator.Next() { - hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(iterator.Event.Raw.BlockNumber))) - if err != nil { - return nil, fmt.Errorf("error getting header for block: %d, Error: %w", iterator.Event.Raw.BlockNumber, err) + lastBlockNumber := uint64(0) + var latestEvent *types.Log + for iterator.Next() { + blockNum := iterator.Event.Raw.BlockNumber + if blockNum > lastBlockNumber { + lastBlockNumber = blockNum + latestEvent = &iterator.Event.Raw } - return pointer.ToTime(hdr.Timestamp), nil } - - return nil, nil + return latestEvent, nil } func (sourceCCIP *SourceCCIPModule) AssertEventCCIPSendRequested( diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go index d3af128309..89804dbf8a 100644 --- a/integration-tests/ccip-tests/load/ccip_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -226,13 +226,19 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.Response { res := &wasp.Response{} sourceCCIP := c.Lane.Source var recentRequestFoundAt *time.Time + var latestEvent *types.Log var err error // Use IsPastRequestTriggeredWithinTimeframe to check for any historical CCIP send request events // within the specified timeframe for the first message. Subsequently, use the watcher method to monitor // and detect any new events as they occur. if c.CurrentMsgSerialNo.Load() == int64(1) { - recentRequestFoundAt, err = sourceCCIP.IsPastRequestTriggeredWithinTimeframe(testcontext.Get(c.t), c.SkipRequestIfAnotherRequestTriggeredWithin) + latestEvent, err = sourceCCIP.IsPastRequestTriggeredWithinTimeframe(testcontext.Get(c.t), c.SkipRequestIfAnotherRequestTriggeredWithin) require.NoError(c.t, err, "error while filtering past requests") + if latestEvent != nil { + hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(latestEvent.BlockNumber))) + require.NoError(c.t, err, "error while getting header by block number") + recentRequestFoundAt = pointer.ToTime(hdr.Timestamp) + } } else { recentRequestFoundAt = sourceCCIP.IsRequestTriggeredWithinTimeframe(c.SkipRequestIfAnotherRequestTriggeredWithin) } diff --git a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go index 04fcffaa4b..39e5388244 100644 --- a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go @@ -91,7 +91,7 @@ func NewMultiCallLoadGenerator(testCfg *testsetups.CCIPTestConfig, lanes []*acti testCfg.Test, lane, testCfg.TestGroupInput.PhaseTimeout.Duration(), 100000, testCfg.TestGroupInput.LoadProfile.MsgProfile, 0, - testCfg.TestGroupInput.LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin, + testCfg.TestGroupInput.SkipRequestIfAnotherRequestTriggeredWithin, ) ccipLoad.BeforeAllCall() m.E2ELoads[fmt.Sprintf("%s-%s", lane.SourceNetworkName, lane.DestNetworkName)] = ccipLoad diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index 3465b58204..2c150bbc5a 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -276,7 +276,7 @@ func (l *LoadArgs) TriggerLoadByLane() { ccipLoad := NewCCIPLoad( l.TestCfg.Test, lane, l.TestCfg.TestGroupInput.PhaseTimeout.Duration(), 100000, l.TestCfg.TestGroupInput.LoadProfile.MsgProfile, sendMaxData, - l.TestCfg.TestGroupInput.LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin, + l.TestCfg.TestGroupInput.SkipRequestIfAnotherRequestTriggeredWithin, ) ccipLoad.BeforeAllCall() // if it's not multicall set the tokens to nil to free up some space, diff --git a/integration-tests/ccip-tests/smoke/ccip_test.go b/integration-tests/ccip-tests/smoke/ccip_test.go index 83bed78507..bf2533f02a 100644 --- a/integration-tests/ccip-tests/smoke/ccip_test.go +++ b/integration-tests/ccip-tests/smoke/ccip_test.go @@ -3,26 +3,30 @@ package smoke import ( "fmt" "math/big" + "strings" "testing" "time" "github.com/AlekSi/pointer" + "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" ) type testDefinition struct { @@ -906,6 +910,123 @@ func TestSmokeCCIPReorgAboveFinalityAtSource(t *testing.T) { }) } +// TestSmokeCCIPForGivenNetworkPairs is designed specifically for scheduled mainnet testing. This test checks for recent +// transaction and skip the lanes accordingly. This test also has capability to take override input on network pairs and phase timeout. +func TestSmokeCCIPForGivenNetworkPairs(t *testing.T) { + t.Parallel() + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + // override network pairs + var temp []testsetups.NetworkPair + overrideNetworkPairs, err := osutil.GetEnv("OVERRIDE_NETWORK_PAIRS") + require.NoError(t, err, "Error getting OVERRIDE_NETWORK_PAIRS environment variable") + if overrideNetworkPairs != "" { + networkPairs := strings.Split(overrideNetworkPairs, ";") + for _, networkPair := range networkPairs { + // check for any malformed inputs + if !strings.Contains(networkPair, ",") || len(strings.Split(networkPair, ",")) != 2 { + log.Error().Msgf("malformed OVERRIDE_NETWORK_PAIRS environment variable for network pair: %s ", networkPair) + return + } + networkPair = strings.ToUpper(strings.ReplaceAll(networkPair, "_", " ")) + for _, network := range TestCfg.NetworkPairs { + if strings.Contains(networkPair, strings.ToUpper(network.NetworkA.Name)) && strings.Contains(networkPair, strings.ToUpper(network.NetworkB.Name)) { + temp = append(temp, network) + break + } + } + } + log.Info().Int("Pairs", len(temp)).Msg("Number of lanes overridden in the test") + log.Info().Interface("Lanes", networkPairs).Msg("Lanes under test") + TestCfg.NetworkPairs = temp + } + + // phase timeout override + phaseTimeout, err := osutil.GetEnv("OVERRIDE_PHASE_TIMEOUT") + require.NoError(t, err, "Error getting OVERRIDE_PHASE_TIMEOUT environment variable") + if phaseTimeout != "" { + configDuration, err := config.ParseDuration(phaseTimeout) + require.NoError(t, err, "Error parsing phase timeout value") + TestCfg.TestGroupInput.PhaseTimeout = &configDuration + log.Info().Float64("Timeout in minutes", configDuration.Duration().Minutes()).Msg("Phase timeout is overridden") + } + + gasLimit := big.NewInt(*TestCfg.TestGroupInput.MsgDetails.DestGasLimit) + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + log.Error().Msg("No lanes found") + return + } + + t.Cleanup(func() { + // If we are running a test that is a token transfer, we need to verify the balance. + // skip the balance check for existing deployment, there can be multiple external requests in progress for existing deployments + // other than token transfer initiated by the test, which can affect the balance check + // therefore we check the balance only for the ccip environment created by the test + if TestCfg.TestGroupInput.MsgDetails.IsTokenTransfer() && + !pointer.GetBool(TestCfg.TestGroupInput.USDCMockDeployment) && + !pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment) { + setUpOutput.Balance.Verify(t) + } + require.NoError(t, setUpOutput.TearDown(), "error in tear down step") + }) + + var tests []testDefinition + lookBackDuration := TestCfg.TestGroupInput.SkipRequestIfAnotherRequestTriggeredWithin + var recentTxFound *types.Log + + addLanesToTest := func(lane *actions.CCIPLane) { + // Create test definitions for given lane if no previous request has been triggered within the specified timeframe. + // By default, the timeframe is set to nil. To define a timeframe, assign a duration to the variable + // SkipRequestIfAnotherRequestTriggeredWithin. + if lookBackDuration != nil { + recentTxFound, err = lane.Source.IsPastRequestTriggeredWithinTimeframe(lane.Context, lookBackDuration) + require.NoError(t, err, "error while finding recent request for lane network %s to network %s", + lane.SourceNetworkName, lane.DestNetworkName) + } + if recentTxFound == nil { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.SourceNetworkName, lane.DestNetworkName), + lane: lane, + }) + } else { + log.Info(). + Str("TX", recentTxFound.TxHash.Hex()). + Uint64("Block Number", recentTxFound.BlockNumber). + Str("Source", lane.SourceNetworkName). + Str("Dest", lane.DestNetworkName). + Msgf("Lane Skipped. Recent request found within %v minutes.", lookBackDuration.Duration().Minutes()) + } + } + for _, lane := range setUpOutput.Lanes { + addLanesToTest(lane.ForwardLane) + if lane.ReverseLane != nil { + recentTxFound = nil + addLanesToTest(lane.ReverseLane) + } + } + + // Execute tests. + log.Info().Int("Total Lanes", len(tests)).Msg("Starting CCIP test") + for _, test := range tests { + tc := test + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + tc.lane.Test = t + log.Info(). + Str("Source", tc.lane.SourceNetworkName). + Str("Destination", tc.lane.DestNetworkName). + Msgf("Starting lane %s -> %s", tc.lane.SourceNetworkName, tc.lane.DestNetworkName) + + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, gasLimit) + require.NoError(t, err, "error sending requests") + tc.lane.ValidateRequests() + }) + } +} + // performAboveFinalityReorgAndValidate is to perform the above finality reorg test func performAboveFinalityReorgAndValidate(t *testing.T, network string) { t.Helper() diff --git a/integration-tests/ccip-tests/testconfig/README.md b/integration-tests/ccip-tests/testconfig/README.md index 474ac2a3af..cf1431baa9 100644 --- a/integration-tests/ccip-tests/testconfig/README.md +++ b/integration-tests/ccip-tests/testconfig/README.md @@ -657,6 +657,13 @@ Specifies the OCR parameters for the execute job. This is only valid if the test Specifies the value for the `InflightExpiry` in commit job's offchain config. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). +### CCIP.Groups.[testgroup].SkipRequestIfAnotherRequestTriggeredWithin + +If there is CCIP Send requested event present within this duration, the test will skip sending another +request during load run or avoid sending request in smoke test in that lane. For Example, +if `SkipRequestIfAnotherRequestTriggeredWithin` is set to `40m`, and a request is triggered at 0th second, the test will skip sending another request for another 40m. +This particular field is used to avoid sending transaction when there is traffic already in that lane. + ### CCIP.Groups.[testgroup].OffRampConfig Specifies the offramp configuration for the execution job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). @@ -736,11 +743,6 @@ Specifies the duration network delay used for `NetworkChaos` experiment. This is If there are multiple chaos experiments, this specifies the duration to wait between each chaos experiment. This is only valid if the test is run on k8s and not on [existing deployments](#ccipgroupstestgroupexistingdeployment). -#### CCIP.Groups.[testgroup].LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin - -If a request is triggered within this duration, the test will skip sending another request during load run. For Example, if `SkipRequestIfAnotherRequestTriggeredWithin` is set to `40m`, and a request is triggered at 0th second, the test will skip sending another request for another 40m. -This particular field is used to avoid sending multiple requests in a short duration during load run. - #### CCIP.Groups.[testgroup].LoadProfile.OptimizeSpace This is used internally to optimize memory usage during load run. If set to true, after the initial lane set up is over the test will discard the lane config to save memory. diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go index 1f4dfaac51..7925ffa71f 100644 --- a/integration-tests/ccip-tests/testconfig/ccip.go +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -211,19 +211,18 @@ type LoadFrequency struct { } type LoadProfile struct { - MsgProfile *MsgProfile `toml:",omitempty"` - FrequencyByDestination map[string]*LoadFrequency `toml:",omitempty"` - RequestPerUnitTime []int64 `toml:",omitempty"` - TimeUnit *config.Duration `toml:",omitempty"` - StepDuration []*config.Duration `toml:",omitempty"` - TestDuration *config.Duration `toml:",omitempty"` - NetworkChaosDelay *config.Duration `toml:",omitempty"` - WaitBetweenChaosDuringLoad *config.Duration `toml:",omitempty"` - SkipRequestIfAnotherRequestTriggeredWithin *config.Duration `toml:",omitempty"` - OptimizeSpace *bool `toml:",omitempty"` - FailOnFirstErrorInLoad *bool `toml:",omitempty"` - SendMaxDataInEveryMsgCount *int64 `toml:",omitempty"` - TestRunName string `toml:",omitempty"` + MsgProfile *MsgProfile `toml:",omitempty"` + FrequencyByDestination map[string]*LoadFrequency `toml:",omitempty"` + RequestPerUnitTime []int64 `toml:",omitempty"` + TimeUnit *config.Duration `toml:",omitempty"` + StepDuration []*config.Duration `toml:",omitempty"` + TestDuration *config.Duration `toml:",omitempty"` + NetworkChaosDelay *config.Duration `toml:",omitempty"` + WaitBetweenChaosDuringLoad *config.Duration `toml:",omitempty"` + OptimizeSpace *bool `toml:",omitempty"` + FailOnFirstErrorInLoad *bool `toml:",omitempty"` + SendMaxDataInEveryMsgCount *int64 `toml:",omitempty"` + TestRunName string `toml:",omitempty"` } func (l *LoadProfile) Validate() error { @@ -242,9 +241,7 @@ func (l *LoadProfile) Validate() error { if l.TestDuration == nil || l.TestDuration.Duration().Minutes() == 0 { return fmt.Errorf("test duration should be set") } - if l.SkipRequestIfAnotherRequestTriggeredWithin != nil && l.TimeUnit.Duration() < l.SkipRequestIfAnotherRequestTriggeredWithin.Duration() { - return fmt.Errorf("SkipRequestIfAnotherRequestTriggeredWithin should be set below the TimeUnit duration") - } + return nil } @@ -265,35 +262,36 @@ func (gp *ReorgProfile) Validate() error { // CCIPTestGroupConfig defines configuration input to change how a particular CCIP test group should run type CCIPTestGroupConfig struct { - Type string `toml:",omitempty"` - KeepEnvAlive *bool `toml:",omitempty"` - BiDirectionalLane *bool `toml:",omitempty"` - CommitAndExecuteOnSameDON *bool `toml:",omitempty"` - AllowOutOfOrder *bool `toml:",omitempty"` // To set out of order execution globally - NoOfCommitNodes int `toml:",omitempty"` - MsgDetails *MsgDetails `toml:",omitempty"` - TokenConfig *TokenConfig `toml:",omitempty"` - MulticallInOneTx *bool `toml:",omitempty"` - NoOfSendsInMulticall int `toml:",omitempty"` - PhaseTimeout *config.Duration `toml:",omitempty"` - LocalCluster *bool `toml:",omitempty"` - ExistingDeployment *bool `toml:",omitempty"` - ReuseContracts *bool `toml:",omitempty"` - NodeFunding float64 `toml:",omitempty"` - NetworkPairs []string `toml:",omitempty"` - DenselyConnectedNetworkChainIds []string `toml:",omitempty"` - NoOfNetworks int `toml:",omitempty"` - NoOfRoutersPerPair int `toml:",omitempty"` - MaxNoOfLanes int `toml:",omitempty"` - ChaosDuration *config.Duration `toml:",omitempty"` - USDCMockDeployment *bool `toml:",omitempty"` - CommitOCRParams *contracts.OffChainAggregatorV2Config `toml:",omitempty"` - ExecOCRParams *contracts.OffChainAggregatorV2Config `toml:",omitempty"` - OffRampConfig *OffRampConfig `toml:",omitempty"` - CommitInflightExpiry *config.Duration `toml:",omitempty"` - StoreLaneConfig *bool `toml:",omitempty"` - LoadProfile *LoadProfile `toml:",omitempty"` - ReorgProfile *ReorgProfile `toml:",omitempty"` + Type string `toml:",omitempty"` + KeepEnvAlive *bool `toml:",omitempty"` + BiDirectionalLane *bool `toml:",omitempty"` + CommitAndExecuteOnSameDON *bool `toml:",omitempty"` + AllowOutOfOrder *bool `toml:",omitempty"` // To set out of order execution globally + NoOfCommitNodes int `toml:",omitempty"` + MsgDetails *MsgDetails `toml:",omitempty"` + TokenConfig *TokenConfig `toml:",omitempty"` + MulticallInOneTx *bool `toml:",omitempty"` + NoOfSendsInMulticall int `toml:",omitempty"` + PhaseTimeout *config.Duration `toml:",omitempty"` + LocalCluster *bool `toml:",omitempty"` + ExistingDeployment *bool `toml:",omitempty"` + ReuseContracts *bool `toml:",omitempty"` + NodeFunding float64 `toml:",omitempty"` + NetworkPairs []string `toml:",omitempty"` + DenselyConnectedNetworkChainIds []string `toml:",omitempty"` + NoOfNetworks int `toml:",omitempty"` + NoOfRoutersPerPair int `toml:",omitempty"` + MaxNoOfLanes int `toml:",omitempty"` + ChaosDuration *config.Duration `toml:",omitempty"` + USDCMockDeployment *bool `toml:",omitempty"` + CommitOCRParams *contracts.OffChainAggregatorV2Config `toml:",omitempty"` + ExecOCRParams *contracts.OffChainAggregatorV2Config `toml:",omitempty"` + OffRampConfig *OffRampConfig `toml:",omitempty"` + CommitInflightExpiry *config.Duration `toml:",omitempty"` + StoreLaneConfig *bool `toml:",omitempty"` + LoadProfile *LoadProfile `toml:",omitempty"` + ReorgProfile *ReorgProfile `toml:",omitempty"` + SkipRequestIfAnotherRequestTriggeredWithin *config.Duration `toml:",omitempty"` } func (c *CCIPTestGroupConfig) Validate() error { @@ -341,6 +339,10 @@ func (c *CCIPTestGroupConfig) Validate() error { return fmt.Errorf("number of sends in multisend should be greater than 0 if multisend is true") } } + if c.SkipRequestIfAnotherRequestTriggeredWithin != nil && c.LoadProfile != nil && + c.LoadProfile.TimeUnit.Duration() < c.SkipRequestIfAnotherRequestTriggeredWithin.Duration() { + return fmt.Errorf("SkipRequestIfAnotherRequestTriggeredWithin should be set below the load TimeUnit duration") + } return nil } diff --git a/integration-tests/ccip-tests/testconfig/override/mainnet.toml b/integration-tests/ccip-tests/testconfig/override/mainnet.toml index f723411eaf..6fa0c3e0dd 100644 --- a/integration-tests/ccip-tests/testconfig/override/mainnet.toml +++ b/integration-tests/ccip-tests/testconfig/override/mainnet.toml @@ -1081,52 +1081,80 @@ TTL = '8h' [CCIP.Env.Network] selected_networks = [ - 'ARBITRUM_MAINNET', - 'AVALANCHE_MAINNET', - 'BSC_MAINNET', - 'BASE_MAINNET', - 'ETHEREUM_MAINNET', - 'KROMA_MAINNET', - 'OPTIMISM_MAINNET', - 'POLYGON_MAINNET', - 'WEMIX_MAINNET', - ] + 'ARBITRUM_MAINNET', + 'AVALANCHE_MAINNET', + 'BASE_MAINNET', + 'BLAST_MAINNET', + 'BSC_MAINNET', + 'CELO_MAINNET', + 'ETHEREUM_MAINNET', + 'GNOSIS_MAINNET', + 'KROMA_MAINNET', + 'METIS_ANDROMEDA', + 'MODE_MAINNET', + 'OPTIMISM_MAINNET', + 'POLYGON_MAINNET', + 'WEMIX_MAINNET', + 'ZKSYNC_MAINNET', +] [CCIP.Groups.load] NetworkPairs = [ - 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', - 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', - 'ETHEREUM_MAINNET,POLYGON_MAINNET', - 'ETHEREUM_MAINNET,BSC_MAINNET', - 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', - 'ETHEREUM_MAINNET,BASE_MAINNET', - 'ETHEREUM_MAINNET,WEMIX_MAINNET', - 'AVALANCHE_MAINNET,POLYGON_MAINNET', - 'BASE_MAINNET,OPTIMISM_MAINNET', - 'BASE_MAINNET,ARBITRUM_MAINNET', - 'AVALANCHE_MAINNET,BSC_MAINNET', - 'BSC_MAINNET,POLYGON_MAINNET', - 'OPTIMISM_MAINNET,POLYGON_MAINNET', - 'BASE_MAINNET,BSC_MAINNET', - 'POLYGON_MAINNET,ARBITRUM_MAINNET', # added as batch 1 - 'ARBITRUM_MAINNET,BSC_MAINNET', # added as batch 1 - 'ARBITRUM_MAINNET,OPTIMISM_MAINNET', # added as batch 1 - 'AVALANCHE_MAINNET,OPTIMISM_MAINNET', # added as batch 2 - 'AVALANCHE_MAINNET,ARBITRUM_MAINNET', # added as batch 2 - 'BASE_MAINNET,POLYGON_MAINNET', # added as batch 2 - 'BSC_MAINNET,OPTIMISM_MAINNET', # added as batch 2 - 'AVALANCHE_MAINNET,BASE_MAINNET', # added as batch 2 - 'WEMIX_MAINNET,KROMA_MAINNET', - 'BSC_MAINNET,WEMIX_MAINNET', # added as batch 2 - 'AVALANCHE_MAINNET,WEMIX_MAINNET', # added as batch 2 - 'POLYGON_MAINNET,WEMIX_MAINNET', # added as batch 2 - 'WEMIX_MAINNET,ARBITRUM_MAINNET', # added as batch 2 - 'OPTIMISM_MAINNET,WEMIX_MAINNET' # added as batch 2 + 'ARBITRUM_MAINNET,BSC_MAINNET', + 'ARBITRUM_MAINNET,OPTIMISM_MAINNET', + 'AVALANCHE_MAINNET,ARBITRUM_MAINNET', + 'AVALANCHE_MAINNET,BASE_MAINNET', + 'AVALANCHE_MAINNET,BSC_MAINNET', + 'AVALANCHE_MAINNET,OPTIMISM_MAINNET', + 'AVALANCHE_MAINNET,POLYGON_MAINNET', + 'AVALANCHE_MAINNET,WEMIX_MAINNET', + 'BASE_MAINNET,ARBITRUM_MAINNET', + 'BASE_MAINNET,BSC_MAINNET', + 'BASE_MAINNET,OPTIMISM_MAINNET', + 'BASE_MAINNET,POLYGON_MAINNET', + 'BLAST_MAINNET,ARBITRUM_MAINNET', + 'BLAST_MAINNET,BASE_MAINNET', + 'BLAST_MAINNET,BSC_MAINNET', + 'BSC_MAINNET,OPTIMISM_MAINNET', + 'BSC_MAINNET,POLYGON_MAINNET', + 'BSC_MAINNET,WEMIX_MAINNET', + 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', + 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', + 'ETHEREUM_MAINNET,BASE_MAINNET', + 'ETHEREUM_MAINNET,BLAST_MAINNET', + 'ETHEREUM_MAINNET,BSC_MAINNET', + 'ETHEREUM_MAINNET,CELO_MAINNET', + 'ETHEREUM_MAINNET,GNOSIS_MAINNET', + 'ETHEREUM_MAINNET,METIS_ANDROMEDA', + 'ETHEREUM_MAINNET,MODE_MAINNET', + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,POLYGON_MAINNET', + 'ETHEREUM_MAINNET,WEMIX_MAINNET', + 'ETHEREUM_MAINNET,ZKSYNC_MAINNET', + 'GNOSIS_MAINNET,ARBITRUM_MAINNET', + 'GNOSIS_MAINNET,AVALANCHE_MAINNET', + 'GNOSIS_MAINNET,BASE_MAINNET', + 'GNOSIS_MAINNET,BSC_MAINNET', + 'GNOSIS_MAINNET,OPTIMISM_MAINNET', + 'GNOSIS_MAINNET,POLYGON_MAINNET', + 'METIS_ANDROMEDA,ARBITRUM_MAINNET', + 'MODE_MAINNET,ARBITRUM_MAINNET', + 'MODE_MAINNET,BASE_MAINNET', + 'MODE_MAINNET,BSC_MAINNET', + 'MODE_MAINNET,OPTIMISM_MAINNET', + 'OPTIMISM_MAINNET,POLYGON_MAINNET', + 'OPTIMISM_MAINNET,WEMIX_MAINNET', + 'POLYGON_MAINNET,ARBITRUM_MAINNET', + 'POLYGON_MAINNET,WEMIX_MAINNET', + 'WEMIX_MAINNET,ARBITRUM_MAINNET', + 'WEMIX_MAINNET,KROMA_MAINNET', + 'ZKSYNC_MAINNET,ARBITRUM_MAINNET' ] BiDirectionalLane = true -PhaseTimeout = '30m' +PhaseTimeout = '20m' ExistingDeployment = true +SkipRequestIfAnotherRequestTriggeredWithin = '40m' [CCIP.Groups.load.TokenConfig] NoOfTokensPerChain = 1 @@ -1137,7 +1165,7 @@ TimeUnit = '1h' TestDuration = '5h' TestRunName = 'Soak_test_mainnet' FailOnFirstErrorInLoad = true -SkipRequestIfAnotherRequestTriggeredWithin = '40m' + [[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] MsgType = 'Data' @@ -1149,34 +1177,55 @@ AmountPerToken = 1 [CCIP.Groups.smoke] # these are all the valid network pairs NetworkPairs = [ - 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', - 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', - 'ETHEREUM_MAINNET,POLYGON_MAINNET', - 'ETHEREUM_MAINNET,BSC_MAINNET', - 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', - 'ETHEREUM_MAINNET,BASE_MAINNET', - 'ETHEREUM_MAINNET,WEMIX_MAINNET', - 'AVALANCHE_MAINNET,POLYGON_MAINNET', - 'BASE_MAINNET,OPTIMISM_MAINNET', - 'BASE_MAINNET,ARBITRUM_MAINNET', - 'AVALANCHE_MAINNET,BSC_MAINNET', - 'BSC_MAINNET,POLYGON_MAINNET', - 'OPTIMISM_MAINNET,POLYGON_MAINNET', - 'BASE_MAINNET,BSC_MAINNET', - 'POLYGON_MAINNET,ARBITRUM_MAINNET', # added as batch 1 - 'ARBITRUM_MAINNET,BSC_MAINNET', # added as batch 1 - 'ARBITRUM_MAINNET,OPTIMISM_MAINNET', # added as batch 1 - 'AVALANCHE_MAINNET,OPTIMISM_MAINNET', # added as batch 2 - 'AVALANCHE_MAINNET,ARBITRUM_MAINNET', # added as batch 2 - 'BASE_MAINNET,POLYGON_MAINNET', # added as batch 2 - 'BSC_MAINNET,OPTIMISM_MAINNET', # added as batch 2 - 'AVALANCHE_MAINNET,BASE_MAINNET', # added as batch 2 - 'WEMIX_MAINNET,KROMA_MAINNET', - 'BSC_MAINNET,WEMIX_MAINNET', # added as batch 2 - 'AVALANCHE_MAINNET,WEMIX_MAINNET', # added as batch 2 - 'POLYGON_MAINNET,WEMIX_MAINNET', # added as batch 2 - 'WEMIX_MAINNET,ARBITRUM_MAINNET', # added as batch 2 - 'OPTIMISM_MAINNET,WEMIX_MAINNET' # added as batch 2 + 'ARBITRUM_MAINNET,BSC_MAINNET', + 'ARBITRUM_MAINNET,OPTIMISM_MAINNET', + 'AVALANCHE_MAINNET,ARBITRUM_MAINNET', + 'AVALANCHE_MAINNET,BASE_MAINNET', + 'AVALANCHE_MAINNET,BSC_MAINNET', + 'AVALANCHE_MAINNET,OPTIMISM_MAINNET', + 'AVALANCHE_MAINNET,POLYGON_MAINNET', + 'AVALANCHE_MAINNET,WEMIX_MAINNET', + 'BASE_MAINNET,ARBITRUM_MAINNET', + 'BASE_MAINNET,BSC_MAINNET', + 'BASE_MAINNET,OPTIMISM_MAINNET', + 'BASE_MAINNET,POLYGON_MAINNET', + 'BLAST_MAINNET,ARBITRUM_MAINNET', + 'BLAST_MAINNET,BASE_MAINNET', + 'BLAST_MAINNET,BSC_MAINNET', + 'BSC_MAINNET,OPTIMISM_MAINNET', + 'BSC_MAINNET,POLYGON_MAINNET', + 'BSC_MAINNET,WEMIX_MAINNET', + 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', + 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', + 'ETHEREUM_MAINNET,BASE_MAINNET', + 'ETHEREUM_MAINNET,BLAST_MAINNET', + 'ETHEREUM_MAINNET,BSC_MAINNET', + 'ETHEREUM_MAINNET,CELO_MAINNET', + 'ETHEREUM_MAINNET,GNOSIS_MAINNET', + 'ETHEREUM_MAINNET,METIS_ANDROMEDA', + 'ETHEREUM_MAINNET,MODE_MAINNET', + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,POLYGON_MAINNET', + 'ETHEREUM_MAINNET,WEMIX_MAINNET', + 'ETHEREUM_MAINNET,ZKSYNC_MAINNET', + 'GNOSIS_MAINNET,ARBITRUM_MAINNET', + 'GNOSIS_MAINNET,AVALANCHE_MAINNET', + 'GNOSIS_MAINNET,BASE_MAINNET', + 'GNOSIS_MAINNET,BSC_MAINNET', + 'GNOSIS_MAINNET,OPTIMISM_MAINNET', + 'GNOSIS_MAINNET,POLYGON_MAINNET', + 'METIS_ANDROMEDA,ARBITRUM_MAINNET', + 'MODE_MAINNET,ARBITRUM_MAINNET', + 'MODE_MAINNET,BASE_MAINNET', + 'MODE_MAINNET,BSC_MAINNET', + 'MODE_MAINNET,OPTIMISM_MAINNET', + 'OPTIMISM_MAINNET,POLYGON_MAINNET', + 'OPTIMISM_MAINNET,WEMIX_MAINNET', + 'POLYGON_MAINNET,ARBITRUM_MAINNET', + 'POLYGON_MAINNET,WEMIX_MAINNET', + 'WEMIX_MAINNET,ARBITRUM_MAINNET', + 'WEMIX_MAINNET,KROMA_MAINNET', + 'ZKSYNC_MAINNET,ARBITRUM_MAINNET' ] BiDirectionalLane = true @@ -1184,7 +1233,7 @@ PhaseTimeout = '20m' LocalCluster = false ExistingDeployment = true ReuseContracts = true - +SkipRequestIfAnotherRequestTriggeredWithin = '24h' [CCIP.Groups.smoke.TokenConfig] NoOfTokensPerChain = 1