-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial impl of chain-upgrade * fmt * code for dummy upgrade * add test for dummy chain upgrade * fix run script * typo * add script to run local tests * clean and fix ci * debug in ci * add tests to image * typo
- Loading branch information
Showing
10 changed files
with
379 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
#!/bin/bash | ||
|
||
# Based on https://gitlab.parity.io/parity/simnet/-/blob/master/scripts/run-test-environment-manager-v2.sh | ||
|
||
set -eou pipefail | ||
|
||
|
||
function usage { | ||
cat << EOF | ||
DEPENDENCY 1: gcloud | ||
https://cloud.google.com/sdk/docs/install | ||
DEPENDENCY 2: kubectl | ||
gcloud components install kubectl | ||
Usage: ${SCRIPT_NAME} OPTION | ||
OPTION | ||
-t, --test OPTIONAL Test file to run | ||
If omitted "all" test in the tests directory will be used. | ||
-h, --help OPTIONAL Print this help message | ||
-o, --output-dir OPTIONAL | ||
Path to dir where to save contens of --github-remote-dir | ||
Defaults to ${SCRIPT_PATH} | ||
specified, it will be ifered from there. | ||
EXAMPLES | ||
Run tests | ||
${SCRIPT_NAME} -g https://github.com/paritytech/polkadot/tree/master/zombienet_tests | ||
EOF | ||
} | ||
|
||
function main { | ||
# Main entry point for the script | ||
set_defaults_for_globals | ||
parse_args "$@" | ||
create_isolated_dir | ||
copy_to_isolated | ||
run_test | ||
log INFO "Exit status is ${EXIT_STATUS}" | ||
exit "${EXIT_STATUS}" | ||
} | ||
|
||
function create_isolated_dir { | ||
TS=$(date +%s) | ||
ISOLATED=${OUTPUT_DIR}/${TS} | ||
mkdir -p ${ISOLATED} | ||
OUTPUT_DIR="${ISOLATED}" | ||
} | ||
|
||
function set_defaults_for_globals { | ||
# DEFAULT VALUES for variables used for testing different projects | ||
SCRIPT_NAME="$0" | ||
SCRIPT_PATH=$(dirname "$0") # relative | ||
SCRIPT_PATH=$(cd "${SCRIPT_PATH}" && pwd) # absolutized and normalized | ||
|
||
export GOOGLE_CREDENTIALS="/etc/zombie-net/sa-zombie.json" | ||
|
||
cd "${SCRIPT_PATH}" | ||
|
||
EXIT_STATUS=0 | ||
GH_REMOTE_DIR="" | ||
TEST_TO_RUN="" | ||
|
||
|
||
LAUNCH_ARGUMENTS="" | ||
USE_LOCAL_TESTS=false | ||
OUTPUT_DIR="${SCRIPT_PATH}" | ||
} | ||
|
||
function parse_args { | ||
function needs_arg { | ||
if [ -z "${OPTARG}" ]; then | ||
log DIE "No arg for --${OPT} option" | ||
fi | ||
} | ||
|
||
function check_args { | ||
if [[ -n "${GH_REMOTE_DIR}" && | ||
! "${GH_REMOTE_DIR}" =~ https:\/\/github.com\/ ]] ; then | ||
log DIE "Not a github URL" | ||
fi | ||
} | ||
|
||
# shellcheck disable=SC2214 | ||
while getopts i:t:g:h:uo:-: OPT; do | ||
# support long options: https://stackoverflow.com/a/28466267/519360 | ||
if [ "$OPT" = "-" ]; then # long option: reformulate OPT and OPTARG | ||
OPT="${OPTARG%%=*}" # extract long option name | ||
OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) | ||
OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` | ||
fi | ||
case "$OPT" in | ||
t | test) needs_arg ; TEST_TO_RUN="${OPTARG}" ;; | ||
g | github-remote-dir) needs_arg ; GH_REMOTE_DIR="${OPTARG}" ;; | ||
h | help ) usage ; exit 0 ;; | ||
o | output-dir) needs_arg ; OUTPUT_DIR="${OPTARG}" ;; | ||
??* ) log DIE "Illegal option --${OPT}" ;; | ||
? ) exit 2 ;; | ||
esac | ||
done | ||
shift $((OPTIND-1)) # remove parsed options and args from $@ list | ||
check_args | ||
} | ||
|
||
function copy_to_isolated { | ||
cd "${SCRIPT_PATH}" | ||
echo $(pwd) | ||
echo $(ls) | ||
echo $(ls ..) | ||
cp -r ../tests/* "${OUTPUT_DIR}" | ||
} | ||
function run_test { | ||
# RUN_IN_CONTAINER is env var that is set in the dockerfile | ||
if [[ -v RUN_IN_CONTAINER ]]; then | ||
gcloud auth activate-service-account --key-file "${GOOGLE_CREDENTIALS}" | ||
gcloud container clusters get-credentials parity-zombienet --zone europe-west3-b --project parity-zombienet | ||
fi | ||
cd "${OUTPUT_DIR}" | ||
set -x | ||
set +e | ||
if [[ ! -z $TEST_TO_RUN ]]; then | ||
TEST_FOUND=0 | ||
for i in $(find ${OUTPUT_DIR} -name "${TEST_TO_RUN}"| head -1); do | ||
TEST_FOUND=1 | ||
zombie test $i | ||
EXIT_STATUS=$? | ||
done; | ||
if [[ $TEST_FOUND -lt 1 ]]; then | ||
EXIT_STATUS=1 | ||
fi; | ||
else | ||
for i in $(find ${OUTPUT_DIR} -name *.feature | sort); do | ||
echo "running test: ${i}" | ||
zombie test $i | ||
TEST_EXIT_STATUS=$? | ||
EXIT_STATUS=$((EXIT_STATUS+TEST_EXIT_STATUS)) | ||
done; | ||
fi | ||
|
||
set +x | ||
set -e | ||
} | ||
|
||
function log { | ||
local lvl msg fmt | ||
lvl=$1 msg=$2 | ||
fmt='+%Y-%m-%d %H:%M:%S' | ||
lg_date=$(date "${fmt}") | ||
if [[ "${lvl}" = "DIE" ]] ; then | ||
lvl="ERROR" | ||
echo -e "\n${lg_date} - ${lvl} - ${msg}" | ||
exit 1 | ||
else | ||
echo -e "\n${lg_date} - ${lvl} - ${msg}" | ||
fi | ||
} | ||
|
||
main "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { ApiPromise, Keyring } from "@polkadot/api"; | ||
import { withTypeString } from "@polkadot/types"; | ||
import { cryptoWaitReady } from "@polkadot/util-crypto"; | ||
import { readFileSync, promises as fsPromises } from "fs"; | ||
|
||
import { compress, decompress } from "napi-maybe-compressed-blob"; | ||
|
||
export async function chainUpgrade(api: ApiPromise, wasmFilePath: string): Promise<void> { | ||
// The filename of the runtime/PVF we want to upgrade to. Usually a file | ||
// with `.compact.compressed.wasm` extension. | ||
console.log(`upgrading chain with file: ${wasmFilePath}`); | ||
|
||
let code = readFileSync(wasmFilePath).toString("hex"); | ||
await performChainUpgrade(api, code); | ||
} | ||
|
||
export async function chainDummyUpgrade(api: ApiPromise): Promise<void> { | ||
const code: any = await api.rpc.state.getStorage(":code"); | ||
const codeHex = code.toString().slice(2) | ||
const codeBuf = Buffer.from(hexToBytes(codeHex)); | ||
const decompressed = decompress(codeBuf); | ||
|
||
// add dummy | ||
// echo -n -e "\x00\x07\x05\x64\x75\x6D\x6D\x79\x0A" | ||
const dummyBuf = [0x00, 0x07, 0x05, 0x64, 0x75, 0x6D, 0x6D, 0x79, 0x0A]; | ||
const withDummyCode = Buffer.concat([decompressed, Buffer.from(dummyBuf)]); | ||
|
||
// compress again | ||
const compressed = compress(withDummyCode); | ||
|
||
// perform upgrade | ||
await performChainUpgrade(api, compressed.toString("hex")); | ||
} | ||
|
||
|
||
async function performChainUpgrade(api: ApiPromise, code: string) { | ||
await cryptoWaitReady() | ||
|
||
const keyring = new Keyring({ type: "sr25519" }); | ||
const alice = keyring.addFromUri("//Alice"); | ||
|
||
await new Promise<void>(async (resolve, reject) => { | ||
const unsub = await api.tx.sudo | ||
.sudoUncheckedWeight(api.tx.system.setCodeWithoutChecks(`0x${code}`), 1) | ||
.signAndSend(alice, (result) => { | ||
console.log(`Current status is ${result.status}`); | ||
if (result.status.isInBlock) { | ||
console.log( | ||
`Transaction included at blockHash ${result.status.asInBlock}` | ||
); | ||
} else if (result.status.isFinalized) { | ||
console.log( | ||
`Transaction finalized at blockHash ${result.status.asFinalized}` | ||
); | ||
unsub(); | ||
return resolve(); | ||
} else if (result.isError) { | ||
console.log(`Transaction Error`); | ||
unsub(); | ||
return reject(); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
/// Internal | ||
function hexToBytes(hex: any) { | ||
for (var bytes = [], c = 0; c < hex.length; c += 2) | ||
bytes.push(parseInt(hex.substr(c, 2), 16)); | ||
return bytes; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { ApiPromise, WsProvider } from "@polkadot/api"; | ||
import { chainUpgrade, chainDummyUpgrade } from "./chain-upgrade"; | ||
|
||
async function connect(apiUrl: string, types: any): Promise<ApiPromise> { | ||
const provider = new WsProvider(apiUrl) | ||
const api = new ApiPromise({ provider, types }) | ||
await api.isReady | ||
return api | ||
} | ||
|
||
export { | ||
connect, | ||
chainUpgrade, | ||
chainDummyUpgrade | ||
} |
Oops, something went wrong.