diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 791fe02f6..8d4da0d43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -827,6 +827,57 @@ jobs: pnpm install pnpm moonwall test zombie_${{ matrix.chains.chain }}_upgrade + zombienet-test-upgrade-starlight: + runs-on: self-hosted + needs: ["set-tags", "build"] + strategy: + fail-fast: false + matrix: + chains: [ + { chain: "dancelight", runtime: "dancelight" } + ] + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ needs.set-tags.outputs.git_ref }} + + - name: Pnpm + uses: pnpm/action-setup@v4.0.0 + with: + version: 9 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: "pnpm" + + - name: Create local folders + run: | + mkdir -p target/release/wbuild/${{ matrix.chains.runtime }}-runtime/ + mkdir -p test/tmp + - name: "Download binaries" + uses: actions/download-artifact@v4 + with: + name: binaries + path: target/release + - name: "Download runtime" + uses: actions/download-artifact@v4 + with: + name: runtimes + path: target/release/wbuild/${{ matrix.chains.runtime }}-runtime/ + + - name: "Install and run upgrade test" + run: | + chmod uog+x target/release/container-chain-simple-node + chmod uog+x target/release/tanssi-relay + chmod uog+x target/release/tanssi-relay-execute-worker + chmod uog+x target/release/tanssi-relay-prepare-worker + cd test + pnpm install + pnpm moonwall test zombie_${{ matrix.chains.chain }}_upgrade + docker-tanssi: runs-on: ubuntu-latest needs: ["set-tags", "build"] diff --git a/test/configs/zombieDancelightUpgrade.json b/test/configs/zombieDancelightUpgrade.json new file mode 100644 index 000000000..ef9bdc1f2 --- /dev/null +++ b/test/configs/zombieDancelightUpgrade.json @@ -0,0 +1,66 @@ +{ + "settings": { + "timeout": 1000, + "provider": "native" + }, + "relaychain": { + "chain_spec_path": "specs/tanssi-relay.json", + "default_command": "../target/release/tanssi-relay", + "default_args": ["--no-hardware-benchmarks", "-lparachain=debug", "--database=paritydb", "--no-beefy"], + "genesis": { + "runtimeGenesis": { + "patch": { + "configuration": { + "config": { + "async_backing_params": { + "allowed_ancestry_len": 2, + "max_candidate_depth": 3 + }, + "scheduler_params": { + "scheduling_lookahead": 2, + "num_cores": 4 + } + } + } + } + } + }, + "nodes": [ + { + "name": "alice", + "ws_port": "9947", + "validator": true + }, + { + "name": "bob", + "validator": true + } + ] + }, + "parachains": [ + { + "id": 2000, + "chain": "dev", + "add_to_genesis": false, + "register_para": false, + "onboard_as_parachain": false, + "collators": [ + { + "name": "FullNode-2000", + "validator": false, + "chain": "dev", + "command": "../target/release/container-chain-simple-node", + "ws_port": 9948, + "p2p_port": 33051 + } + ] + } + ], + "types": { + "Header": { + "number": "u64", + "parent_hash": "Hash", + "post_state": "Hash" + } + } +} diff --git a/test/moonwall.config.json b/test/moonwall.config.json index bd31ab8bd..1956d27ab 100644 --- a/test/moonwall.config.json +++ b/test/moonwall.config.json @@ -532,7 +532,7 @@ }, { "name": "zombie_dancebox_upgrade", - "testFileDir": ["suites/rt-upgrade-zombienet"], + "testFileDir": ["suites/rt-upgrade-parachain-zombienet"], "runScripts": ["download-polkadot.sh"], "timeout": 600000, "foundation": { @@ -582,6 +582,31 @@ } ] }, + { + "name": "zombie_dancelight_upgrade", + "testFileDir": ["suites/rt-upgrade-relay-zombienet"], + "runScripts": [ + "download-latest-rt-binaries-starlight.sh", + "build-spec-dancelight-single.sh tmp" + ], + + "timeout": 900000, + "foundation": { + "rtUpgradePath": "../target/release/wbuild/dancelight-runtime/dancelight_runtime.compact.compressed.wasm", + "type": "zombie", + "zombieSpec": { + "configPath": "./configs/zombieDancelightUpgrade.json", + "disableDefaultEthProviders": true + } + }, + "connections": [ + { + "name": "parachain", + "type": "polkadotJs", + "endpoints": ["ws://127.0.0.1:9947"] + } + ] + }, { "name": "zombie_simple_template_upgrade_with_latest_releases", "testFileDir": ["suites/rt-upgrade-templates-zombienet"], diff --git a/test/scripts/build-spec-dancelight-single.sh b/test/scripts/build-spec-dancelight-single.sh new file mode 100755 index 000000000..a20103415 --- /dev/null +++ b/test/scripts/build-spec-dancelight-single.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Exit on any error +set -e + +# Always run the commands from the "test" dir +cd $(dirname $0)/.. + +if [[ -z "${1}" || ${1} == "undefined" ]]; then + BINARY_FOLDER="../target/release" +else + BINARY_FOLDER="${1}" +fi + +mkdir -p specs +$BINARY_FOLDER/tanssi-relay build-spec --chain dancelight-local > specs/tanssi-relay.json diff --git a/test/scripts/download-latest-rt-binaries-starlight.sh b/test/scripts/download-latest-rt-binaries-starlight.sh new file mode 100755 index 000000000..ab071aa23 --- /dev/null +++ b/test/scripts/download-latest-rt-binaries-starlight.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Exit on any error +set -e + +# Always run the commands from the "test" dir +cd $(dirname $0)/.. + +LATEST_RUNTIME_RELEASE=$(curl -s https://api.github.com/repos/moondance-labs/tanssi/releases | jq -r '.[] | select(.name | test("runtime";"i") and (test("starlight";"i"))) | .tag_name' | head -n 1 | tr -d '[:blank:]') && [[ ! -z "${LATEST_RUNTIME_RELEASE}" ]] +ENDPOINT="https://api.github.com/repos/moondance-labs/tanssi/git/refs/tags/$LATEST_RUNTIME_RELEASE" +RESPONSE=$(curl -s -H "Accept: application/vnd.github.v3+json" $ENDPOINT) +TYPE=$(echo $RESPONSE | jq -r '.object.type') +if [[ $TYPE == "commit" ]] +then + LATEST_RT_SHA8=$(echo $RESPONSE | jq -r '.object.sha' | cut -c -8) +elif [[ $TYPE == "tag" ]] +then + URL=$(echo $RESPONSE | jq -r '.object.url') + TAG_RESPONSE=$(curl -s -H "Accept: application/vnd.github.v3+json" $URL) + TAG_RESPONSE_CLEAN=$(echo $TAG_RESPONSE | tr -d '\000-\037') + LATEST_RT_SHA8=$(echo $TAG_RESPONSE_CLEAN | jq -r '.object.sha' | cut -c -8) +fi + +DOCKER_TAG_STARLIGHT="moondancelabs/starlight:sha-$LATEST_RT_SHA8-fast-runtime" + +docker rm -f starlight_container 2> /dev/null | true +docker create --name starlight_container $DOCKER_TAG_STARLIGHT bash +docker cp starlight_container:tanssi-relay/tanssi-relay tmp/tanssi-relay +docker cp starlight_container:tanssi-relay/tanssi-relay-execute-worker tmp/tanssi-relay-execute-worker +docker cp starlight_container:tanssi-relay/tanssi-relay-prepare-worker tmp/tanssi-relay-prepare-worker +docker rm -f starlight_container +chmod uog+x ../target/release/tanssi-relay +chmod uog+x tmp/tanssi-relay \ No newline at end of file diff --git a/test/scripts/download-latest-rt-binaries.sh b/test/scripts/download-latest-rt-binaries.sh index 3a7c2b310..3a327d0d3 100755 --- a/test/scripts/download-latest-rt-binaries.sh +++ b/test/scripts/download-latest-rt-binaries.sh @@ -6,7 +6,8 @@ set -e # Always run the commands from the "test" dir cd $(dirname $0)/.. -LATEST_RUNTIME_RELEASE=$(curl -s https://api.github.com/repos/moondance-labs/tanssi/releases | jq -r '.[] | select(.name | test("runtime";"i")) | .tag_name' | head -n 1 | tr -d '[:blank:]') && [[ ! -z "${LATEST_RUNTIME_RELEASE}" ]] +LATEST_RUNTIME_RELEASE=$(curl -s https://api.github.com/repos/moondance-labs/tanssi/releases | jq -r '.[] | select(.name | test("runtime";"i") and (test("starlight";"i")|not)) | .tag_name' | head -n 1 | tr -d '[:blank:]') && [[ ! -z "${LATEST_RUNTIME_RELEASE}" ]] + ENDPOINT="https://api.github.com/repos/moondance-labs/tanssi/git/refs/tags/$LATEST_RUNTIME_RELEASE" RESPONSE=$(curl -s -H "Accept: application/vnd.github.v3+json" $ENDPOINT) TYPE=$(echo $RESPONSE | jq -r '.object.type') @@ -21,7 +22,13 @@ then LATEST_RT_SHA8=$(echo $TAG_RESPONSE_CLEAN | jq -r '.object.sha' | cut -c -8) fi -DOCKER_TAG_TANSSI="moondancelabs/tanssi:sha-$LATEST_RT_SHA8" +RUNTIME_VER=$(echo $LATEST_RUNTIME_RELEASE | tr -d -c 0-9) + +if [ "$RUNTIME_VER" -ge 900 ]; then + DOCKER_TAG_TANSSI="moondancelabs/tanssi:sha-$LATEST_RT_SHA8-fast-runtime" +else + DOCKER_TAG_TANSSI="moondancelabs/tanssi:sha-$LATEST_RT_SHA8" +fi docker rm -f tanssi_container 2> /dev/null | true docker create --name tanssi_container $DOCKER_TAG_TANSSI bash @@ -30,8 +37,11 @@ docker rm -f tanssi_container chmod uog+x ../target/release/tanssi-node chmod uog+x tmp/tanssi-node -DOCKER_TAG_CONTAINER_SIMPLE="moondancelabs/container-chain-simple-template:sha-$LATEST_RT_SHA8" -RUNTIME_VER=$(echo $LATEST_RUNTIME_RELEASE | tr -d -c 0-9) +if [ "$RUNTIME_VER" -ge 900 ]; then + DOCKER_TAG_CONTAINER_SIMPLE="moondancelabs/container-chain-simple-template:sha-$LATEST_RT_SHA8-fast-runtime" +else + DOCKER_TAG_CONTAINER_SIMPLE="moondancelabs/container-chain-simple-template:sha-$LATEST_RT_SHA8" +fi docker rm -f tanssi_container_simple 2> /dev/null | true docker create --name tanssi_container_simple $DOCKER_TAG_CONTAINER_SIMPLE bash @@ -44,7 +54,11 @@ docker rm -f tanssi_container_simple chmod uog+x ../target/release/container-chain-simple-node chmod uog+x tmp/container-chain-simple-node -DOCKER_TAG_CONTAINER_FRONTIER="moondancelabs/container-chain-evm-template:sha-$LATEST_RT_SHA8" +if [ "$RUNTIME_VER" -ge 900 ]; then + DOCKER_TAG_CONTAINER_FRONTIER="moondancelabs/container-chain-evm-template:sha-$LATEST_RT_SHA8-fast-runtime" +else + DOCKER_TAG_CONTAINER_FRONTIER="moondancelabs/container-chain-evm-template:sha-$LATEST_RT_SHA8" +fi docker rm -f tanssi_container_frontier 2> /dev/null | true docker create --name tanssi_container_frontier $DOCKER_TAG_CONTAINER_FRONTIER bash diff --git a/test/suites/rt-upgrade-zombienet/test-upgrade-chain.ts b/test/suites/rt-upgrade-parachain-zombienet/test-upgrade-chain.ts similarity index 100% rename from test/suites/rt-upgrade-zombienet/test-upgrade-chain.ts rename to test/suites/rt-upgrade-parachain-zombienet/test-upgrade-chain.ts diff --git a/test/suites/rt-upgrade-relay-zombienet/test-upgrade-chain.ts b/test/suites/rt-upgrade-relay-zombienet/test-upgrade-chain.ts new file mode 100644 index 000000000..a42c08ca3 --- /dev/null +++ b/test/suites/rt-upgrade-relay-zombienet/test-upgrade-chain.ts @@ -0,0 +1,69 @@ +import { MoonwallContext, beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import fs from "node:fs"; + +describeSuite({ + id: "R01", + title: "Zombie Dancelight Upgrade Test", + foundationMethods: "zombie", + testCases: function ({ it, context, log }) { + let relayApi: ApiPromise; + let alice: KeyringPair; + + beforeAll(async () => { + const keyring = new Keyring({ type: "sr25519" }); + alice = keyring.addFromUri("//Alice", { name: "Alice default" }); + relayApi = context.polkadotJs("parachain"); + + const relayNetwork = relayApi.consts.system.version.specName.toString(); + expect(relayNetwork, "Relay API incorrect").to.contain("dancelight"); + + const currentBlock = (await relayApi.rpc.chain.getBlock()).block.header.number.toNumber(); + expect(currentBlock, "Parachain not producing blocks").to.be.greaterThan(0); + }, 120000); + + it({ + id: "T01", + title: "Blocks are being produced on parachain", + test: async function () { + const blockNum = (await relayApi.rpc.chain.getBlock()).block.header.number.toNumber(); + expect(blockNum).to.be.greaterThan(0); + }, + }); + + it({ + id: "T02", + title: "Chain can be upgraded", + timeout: 600000, + test: async function () { + const blockNumberBefore = (await relayApi.rpc.chain.getBlock()).block.header.number.toNumber(); + const currentCode = await relayApi.rpc.state.getStorage(":code"); + const codeString = currentCode.toString(); + + const wasm = fs.readFileSync((await MoonwallContext.getContext()).rtUpgradePath); + const rtHex = `0x${wasm.toString("hex")}`; + const rtBefore = relayApi.consts.system.version.specVersion.toNumber(); + + if (rtHex === codeString) { + log("Runtime already upgraded, skipping test"); + return; + } else { + log("Runtime not upgraded, proceeding with test"); + log("Current runtime hash: " + rtHex.slice(0, 10) + "..." + rtHex.slice(-10)); + log("New runtime hash: " + codeString.slice(0, 10) + "..." + codeString.slice(-10)); + } + + await context.upgradeRuntime({ from: alice, logger: log }); + await context.waitBlock(2); + const rtafter = relayApi.consts.system.version.specVersion.toNumber(); + if (rtBefore === rtafter) { + throw new Error("Runtime upgrade failed"); + } + const blockNumberAfter = (await relayApi.rpc.chain.getBlock()).block.header.number.toNumber(); + log(`Before: #${blockNumberBefore}, After: #${blockNumberAfter}`); + expect(blockNumberAfter, "Block number did not increase").to.be.greaterThan(blockNumberBefore); + }, + }); + }, +});