diff --git a/.github/actions/performance-tests/art.yaml b/.github/actions/performance-tests/art.yaml index 70d2ba1f85..35f79a788f 100644 --- a/.github/actions/performance-tests/art.yaml +++ b/.github/actions/performance-tests/art.yaml @@ -1,8 +1,8 @@ config: - target: "http://localhost:9545" + target: "-=http_request_protocol=-://-=endpoint_to_test=-" phases: - - duration: 60 - arrivalRate: 10 + - duration: 300 + arrivalRate: 400 defaults: headers: content-type: "application/json" @@ -19,7 +19,6 @@ config: - type: "html" filename: "artillery_report.html" logLevel: debug - scenarios: - name: web3_clientVersion flow: diff --git a/.github/workflows/ci-nightly-performance-testing.yaml b/.github/workflows/ci-nightly-performance-testing.yaml index a6a566f4aa..0c6280b135 100644 --- a/.github/workflows/ci-nightly-performance-testing.yaml +++ b/.github/workflows/ci-nightly-performance-testing.yaml @@ -2,6 +2,11 @@ name: "NIGHTLY:EVM:PERFORMANCE:TESTING" on: workflow_dispatch: + inputs: + endpoint: + description: 'The EVM endpoint you want to test.' + required: false + default: 'http://localhost:9545' schedule: - cron: '0 0 * * *' # Runs every day at midnight UTC @@ -9,6 +14,8 @@ jobs: nightly_evm_api_performance_test: name: "NIGHTLY:EVM:API:PERFORMANCE:TEST" runs-on: "buildjet-16vcpu-ubuntu-2204" + env: + endpoint_to_test: "http://localhost:9545" steps: - uses: actions/checkout@v4 @@ -25,16 +32,62 @@ jobs: run: | npm install -g artillery@latest + - name: "CONFIGURE:PERFORMANCE:TEMPLATE" + run: | + # Check if the inputs.endpoint starts with https:// or http:// + if [[ "${{inputs.endpoint}}" =~ ^https:// ]]; then + # Set the http_request_protocol to https if the URL starts with https:// + export http_request_protocol=https + elif [[ "${{inputs.endpoint}}" =~ ^http:// ]]; then + # Set the http_request_protocol to http if the URL starts with http:// + export http_request_protocol=http + else + # If the URL doesn't start with either http:// or https://, print an error and exit + echo "Please input a url with either https:// or http://" && exit 1 + fi + + # Check if inputs.endpoint is different from the default "http://localhost:9545" + if [ "${{inputs.endpoint}}" != "http://localhost:9545" ]; then + # Check if inputs.endpoint is not empty + if [ -n "${{inputs.endpoint}}" ]; then + # If inputs.endpoint isn't different from the default and is not empty, use inputs.endpoint + export endpoint_to_test=${{inputs.endpoint}} + # Remove the protocol (http:// or https://) from endpoint_to_test + endpoint_to_test=${endpoint_to_test#http://} + endpoint_to_test=${endpoint_to_test#https://} + else + # If inputs.endpoint is empty, strip the protocol from endpoint_to_test + endpoint_to_test=${endpoint_to_test#http://} + endpoint_to_test=${endpoint_to_test#https://} + fi + else + # If inputs.endpoint is "http://localhost:9545", strip the protocol from endpoint_to_test + endpoint_to_test=${endpoint_to_test#http://} + endpoint_to_test=${endpoint_to_test#https://} + fi + + # Replace -=endpoint_to_test=- placeholder in the art.yaml file with the endpoint_to_test value + sed -i "s/-=endpoint_to_test=-/${endpoint_to_test}/g" .github/actions/performance-tests/art.yaml + # Replace -=http_request_protocol=- placeholder in the art.yaml file with the http_request_protocol value + sed -i "s/-=http_request_protocol=-/${http_request_protocol}/g" .github/actions/performance-tests/art.yaml + - name: "EXECUTE:PERFORMANCE:TESTS" run: | - artillery run .github/actions/performance-tests/art.yaml --record --key ${{ secrets.ARTILLERY_KEY }} --output ./report.json + # Execute Artillery to run performance tests using the specified configuration file + artillery run .github/actions/performance-tests/art.yaml \ + --record \ + --key ${{ secrets.ARTILLERY_KEY }} \ + --output ./report.json + + - name: "CHECK:TEST:RESULTS" + run: | # Check Artillery exit status if [ $? -ne 0 ]; then echo "Artillery command failed to execute." exit 1 fi - # Parse the results.json file to check for failed vusers and http response codes + # Parse the results.json file to check for failed vusers and HTTP response codes failed_vusers=$(jq '.aggregate.counters["vusers.failed"] // 0' ./report.json) http_codes_200=$(jq '.aggregate.counters["http.codes.200"] // 0' ./report.json) http_responses=$(jq '.aggregate.counters["http.responses"] // 0' ./report.json) @@ -45,6 +98,26 @@ jobs: else echo "EVM Performance Testing Successful" fi + + # Read the JSON file and extract the required metrics + p99_values=$(jq -r '.aggregate.summaries["http.response_time"].p99, .aggregate.summaries["plugins.metrics-by-endpoint.response_time./"].p99, .aggregate.summaries["vusers.session_length"].p99' ./report.json) + p50_values=$(jq -r '.aggregate.summaries["http.response_time"].p50, .aggregate.summaries["plugins.metrics-by-endpoint.response_time./"].p50, .aggregate.summaries["vusers.session_length"].p50' ./report.json) + + # Check P99 values + for p99 in $p99_values; do + if (( $(echo "$p99 > 2000" | bc -l) )); then + echo "P99 value $p99 exceeds 2000ms" + exit 1 + fi + done + + # Check P50 values + for p50 in $p50_values; do + if (( $(echo "$p50 > 40" | bc -l) )); then + echo "P50 value $p50 exceeds 40ms" + exit 1 + fi + done - name: "GENERATE:REPORT" if: always() diff --git a/.github/workflows/reusable-e2e.yml b/.github/workflows/reusable-e2e.yml index 2407598141..2bc75efcfb 100644 --- a/.github/workflows/reusable-e2e.yml +++ b/.github/workflows/reusable-e2e.yml @@ -101,7 +101,7 @@ jobs: path: /tmp/logs.txt - name: Notify Slack on Failure - if: failure() && (github.event_name == 'push' && github.ref == 'refs/heads/develop') || github.event_name == 'schedule' + if: failure() && ((github.event_name == 'push' && github.ref == 'refs/heads/develop') || github.event_name == 'schedule') uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} diff --git a/Dockerfile-localnet b/Dockerfile-localnet index f9ff74d48a..24b98adf53 100644 --- a/Dockerfile-localnet +++ b/Dockerfile-localnet @@ -59,13 +59,9 @@ FROM base-runtime AS latest-runtime COPY --from=cosmovisor-build /go/bin/cosmovisor /usr/local/bin COPY --from=latest-build /go/bin/zetacored /go/bin/zetaclientd /go/bin/zetaclientd-supervisor /go/bin/zetae2e /usr/local/bin -# optional old version build. This old build is used as the genesis version in the upgrade tests. -# use --target latest-runtime to skip -# -# TODO: just download binaries from github release now that we're using glibc -# we can't do this right now since we do not have a v16 release candidate -# https://github.com/zeta-chain/node/issues/2179 -FROM base-build as old-build +# Optional old version build (from source). This old build is used as the genesis version in the upgrade tests. +# Use --target latest-runtime to skip. +FROM base-build as old-build-source ARG OLD_VERSION RUN git clone https://github.com/zeta-chain/node.git @@ -74,8 +70,22 @@ RUN cd node && git fetch RUN cd node && git checkout ${OLD_VERSION} RUN cd node && make install +FROM base-runtime AS old-runtime-source + +COPY --from=cosmovisor-build /go/bin/cosmovisor /usr/local/bin +COPY --from=old-build-source /go/bin/zetacored /go/bin/zetaclientd /usr/local/bin +COPY --from=latest-build /go/bin/zetaclientd-supervisor /usr/local/bin + +# Optional old version build (from binary). +# Use --target latest-runtime to skip. FROM base-runtime AS old-runtime +ARG OLD_VERSION +ARG BUILDARCH + COPY --from=cosmovisor-build /go/bin/cosmovisor /usr/local/bin -COPY --from=old-build /go/bin/zetacored /go/bin/zetaclientd /usr/local/bin -COPY --from=latest-build /go/bin/zetaclientd-supervisor /usr/local/bin \ No newline at end of file +COPY --from=latest-build /go/bin/zetaclientd-supervisor /usr/local/bin +RUN curl -Lo /usr/local/bin/zetacored ${OLD_VERSION}/zetacored-linux-${BUILDARCH} && \ + chmod 755 /usr/local/bin/zetacored && \ + curl -Lo /usr/local/bin/zetaclientd ${OLD_VERSION}/zetaclientd-linux-${BUILDARCH} && \ + chmod 755 /usr/local/bin/zetaclientd \ No newline at end of file diff --git a/Makefile b/Makefile index 177f064722..c929aea7f8 100644 --- a/Makefile +++ b/Makefile @@ -258,12 +258,19 @@ start-stress-test: zetanode ### Upgrade Tests ### ############################################################################### - +# build from source only if requested +ifdef UPGRADE_TEST_FROM_SOURCE zetanode-upgrade: zetanode - @echo "Building zetanode-upgrade" - $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime --build-arg OLD_VERSION='release/v17' . - $(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile.fastbuild . + @echo "Building zetanode-upgrade from source" + $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime-source --build-arg OLD_VERSION='release/v17' . +.PHONY: zetanode-upgrade +else +zetanode-upgrade: zetanode + @echo "Building zetanode-upgrade from binaries" + $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime --build-arg OLD_VERSION='https://github.com/zeta-chain/ci-testing-node/releases/download/v17.0.1-internal' . .PHONY: zetanode-upgrade +endif + start-upgrade-test: zetanode-upgrade @echo "--> Starting upgrade test" @@ -277,6 +284,14 @@ start-upgrade-test-light: zetanode-upgrade export UPGRADE_HEIGHT=90 && \ cd contrib/localnet/ && $(DOCKER) compose --profile upgrade -f docker-compose.yml -f docker-compose-upgrade.yml up -d + +start-upgrade-test-admin: zetanode-upgrade + @echo "--> Starting admin upgrade test" + export LOCALNET_MODE=upgrade && \ + export UPGRADE_HEIGHT=90 && \ + export E2E_ARGS="--skip-regular --test-admin" && \ + cd contrib/localnet/ && $(DOCKER) compose --profile upgrade -f docker-compose.yml -f docker-compose-upgrade.yml up -d + start-upgrade-import-mainnet-test: zetanode-upgrade @echo "--> Starting import-data upgrade test" export LOCALNET_MODE=upgrade && \ diff --git a/changelog.md b/changelog.md index fc417b1109..ae3f8d42fe 100644 --- a/changelog.md +++ b/changelog.md @@ -77,6 +77,7 @@ * [2368](https://github.com/zeta-chain/node/pull/2368) - eliminate panic usage across testing suite * [2369](https://github.com/zeta-chain/node/pull/2369) - fix random cross-chain swap failure caused by using tiny UTXO * [2549](https://github.com/zeta-chain/node/pull/2459) - add separate accounts for each policy in e2e tests +* [2415](https://github.com/zeta-chain/node/pull/2415) - add e2e test for upgrade and test admin functionalities ### Fixes @@ -89,6 +90,7 @@ * [2327](https://github.com/zeta-chain/node/pull/2327) - partially cherry picked the fix to Bitcoin outbound dust amount * [2362](https://github.com/zeta-chain/node/pull/2362) - set 1000 satoshis as minimum BTC amount that can be withdrawn from zEVM * [2382](https://github.com/zeta-chain/node/pull/2382) - add tx input and gas in rpc methods for synthetic eth txs +* [2434](https://github.com/zeta-chain/node/pull/2434) - the default database when running `zetacored init` is now pebbledb ### CI * [2388](https://github.com/zeta-chain/node/pull/2388) - added GitHub attestations of binaries produced in the release workflow. @@ -102,6 +104,7 @@ * [2335](https://github.com/zeta-chain/node/pull/2335) - ci: updated the artillery report to publish to artillery cloud * [2377](https://github.com/zeta-chain/node/pull/2377) - ci: adjusted sast-linters.yml to not scan itself, nor alert on removal of nosec. * [2400](https://github.com/zeta-chain/node/pull/2400) - ci: adjusted the performance test to pass or fail pipeline based on test results, alert slack, and launch network with state. Fixed connection issues as well. +* [2425](https://github.com/zeta-chain/node/pull/2425) - Added verification to performance testing pipeline to ensure p99 aren't above 2000ms and p50 aren't above 40ms, Tweaked the config to 400 users requests per second. 425 is the current max before it starts failing. ### Documentation diff --git a/cmd/zetacored/root.go b/cmd/zetacored/root.go index 28654f885c..65a4e447c3 100644 --- a/cmd/zetacored/root.go +++ b/cmd/zetacored/root.go @@ -114,6 +114,8 @@ func initTmConfig() *tmcfg.Config { cfg.Mempool.Version = tmcfg.MempoolV1 } + cfg.DBBackend = "pebbledb" + return cfg } diff --git a/e2e/e2etests/test_rate_limiter.go b/e2e/e2etests/test_rate_limiter.go index af8221f23f..d1eb666986 100644 --- a/e2e/e2etests/test_rate_limiter.go +++ b/e2e/e2etests/test_rate_limiter.go @@ -71,8 +71,8 @@ func TestRateLimiter(r *runner.E2ERunner, _ []string) { // https://github.com/zeta-chain/node/issues/2090 r.Logger.Print("rate limiter enabled") require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, zetaAmount)) - require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, ethAmount)) - require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, erc20Amount)) + require.NoError(r, createAndWaitWithdraws(r, withdrawTypeETH, ethAmount)) + require.NoError(r, createAndWaitWithdraws(r, withdrawTypeERC20, erc20Amount)) // Disable rate limiter r.Logger.Info("disabling rate limiter") diff --git a/go.mod b/go.mod index 43584e6b4e..7e6324fd78 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/frumioj/crypto11 v1.2.5-0.20210823151709-946ce662cc0e github.com/pkg/errors v0.9.1 github.com/rakyll/statik v0.1.7 - github.com/zeta-chain/go-tss v0.1.1-0.20240430111318-1785e48eb127 + github.com/zeta-chain/go-tss v0.1.1-0.20240711114423-d6125e8b3b69 github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240418181724-c222fd3ae1f5 google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 @@ -334,7 +334,7 @@ require ( google.golang.org/protobuf v1.32.0 gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.2.1 // indirect nhooyr.io/websocket v1.8.7 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index ad13862826..4e076f69ff 100644 --- a/go.sum +++ b/go.sum @@ -1734,8 +1734,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94 h1:M54ljayJvy+WlEVdUmX8pgo1nA+XguB3mLhm3wi2z9o= github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94/go.mod h1:s1zA6OpXv3Tb5I0M6M6j5fo/AssaZL/pgkc7G0W2kN8= -github.com/zeta-chain/go-tss v0.1.1-0.20240430111318-1785e48eb127 h1:AGQepvsMIVHAHPlplzNcSCyMoGBY1DfO4WHG/QHUSIU= -github.com/zeta-chain/go-tss v0.1.1-0.20240430111318-1785e48eb127/go.mod h1:bVpAoSlRYYCY/R34horVU3cheeHqhSVxygelc++emIU= +github.com/zeta-chain/go-tss v0.1.1-0.20240711114423-d6125e8b3b69 h1:9OkWQkYWRyLWdaorf8ORhZk2f6hmR0IjXsC6w7PySAw= +github.com/zeta-chain/go-tss v0.1.1-0.20240711114423-d6125e8b3b69/go.mod h1:bVpAoSlRYYCY/R34horVU3cheeHqhSVxygelc++emIU= github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 h1:gd2uE0X+ZbdFJ8DubxNqLbOVlCB12EgWdzSNRAR82tM= github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2/go.mod h1:x7Bkwbzt2W2lQfjOirnff0Dj+tykdbTG1FMJPVPZsvE= github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240418181724-c222fd3ae1f5 h1:ljM7xka3WZvth9k1uYxrG3/FKQQTkR96FZlIjUKOoYw=