diff --git a/parachain/parachain.star b/parachain/parachain.star index 59726b3..53861bf 100644 --- a/parachain/parachain.star +++ b/parachain/parachain.star @@ -45,3 +45,4 @@ def start_nodes(plan, args, relay_chain_ip): for parachain in parachains: para_id = register_para_slot.register_para_id(plan, relay_chain_ip) start_local_parachain_node(plan, parachain, para_id) + register_para_slot.onboard_genesis_state_and_wasm(plan, para_id, parachain) diff --git a/parachain/register-para-id.star b/parachain/register-para-id.star index bd7b6e7..8b24a0f 100644 --- a/parachain/register-para-id.star +++ b/parachain/register-para-id.star @@ -9,3 +9,20 @@ def register_para_id(plan, alice_ip): para_id = plan.exec(service_name = test.name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "cat /tmp/para.json | tr -d '\n\r'"])) return para_id["output"] + +def onboard_genesis_state_and_wasm(plan, para_id, chain_name): + service = plan.add_service( + name = "upload-genesis-file", + config = ServiceConfig( + image = constant.NODE_IMAGE, + files = { + "/app": "configs", + "/build": constant.RAW_BUILD_SPEC, + "/javascript": "javascript", + }, + entrypoint = ["/bin/sh"], + ), + ) + + plan.exec(service_name = service.name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "cd /javascript && npm i "])) + plan.exec(service_name = service.name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "cd /javascript && node onboard ws://{0}:9944 //Alice {1} /build/{2}-genesis-state /build/{2}-genesis-wasm".format(alice_ip, para_id, chain_name)])) diff --git a/parachain/static_files/javascript/onboard.js b/parachain/static_files/javascript/onboard.js new file mode 100644 index 0000000..d7aa9c2 --- /dev/null +++ b/parachain/static_files/javascript/onboard.js @@ -0,0 +1,69 @@ +const { ApiPromise, WsProvider, Keyring } = require("@polkadot/api"); +const fs = require("fs"); + +const run = async () => { + try { + console.log("Parsing Args ..."); + // 0 & 1 are command context + const endpoint = process.argv[2]; + const seed = process.argv[3]; + const id = process.argv[4]; + const header = process.argv[5]; + const wasmFile = process.argv[6]; + + const wsProvider = new WsProvider(endpoint); + + const api = await ApiPromise.create({ + provider: wsProvider, + }); + + const keyring = new Keyring({ type: "sr25519" }); + const alice = keyring.addFromUri(seed); + + let wasm; + try { + wasm = fs.readFileSync(wasmFile, "utf8"); + } catch (err) { + console.error(err); + throw err; + } + + let paraGenesisArgs = { + genesis_head: header, + validation_code: wasm, + parachain: true, + }; + + let genesis = api.createType("ParaGenesisArgs", paraGenesisArgs); + + const nonce = Number((await api.query.system.account(alice.address)).nonce); + + console.log( + `--- Submitting extrinsic to register parachain ${id}. (nonce: ${nonce}) ---` + ); + const sudoCall = await api.tx.sudo + .sudo(api.tx.parasSudoWrapper.sudoScheduleParaInitialize(id, genesis)) + .signAndSend(alice, { nonce: nonce, era: 0 }, (result) => { + console.log(`Current status is ${result.status}`); + if (result.status.isInBlock) { + console.log( + `Transaction included at blockHash ${result.status.asInBlock}` + ); + console.log("Waiting for finalization..."); + } else if (result.status.isFinalized) { + console.log( + `Transaction finalized at blockHash ${result.status.asFinalized}` + ); + sudoCall(); + process.exit(); + } else if (result.isError) { + console.log(`Transaction Error`); + process.exit(); + } + }); + } catch (error) { + console.log("error:", error); + } +}; + +run(); diff --git a/parachain/static_files/javascript/package.json b/parachain/static_files/javascript/package.json index edad65e..bf7b53f 100644 --- a/parachain/static_files/javascript/package.json +++ b/parachain/static_files/javascript/package.json @@ -4,7 +4,8 @@ "description": "", "main": "index.js", "scripts": { - "register": "node register.js" + "register": "node register.js", + "onboard": "node onboard.js" }, "keywords": [], "dependencies": {