From c6aaa88ca965a88bd71fdc0bd61ac0cf9c4e8e47 Mon Sep 17 00:00:00 2001 From: Konstantin Astakhov Date: Sun, 14 Aug 2022 21:01:00 +0000 Subject: [PATCH] add CI for update parachain & relay with forking data --- --- /dev/null +++ b/.docker/forking/Dockerfile-parachain-live-fork @@ -0,0 +1,126 @@ +# ===== Rust builder ===== +FROM ubuntu:20.04 as rust-builder +LABEL maintainer="Unique.Network" + +ARG RUST_TOOLCHAIN= + +ARG UNIQUE_BRANCH=develop + +ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN +ENV UNIQUE_BRANCH $UNIQUE_BRANCH + +ENV CARGO_HOME="/cargo-home" +ENV PATH="/cargo-home/bin:$PATH" +ENV TZ=UTC +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update && \ + apt-get install -y curl cmake pkg-config libssl-dev git clang && \ + apt-get clean && \ + rm -r /var/lib/apt/lists/* + +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none + +RUN rustup toolchain uninstall $(rustup toolchain list) && \ + rustup toolchain install $RUST_TOOLCHAIN && \ + rustup default $RUST_TOOLCHAIN && \ + rustup target list --installed && \ + rustup show +RUN rustup target add wasm32-unknown-unknown --toolchain $RUST_TOOLCHAIN + +# ===== BUILD current version ====== +FROM rust-builder as builder-unique-current + +ARG PROFILE=release +ARG FEATURE= +ARG MAINNET_BRANCH= +ARG REPO_URL= + +RUN mkdir /unique_parachain +WORKDIR /unique_parachain + +RUN git clone $REPO_URL -b $MAINNET_BRANCH . && \ + cargo build --features=$FEATURE --$PROFILE + + +# ===== BUILD target version ====== +FROM rust-builder as builder-unique-target + +ARG PROFILE=release +ARG FEATURE= +ARG BRANCH= +ARG REPO_URL= + +RUN mkdir /unique_parachain +WORKDIR /unique_parachain + +RUN git clone $REPO_URL -b $BRANCH . && \ + cargo build --features=$FEATURE --$PROFILE + +# ===== BUILD POLKADOT ===== +FROM rust-builder as builder-polkadot + +ARG POLKADOT_BUILD_BRANCH= +ENV POLKADOT_BUILD_BRANCH $POLKADOT_BUILD_BRANCH + +RUN mkdir /unique_parachain +WORKDIR /unique_parachain + +RUN git clone -b $POLKADOT_BUILD_BRANCH --depth 1 https://github.com/paritytech/polkadot.git && \ + cd polkadot && \ + cargo build --release + +# ===== BUILD CHAINQL ===== +FROM rust-builder as builder-chainql + +RUN mkdir chainql +WORKDIR /chainql + +RUN git clone --depth 1 https://github.com/CertainLach/chainql.git . && \ + cargo build --release + +# ===== RUN ====== + +FROM ubuntu:20.04 + +ARG RUNTIME= +ENV RUNTIME $RUNTIME + +RUN apt-get -y update && \ + apt-get -y install curl git && \ + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \ + export NVM_DIR="$HOME/.nvm" && \ + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \ + nvm install v16.16.0 && \ + nvm use v16.16.0 + +RUN git clone https://github.com/uniquenetwork/polkadot-launch -b feature/parachain-forking + +RUN export NVM_DIR="$HOME/.nvm" && \ + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \ + cd /polkadot-launch && \ + npm install --global yarn && \ + yarn + +RUN echo "$RUNTIME" + +COPY --from=builder-unique-current /unique_parachain/target/release/unique-collator /unique-chain/current/release/ +COPY --from=builder-unique-target /unique_parachain/target/release/unique-collator /unique-chain/target/release/ +COPY --from=builder-unique-target /unique_parachain/target/release/wbuild/"$RUNTIME"-runtime/"$RUNTIME"_runtime.compact.compressed.wasm /unique-chain/target/release/wbuild/"$RUNTIME"-runtime/"$RUNTIME"_runtime.compact.compressed.wasm + +COPY --from=builder-polkadot /unique_parachain/polkadot/target/release/polkadot /polkadot/target/release/ +COPY --from=builder-polkadot /unique_parachain/polkadot/target/release/wbuild/westend-runtime/westend_runtime.compact.compressed.wasm /polkadot/target/release/wbuild/westend-runtime/westend_runtime.compact.compressed.wasm + +COPY --from=builder-chainql /chainql/target/release/chainql /chainql/target/release/ + +ARG FORK_FROM=wss://eu-ws-quartz.unique.network:443 +ENV FORK_FROM=$FORK_FROM +CMD export NVM_DIR="$HOME/.nvm" PATH="$PATH:/chainql/target/release" FORK_FROM && \ + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \ + cd /polkadot-launch && \ + yarn start launch-config.json --test-upgrade-parachains + + + + + --- /dev/null +++ b/.docker/forking/docker-compose-fork.yaml @@ -0,0 +1,28 @@ +version: "3.5" + +services: + parachain-fork: + build: + context: ../ + dockerfile: .docker/forking/Dockerfile-parachain-live-fork + image: parachain-fork + container_name: parachain-fork + volumes: + - type: bind + source: ./launch-config-fork.json + target: /polkadot-launch/launch-config.json + read_only: true + - type: bind + source: ./fork.jsonnet + target: /polkadot-launch/fork.jsonnet + read_only: true + expose: + - 9944 + - 9933 + ports: + - 127.0.0.1:9944:9944 + - 127.0.0.1:9933:9933 + logging: + options: + max-size: "1m" + max-file: "3" --- /dev/null +++ b/.docker/forking/docker-compose.tmp-fork.j2 @@ -0,0 +1,14 @@ +version: "3.5" + +services: + parachain-fork: + build: + args: + - "RUST_TOOLCHAIN={{ RUST_TOOLCHAIN }}" + - "BRANCH={{ BRANCH }}" + - "REPO_URL={{ REPO_URL }}" + - "FEATURE={{ FEATURE }}" + - "RUNTIME={{ RUNTIME }}" + - "POLKADOT_BUILD_BRANCH={{ POLKADOT_BUILD_BRANCH }}" + - "MAINNET_TAG={{ MAINNET_TAG }}" + - "MAINNET_BRANCH={{ MAINNET_BRANCH }}" --- /dev/null +++ b/.docker/forking/fork.jsonnet @@ -0,0 +1,59 @@ + +function(rawSpec, forkFrom) +local sourceChain = cql.chain(forkFrom).latest; + +local raw = local sourceRaw = sourceChain._raw._preloadKeys; { + [key]: cql.toHex(sourceRaw[key]) + for key in std.objectFields(sourceRaw) + if sourceRaw[key] != null +}; + +local +auraKeys = [ + // AuraExt.Authorities, we don't have aura pallet enabled for some reason, to refer using cql api + '0x3c311d57d4daf52904616cf69648081e5e0621c4869aa60c02be9adcc98a0d1d', + // Aura.Authorities + '0x57f8dc2f5ab09467896f47300f0424385e0621c4869aa60c02be9adcc98a0d1d', +], + +// Keys, which should be migrated from passed spec, rather than from forked chain +wantedKeys = [ + sourceChain.ParachainInfo._key.ParachainId, + sourceChain.Sudo._key.Key, + sourceChain.System.BlockHash._key['0'], + sourceChain.System._key.ParentHash, +] + auraKeys, + +// Keys to remove from original chain +unwantedPrefixes = [ + // Aura.CurrentSlot + '0x57f8dc2f5ab09467896f47300f04243806155b3cd9a8c9e5e9a23fd5dc13a5ed', + // Ensure there will be no panics caused by unexpected kept state + sourceChain.ParachainSystem._key.ValidationData, + sourceChain.ParachainSystem._key.RelayStateProof, + sourceChain.ParachainSystem._key.HostConfiguration, + sourceChain.ParachainSystem._key.LastDmqMqcHead, + // Part of head + sourceChain.System._key.BlockHash, + sourceChain.System._key.Number, + sourceChain.System._key.Digest, +] + auraKeys, + +cleanupRaw(raw) = { + [key]: raw[key] + for key in std.objectFields(raw) + if std.all(std.map(function(prefix) !std.startsWith(key, prefix), unwantedPrefixes)) +}; + +local originalRaw = rawSpec.genesis.raw.top; +local outSpec = rawSpec { + genesis+: { + raw+: { + top: cleanupRaw(raw) { + [key]: originalRaw[key] + for key in wantedKeys + }, + }, + }, +}; +outSpec --- /dev/null +++ b/.docker/forking/launch-config-fork.j2 @@ -0,0 +1,132 @@ +{ + "relaychain": { + "bin": "/polkadot/target/release/polkadot", + "upgradeBin": "/polkadot/target/release/polkadot", + "upgradeWasm": "/polkadot/target/release/wbuild/westend-runtime/westend_runtime.compact.compressed.wasm", + "chain": "westend-local", + "nodes": [ + { + "name": "alice", + "wsPort": 9844, + "rpcPort": 9843, + "port": 30444, + "flags": [ + "-lparachain::candidate_validation=debug", + "-lxcm=trace", + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "name": "bob", + "wsPort": 9855, + "rpcPort": 9854, + "port": 30555, + "flags": [ + "-lparachain::candidate_validation=debug", + "-lxcm=trace", + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "name": "charlie", + "wsPort": 9866, + "rpcPort": 9865, + "port": 30666, + "flags": [ + "-lparachain::candidate_validation=debug", + "-lxcm=trace", + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "name": "dave", + "wsPort": 9877, + "rpcPort": 9876, + "port": 30777, + "flags": [ + "-lparachain::candidate_validation=debug", + "-lxcm=trace", + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "name": "eve", + "wsPort": 9888, + "rpcPort": 9887, + "port": 30888, + "flags": [ + "-lparachain::candidate_validation=debug", + "-lxcm=trace", + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + } + ], + "genesis": { + "runtime": { + "runtime_genesis_config": { + "parachainsConfiguration": { + "config": { + "validation_upgrade_frequency": 1, + "validation_upgrade_delay": 1 + } + } + } + } + } + }, + "parachains": [ + { + "bin": "/unique-chain/current/release/unique-collator", + "upgradeBin": "/unique-chain/target/release/unique-collator", + "upgradeWasm": "/unique-chain/target/release/wbuild/{{ FEATURE }}/{{ RUNTIME }}_runtime.compact.compressed.wasm", + "id": "1000", + "balance": "1000000000000000000000000", + "chainRawInitializer": [ + "chainql", + "--ext-str=FORK_FROM", + "--tla-code=rawSpec=import '${rawSpec}'", + "--tla-code=forkFrom=std.extVar('FORK_FROM')", + "fork.jsonnet" + ], + "nodes": [ + { + "port": 31200, + "wsPort": 9944, + "rpcPort": 9933, + "name": "alice", + "flags": [ + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external", + "-lxcm=trace" + ] + }, + { + "port": 31201, + "wsPort": 9945, + "rpcPort": 9934, + "name": "bob", + "flags": [ + "--rpc-cors=all", + "--unsafe-rpc-external", + "--unsafe-ws-external", + "-lxcm=trace" + ] + } + ] + } + ], + "simpleParachains": [], + "hrmpChannels": [], + "finalization": false +} --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,5 @@ .git/ .github/ -.docker/ doc/ target/ tests/ --- a/.env +++ b/.env @@ -5,4 +5,4 @@ UNIQUE_MAINNET_TAG=v924010 KUSAMA_MAINNET_BRANCH=release-v0.9.26 -QUARTZ_MAINNET_TAG=v924012 \ No newline at end of file +QUARTZ_MAINNET_TAG=quartz-v924012-2 --- /dev/null +++ b/.github/workflows/fork-update-withdata.yml @@ -0,0 +1,203 @@ +name: Forkless Parachain update with no data + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + pull_request: + branches: + - develop + types: + - opened + - reopened + - synchronize #commit(s) pushed to the pull request + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +#Define Workflow variables +env: + REPO_URL: ${{ github.server_url }}/${{ github.repository }} + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + + prepare-execution-marix-fork: + + name: Prepare execution matrix for fork + + runs-on: self-hosted-ci + outputs: + matrix: ${{ steps.create_matrix.outputs.matrix }} + steps: + + - name: Clean Workspace + uses: AutoModality/action-clean@v1.1.0 + + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} #Checking out head commit + + - name: Read .env file + uses: xom9ikk/dotenv@v1.0.2 + + - name: Create Execution matrix + uses: fabiocaccamo/create-matrix-action@v2 + id: create_matrix + with: + matrix: | + network {Opal}, runtime {opal}, features {opal-runtime}, mainnet_branch {${{ env.OPAL_MAINNET_TAG }}} + network {Quartz}, runtime {quartz}, features {quartz-runtime}, mainnet_branch {${{ env.QUARTZ_MAINNET_TAG }}} + network {Unique}, runtime {unique}, features {unique-runtime}, mainnet_branch {${{ env.UNIQUE_MAINNET_TAG }}} + + + + fork-update-withdata: + needs: prepare-execution-marix-fork + # The type of runner that the job will run on + runs-on: ci-tests + + name: Build Container, Spin it Up an test + + continue-on-error: true #Do not stop testing of matrix runs failed. As it decided during PR review - it required 50/50& Let's check it with false. + + strategy: + matrix: + include: ${{fromJson(needs.prepare-execution-marix-fork.outputs.matrix)}} +# include: +# - network: "Opal" +# features: "opal-runtime" +# runtime: "opal" +# mainnet_branch: v924010 +# mainnet_tag: v924010 +# - network: "Quartz" # KUSAMA_MAINNET_BRANCH для quartz-runtime +# features: "quartz-runtime" +# runtime: "quartz" +# mainnet_branch: quartz-v924012-2 +# mainnet_tag: v924012 +# - network: "Unique" # POLKADOT_MAINNET_BRANCH для unique-runtime +# features: "unique-runtime" +# runtime: "unique" +# mainnet_branch: v924010 +# mainnet_tag: v924010 + + + + steps: +# - name: Skip if pull request is in Draft + # `if: github.event.pull_request.draft == true` should be kept here, at + # the step level, rather than at the job level. The latter is not + # recommended because when the PR is moved from "Draft" to "Ready to + # review" the workflow will immediately be passing (since it was skipped), + # even though it hasn't actually ran, since it takes a few seconds for + # the workflow to start. This is also disclosed in: + # https://github.community/t/dont-run-actions-on-draft-pull-requests/16817/17 + # That scenario would open an opportunity for the check to be bypassed: + # 1. Get your PR approved + # 2. Move it to Draft + # 3. Push whatever commits you want + # 4. Move it to "Ready for review"; now the workflow is passing (it was + # skipped) and "Check reviews" is also passing (it won't be updated + # until the workflow is finished) +# if: github.event.pull_request.draft == true +# run: exit 1 + + - name: Clean Workspace + uses: AutoModality/action-clean@v1.1.0 + + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} #Checking out head commit + + - name: Read .env file + uses: xom9ikk/dotenv@v1.0.2 + + - name: Generate ENV related extend file for docker-compose + uses: cuchi/jinja2-action@v1.2.0 + with: + template: .docker/forking/docker-compose.tmp-fork.j2 + output_file: .docker/forking/docker-compose.${{ matrix.network }}.yml + variables: | + REPO_URL=${{ github.server_url }}/${{ github.repository }}.git + RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }} + POLKADOT_BUILD_BRANCH=${{ env.POLKADOT_BUILD_BRANCH }} + POLKADOT_MAINNET_BRANCH=${{ env.POLKADOT_MAINNET_BRANCH }} + MAINNET_TAG=${{ matrix.mainnet_tag }} + MAINNET_BRANCH=${{ matrix.mainnet_branch }} + FEATURE=${{ matrix.features }} + RUNTIME=${{ matrix.runtime }} + BRANCH=${{ github.head_ref }} + + - name: Show build configuration + run: cat .docker/forking/docker-compose.${{ matrix.network }}.yml + + - name: Generate launch-config-fork.json + uses: cuchi/jinja2-action@v1.2.0 + with: + template: .docker/forking/launch-config-fork.j2 + output_file: .docker/forking/launch-config-fork.json + variables: | + FEATURE=${{ matrix.features }} + RUNTIME=${{ matrix.runtime }} + + - name: Show launch-config-fork configuration + run: cat .docker/forking/launch-config-fork.json + + + - name: Build the stack + run: docker-compose -f ".docker/forking/docker-compose-fork.yaml" -f ".docker/forking/docker-compose.${{ matrix.network }}.yml" up -d --build --force-recreate --timeout 300 + + - name: Check if docker logs consist logs related to Runtime Upgrade testing. + if: success() + run: | + counter=160 + function do_docker_logs { + docker logs --details parachain-fork 2>&1 + } + function is_started { + echo "Check Docker logs" + DOCKER_LOGS=$(do_docker_logs) + if [[ ${DOCKER_LOGS} = *"🛸 PARACHAINS' RUNTIME UPGRADE TESTING COMPLETE 🛸"* ]];then + echo "🛸 PARACHAINS' RUNTIME UPGRADE TESTING COMPLETE 🛸" + return 0 + exit 0 + fi + echo "Function is_started: Return 1" + return 1 + } + while ! is_started; do + echo "Waiting for special message in log files " + sleep 30s + counter=$(( $counter - 1 )) + echo "Counter: $counter" + if [ "$counter" -gt "0" ]; then + continue + else + break + fi + done + exit 1 + shell: bash + + - name: Collect Docker Logs + if: success() || failure() + uses: jwalton/gh-docker-logs@v2.2.0 + with: + dest: './fork-parachain-update-withdata-logs.${{ matrix.features }}' + images: 'parachain-fork' + + - name: Tar logs + if: success() || failure() + run: tar cvzf ./fork-parachain-update-withdata-logs.${{ matrix.features }}.tgz ./fork-parachain-update-withdata-logs.${{ matrix.features }} + + - name: Upload logs to GitHub + if: success() || failure() + uses: actions/upload-artifact@master + with: + name: fork-parachain-update-withdata-logs.${{ matrix.features }}.tgz + path: ./fork-parachain-update-withdata-logs.${{ matrix.features }}.tgz + +# - name: Stop running containers +# if: always() # run this step always +# run: docker-compose -f ".docker/forking/docker-compose-fork.yaml" -f ".docker/forking/docker-compose.${{ matrix.network }}.yml" down -- gitstuff