Skip to content

Commit

Permalink
Make sure validator nodes can find each other (#153)
Browse files Browse the repository at this point in the history
* Add dependencies

* Pass nodeKeys

Generate them as well if needed

* run lint
  • Loading branch information
pepyakin authored Nov 22, 2021
1 parent 0a526b3 commit d62c028
Show file tree
Hide file tree
Showing 8 changed files with 602 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ You can see an example [here](config.json).
- `name`: Must be one of `alice`, `bob`, `charlie`, or `dave`.
- `wsPort`: The websocket port for this node.
- `port`: The TCP port for this node.
- `nodeKey`: a secret key used for generating libp2p peer identifier. Optional.
- `basePath`: The directory used for the blockchain db and other outputs. When unspecified, we use
`--tmp`.
- `flags`: Any additional command line flags you want to add when starting your node.
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"@polkadot/util": "^7.4.1",
"@polkadot/util-crypto": "^7.4.1",
"filter-console": "^0.1.1",
"libp2p-crypto": "^0.20.0",
"peer-id": "^0.15.3",
"yargs": "^15.4.1"
},
"files": [
Expand Down
36 changes: 33 additions & 3 deletions src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import {
changeGenesisConfig,
addGenesisParachain,
addGenesisHrmpChannel,
addBootNodes,
} from "./spec";
import { parachainAccount } from "./parachain";
import { ApiPromise } from "@polkadot/api";
import { randomAsHex } from "@polkadot/util-crypto";

import { resolve } from "path";
import fs from "fs";
Expand All @@ -31,7 +33,9 @@ import type {
HrmpChannelsConfig,
ResolvedLaunchConfig,
} from "./types";
import { type } from "os";
import { keys as libp2pKeys } from "libp2p-crypto";
import { hexAddPrefix, hexStripPrefix, hexToU8a } from "@polkadot/util";
import PeerId from "peer-id";

function loadTypeDef(types: string | object): object {
if (typeof types === "string") {
Expand Down Expand Up @@ -59,6 +63,7 @@ export async function run(config_dir: string, rawConfig: LaunchConfig) {
return;
}
const config = await resolveParachainId(config_dir, rawConfig);
var bootnodes = await generateNodeKeys(config);

const relay_chain_bin = resolve(config_dir, config.relaychain.bin);
if (!fs.existsSync(relay_chain_bin)) {
Expand All @@ -84,15 +89,16 @@ export async function run(config_dir: string, rawConfig: LaunchConfig) {
if (config.hrmpChannels) {
await addHrmpChannelsToGenesis(`${chain}.json`, config.hrmpChannels);
}
addBootNodes(`${chain}.json`, bootnodes);
// -- End Chain Spec Modify --
await generateChainSpecRaw(relay_chain_bin, chain);
const spec = resolve(`${chain}-raw.json`);

// First we launch each of the validators for the relay chain.
for (const node of config.relaychain.nodes) {
const { name, wsPort, rpcPort, port, flags, basePath } = node;
const { name, wsPort, rpcPort, port, flags, basePath, nodeKey } = node;
console.log(
`Starting Relaychain Node ${name}... wsPort: ${wsPort} rpcPort: ${rpcPort} port: ${port}`
`Starting Relaychain Node ${name}... wsPort: ${wsPort} rpcPort: ${rpcPort} port: ${port} nodeKey: ${nodeKey}`
);
// We spawn a `child_process` starting a node, and then wait until we
// able to connect to it using PolkadotJS in order to know its running.
Expand All @@ -102,6 +108,7 @@ export async function run(config_dir: string, rawConfig: LaunchConfig) {
wsPort,
rpcPort,
port,
nodeKey!, // by the time the control flow gets here it should be assigned.
spec,
flags,
basePath
Expand Down Expand Up @@ -277,3 +284,26 @@ async function resolveParachainId(
}
return resolvedConfig;
}

async function generateNodeKeys(
config: ResolvedLaunchConfig
): Promise<string[]> {
var bootnodes = [];
for (const node of config.relaychain.nodes) {
if (!node.nodeKey) {
node.nodeKey = hexStripPrefix(randomAsHex(32));
}

let pair = await libp2pKeys.generateKeyPairFromSeed(
"Ed25519",
hexToU8a(hexAddPrefix(node.nodeKey!)),
1024
);
let peerId: PeerId = await PeerId.createFromPrivKey(pair.bytes);
bootnodes.push(
`/ip4/127.0.0.1/tcp/${node.port}/p2p/${peerId.toB58String()}`
);
}

return bootnodes;
}
2 changes: 2 additions & 0 deletions src/spawn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export function startNode(
wsPort: number,
rpcPort: number | undefined,
port: number,
nodeKey: string,
spec: string,
flags?: string[],
basePath?: string
Expand All @@ -109,6 +110,7 @@ export function startNode(
"--chain=" + spec,
"--ws-port=" + wsPort,
"--port=" + port,
"--node-key=" + nodeKey,
"--" + name.toLowerCase(),
];
if (rpcPort) {
Expand Down
9 changes: 9 additions & 0 deletions src/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,12 @@ function findAndReplaceConfig(obj1: any, obj2: any) {
}
});
}

export async function addBootNodes(spec: any, addresses: any) {
let rawdata = fs.readFileSync(spec);
let chainSpec = JSON.parse(rawdata);
chainSpec.bootNodes = addresses;
let data = JSON.stringify(chainSpec, null, 2);
fs.writeFileSync(spec, data);
console.log(`Added Boot Nodes: ${addresses}`);
}
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface RelayChainConfig {
basePath?: string;
wsPort: number;
rpcPort?: number;
nodeKey?: string;
port: number;
flags?: string[];
}[];
Expand Down
Loading

0 comments on commit d62c028

Please sign in to comment.