Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement add custom sudo key for parachain #204

Merged
merged 18 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
9ae9205
fix: fix issue for robonomics mainnet relay not showing blocks
abhiyana Feb 8, 2024
46c1a95
fix: fix issue litentry parachain testnet not showing blocks
abhiyana Feb 8, 2024
16f4d4b
fix: kilt issue and acala karura testnet issue
abhiyana Feb 8, 2024
3594e1a
fix: acala, karura testnet issue
abhiyana Feb 8, 2024
04667d6
chore: change base for manta parachain
abhiyana Feb 8, 2024
a7f7061
feat: implement add custom sudo key for parachain
abhiyana Feb 9, 2024
4d53579
Merge branch 'main' of https://github.com/HugoByte/polkadot-kurtosis-…
abhiyana Feb 9, 2024
0a7c25d
refactor: change insert_keys function, from js script to curl command
abhiyana Feb 9, 2024
b5bb6ee
chore: code clean in parachain.star
abhiyana Feb 9, 2024
ec8f034
refactor: change insertkey function from curl to js script
abhiyana Feb 9, 2024
fa93a27
chore: updated the config.json
abhiyana Feb 9, 2024
ada835c
refactor: refactor the insert_keys function parameter
abhiyana Feb 9, 2024
9eafea5
refactor: refactor config.json, change sudo_key key position
abhiyana Feb 9, 2024
32be31c
feat: add functionality to add sepate key wallet for each node
abhiyana Feb 9, 2024
976cf19
refactor: refactor code in parachain.star, nodes can start with and w…
abhiyana Feb 9, 2024
42c899b
refactor: update script to update parachain spec
abhiyana Feb 12, 2024
f5b940f
fix: fix issue if sudo_key, key is not provided in config then it thr…
abhiyana Feb 13, 2024
e44b749
fix: issue with sudo key while without registratioon is true
shanithkk Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 20 additions & 23 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,43 @@
{
"name": "bob",
"node_type": "validator",
"prometheus": true
"prometheus": false

}
]
},

"parachains": [
{
"name":"acala",
"nodes": [
{
"name": "alice",
"node_type": "validator",
"prometheus": false

},
{
"name": "bob",
"node_type": "full",
"prometheus": true
}
]
},
{
"name":"frequency",
"nodes": [
{
"name": "alice",
"node_type": "validator",
"prometheus": false
"node_type": "collator",
"prometheus": false,
"key":{
"private_phrase":"dizzy rose offer wall social glory debris gift govern seminar almost bicycle" ,
"public_key":"5G3vA9UC6J7hPN5Jqfiz4qFNqYAfahHxffbuQf6dcZZx3Yx6"
}

},
{
"name": "bob",
"node_type": "full",
"prometheus": true
"prometheus": false,
"key": {
"private_phrase":"diamond crane pioneer aisle conduct media news cup price olive dust light" ,
"public_key":"5GgwsM48CCT7oPUyFTTpE5L1t7Fjpe7D8SDNKxJxug15YEKy"
}
}
]
],
"sudo_key": {
shanithkk marked this conversation as resolved.
Show resolved Hide resolved
"private_phrase":"dizzy rose offer wall social glory debris gift govern seminar almost bicycle" ,
"public_key":"5G3vA9UC6J7hPN5Jqfiz4qFNqYAfahHxffbuQf6dcZZx3Yx6"
abhiyana marked this conversation as resolved.
Show resolved Hide resolved
}
}
],
"explorer": true,
"without_registration" : true

"explorer": false,
"without_registration" : false
}
6 changes: 3 additions & 3 deletions main.star
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ utils = import_module("./package_io/utils.star")
constant = import_module("./package_io/constant.star")
parachain_without_registration = import_module("./parachain/parachain_without_registration.star")

def run(plan, chain_type = "localnet", relaychain = None, parachains = None, explorer = False, without_registration = False):
def run(plan, chain_type = "localnet", relaychain = None, parachains = None, explorer = False, without_registration = False, sudo_key=None):
"""
Main function to run the Polkadot relay and parachain setup.

Expand All @@ -31,10 +31,10 @@ def run(plan, chain_type = "localnet", relaychain = None, parachains = None, exp
Returns:
service_details (json): Service details containing information about relay chains, parachains, and Prometheus.
"""
service_details = run_polkadot_setup(plan, chain_type, relaychain, parachains, explorer, without_registration)
service_details = run_polkadot_setup(plan, chain_type, relaychain, parachains, explorer, without_registration, sudo_key)
return service_details

def run_polkadot_setup(plan, chain_type, relaychain, parachains, explorer, without_registration):
def run_polkadot_setup(plan, chain_type, relaychain, parachains, explorer, without_registration, sudo_key):
"""
Main function to run the Polkadot relay and parachain setup.

Expand Down
14 changes: 10 additions & 4 deletions parachain/build-spec.star
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
build_spec = import_module("../package_io/build-spec.star")
constant = import_module("../package_io/constant.star")

def create_parachain_build_spec_with_para_id(plan, image, binary, chain_name, chain_base, para_id):
def create_parachain_build_spec_with_para_id(plan, image, binary, chain_name, chain_base, para_id, sudo_key, collators_keys):
files = {
"/app": "configs",
}
Expand All @@ -16,13 +16,19 @@ def create_parachain_build_spec_with_para_id(plan, image, binary, chain_name, ch
files = {
"/app": "configs",
"/build": chain_name + "plain",
"/javascript": "javascript",
}


run_command = "cd /javascript && npm i && node edit_parachain_plain.js /build/{0}.json {1} \"{2}\" \'{3}\'".format(chain_name, para_id, sudo_key, collators_keys)
plan.print(run_command)
plan.run_sh(
run = "sed -e 's/\"parachainId\": *[0-9]\\+/\"parachainId\": {0}/' -e 's/\"para_id\": [0-9]*,/\"para_id\": {0},/' -e 's/\"paraId\": [0-9]*,/\"paraId\": {0},/' -e 's/\"parachain_id\": [0-9]*,/\"parachain_id\": {0},/' /build/{1}.json > /tmp/{1}.json".format(para_id, chain_name),
image = constant.CURL_JQ_IMAGE,
run = run_command,
image = constant.NODE_IMAGE,
files = files,
store = [StoreSpec(src = "/tmp/{0}.json".format(chain_name), name = chain_name + "edit")],
store = [StoreSpec(src = "/build/{0}.json".format(chain_name), name = chain_name + "edit")],
)


raw_service = create_raw_build_spec_genisis_state_genisis_wasm_for_parachain(plan, binary, image, chain_name)

Expand Down
60 changes: 49 additions & 11 deletions parachain/parachain.star
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ def start_local_parachain_node(plan, chain_type, parachain, para_id):
image = parachain_details["image"]
binary = parachain_details["entrypoint"]
chain_base = parachain_details["base"][0]
raw_service = build_spec.create_parachain_build_spec_with_para_id(plan, image, binary, chain_name, chain_base, para_id)

sudo_key = ""
if len(parachain["sudo_key"]) != 0:
sudo_key = parachain["sudo_key"]["public_key"]

public_keys = [node.get("key", {}).get("public_key", "") for node in parachain["nodes"] if node.get("key")]
collators_keys = "[" + ", ".join(["\"{}\"".format(key) for key in public_keys]) + "]"

raw_service = build_spec.create_parachain_build_spec_with_para_id(plan, image, binary, chain_name, chain_base, para_id, sudo_key, collators_keys)

parachain_final = {}

Expand All @@ -41,17 +49,32 @@ def start_local_parachain_node(plan, chain_type, parachain, para_id):
ws_port = None

if chain_name in constant.WS_PORT:
exec_comexec_commandmand = [
"/bin/bash",
"-c",
"{0} --base-path=/tmp/{1} --chain=/build/{1}-raw.json --ws-port=9944 --port=30333 --rpc-port=9947 --ws-external --rpc-external --prometheus-external --rpc-cors=all --{2} --collator --rpc-methods=unsafe --force-authoring --execution=wasm -- --chain=/app/raw-polkadot.json --execution=wasm".format(binary, chain_name, node["name"]),
]
if len(node["key"]) != 0:
exec_comexec_commandmand = [
"/bin/bash",
"-c",
"{0} --base-path=/tmp/{1} --chain=/build/{1}-raw.json --ws-port=9944 --port=30333 --rpc-port=9947 --ws-external --rpc-external --prometheus-external --rpc-cors=all --name={2} --collator --rpc-methods=unsafe --force-authoring --execution=wasm -- --chain=/app/raw-polkadot.json --execution=wasm".format(binary, chain_name, node["name"]),
]
else:
exec_comexec_commandmand = [
"/bin/bash",
"-c",
"{0} --base-path=/tmp/{1} --chain=/build/{1}-raw.json --ws-port=9944 --port=30333 --rpc-port=9947 --ws-external --rpc-external --prometheus-external --rpc-cors=all --{2} --collator --rpc-methods=unsafe --force-authoring --execution=wasm -- --chain=/app/raw-polkadot.json --execution=wasm".format(binary, chain_name, node["name"]),
]
else:
exec_comexec_commandmand = [
"/bin/bash",
"-c",
"{0} --base-path=/tmp/{1} --chain=/build/{1}-raw.json --rpc-port=9947 --port=30333 --rpc-external --rpc-cors=all --prometheus-external --{2} --collator --rpc-methods=unsafe --force-authoring --execution=wasm -- --chain=/app/raw-polkadot.json --execution=wasm".format(binary, chain_name, node["name"]),
]
if len(node["key"]) != 0:
exec_comexec_commandmand = [
"/bin/bash",
"-c",
"{0} --base-path=/tmp/{1} --chain=/build/{1}-raw.json --rpc-port=9947 --port=30333 --rpc-external --rpc-cors=all --prometheus-external --name={2} --collator --rpc-methods=unsafe --force-authoring --execution=wasm -- --chain=/app/raw-polkadot.json --execution=wasm".format(binary, chain_name, node["name"]),
]
else:
exec_comexec_commandmand = [
"/bin/bash",
"-c",
"{0} --base-path=/tmp/{1} --chain=/build/{1}-raw.json --rpc-port=9947 --port=30333 --rpc-external --rpc-cors=all --prometheus-external --{2} --collator --rpc-methods=unsafe --force-authoring --execution=wasm -- --chain=/app/raw-polkadot.json --execution=wasm".format(binary, chain_name, node["name"]),
]


build_file = raw_service
parachain_spawn_detail = node_setup.spawn_parachain(plan, node["prometheus"], image, parachain["name"], "{0}-{1}-{2}".format(chain_name, node["name"], chain_type), exec_comexec_commandmand, build_file, rpc_port, prometheus_port, lib2lib_port, ws_port)
Expand All @@ -72,6 +95,8 @@ def start_local_parachain_node(plan, chain_type, parachain, para_id):

parachain_final[parachain_spawn_detail.name] = parachain_detail

if len(node["key"]) != 0:
insert_keys(plan, "aura", node["key"]["private_phrase"], parachain_detail["endpoint"])
return parachain_final

def start_nodes(plan, chain_type, parachains, relay_chain_ip):
Expand Down Expand Up @@ -239,3 +264,16 @@ def run_testnet_mainnet(plan, chain_type, relaychain_name, parachain):

final_parachain_info[node_details.name] = node_info
return final_parachain_info



def insert_keys(plan, key_type, private_phrase, uri):
files = {
"/javascript": "javascript",
}

plan.run_sh(
run = 'cd /javascript && npm i && node insert_key.js "{0}" "{1}" "{2}"'.format(key_type, private_phrase, uri),
image = constant.NODE_IMAGE,
files = files,
)
68 changes: 68 additions & 0 deletions parachain/static_files/javascript/edit_parachain_plain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const fs = require("fs");

function updateParachainSpec(PARA_SPEC_FILE, PARA_ID, NEW_SUDO_KEY, INITIAL_COLLATORS) {
shreyasbhat0 marked this conversation as resolved.
Show resolved Hide resolved
try {
const rawdata = fs.readFileSync(PARA_SPEC_FILE);
shreyasbhat0 marked this conversation as resolved.
Show resolved Hide resolved
const chainSpec = JSON.parse(rawdata);
const collators = JSON.parse(INITIAL_COLLATORS);

chainSpec.para_id = PARA_ID;
chainSpec.genesis.runtime.parachainInfo.parachainId = PARA_ID;


if (NEW_SUDO_KEY.length > 0) {
chainSpec.genesis.runtime.sudo.key = NEW_SUDO_KEY;

const SESSION_KEYS = [
NEW_SUDO_KEY,
NEW_SUDO_KEY,
{ aura: NEW_SUDO_KEY }
];
chainSpec.genesis.runtime.session.keys.push(SESSION_KEYS);

const BALANCE = [
NEW_SUDO_KEY,
chainSpec.genesis.runtime.balances.balances[0][1]
];
chainSpec.genesis.runtime.balances.balances.push(BALANCE);
console.log("changed sudo key:", NEW_SUDO_KEY);
}

if (collators.length > 0) {
collators.forEach(collator => {
//adding this condition to prevent adding duplicate keys
if(collator!=NEW_SUDO_KEY){
console.log("updating collator:", collator);
const sessionKey = [
collator,
collator,
{ aura: collator }
];
chainSpec.genesis.runtime.session.keys.push(sessionKey);

const balance = [
collator,
chainSpec.genesis.runtime.balances.balances[0][1]
];
chainSpec.genesis.runtime.balances.balances.push(balance);

chainSpec.genesis.runtime.collatorSelection.invulnerables.push(collator);
} else{
chainSpec.genesis.runtime.collatorSelection.invulnerables.push(collator);
}
});
}

fs.writeFileSync(PARA_SPEC_FILE, JSON.stringify(chainSpec, null, 2));

console.log("✓ Updated sudo key and session keys in parachain spec");
} catch (error) {
console.error("Error updating parachain spec:", error.message);
}
}

const paraSpecFile = process.argv[2];
const paraId = parseInt(process.argv[3], 10) || 2000;
const newSudoKey = process.argv[4];
const initialCollators = process.argv[5];
updateParachainSpec(paraSpecFile, paraId, newSudoKey, initialCollators);
37 changes: 37 additions & 0 deletions parachain/static_files/javascript/insert_key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api');
const { encodeAddress } = require('@polkadot/util-crypto');
const { createType } = require('@polkadot/types');
const { u8aToHex } =require("@polkadot/util")
const { decodeAddress } = require("@polkadot/util-crypto")



async function insertKey(keyType, mnemonicOrPrivateKey, providerUrl) {
try {
const wsProvider = new WsProvider(providerUrl);
const api = await ApiPromise.create({ provider: wsProvider });
const keyring = new Keyring({ type: 'sr25519' });
const account = keyring.addFromMnemonic(mnemonicOrPrivateKey);
const result = await api.rpc.author.insertKey(keyType, mnemonicOrPrivateKey, u8aToHex(decodeAddress(account.address)));
console.log(`Account ${account.address} inserted successfully!`);
return result;
} catch (error) {
console.error('Error inserting account:', error);
throw error;
}
}

const keyType = process.argv[2];
const mnemonicOrPrivateKey = process.argv[3];
const providerUrl = process.argv[4];

(async () => {
try {
await insertKey(keyType, mnemonicOrPrivateKey, providerUrl);
console.log('Script executed successfully!');
process.exit(0);
} catch (error) {
console.error('Error executing script:', error);
process.exit(1);
}
})();
Loading