Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 10 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
{
"editor.formatOnSave": true
"editor.formatOnSave": false,
"editor.formatOnPaste": false,
"[javascript]": {
"editor.formatOnSave": false
},
"editor.codeActionsOnSave": {
"source.fixAll": "never",
"source.fixAll.eslint": "never"
},
"standard.autoFixOnSave": false
}
3 changes: 2 additions & 1 deletion bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

const prog = require('caporal')
const register = require('../src/commands')
const package = require('../package.json')

prog
.bin('shardus-network')
.name('Shardus Network')
.version('1.0.0')
.version(package.version)

for (const command in register) {
register[command](prog)
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shardus/network-tool",
"version": "4.4.0",
"version": "4.4.1",
"description": "Tool for managing a Shardus test network",
"main": "index.js",
"scripts": {
Expand Down
11 changes: 5 additions & 6 deletions src/actions/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,9 @@ module.exports = async function (args, options, logger) {
await create(networkDir, networkConfig, num, args.pm2)

if (!options['noLogRotation']) {
await util.pm2InstallRotateLog(networkDir)
await util.pm2SetRotateLog(networkDir)
const logSize = options.logSizeMb || networkConfig.logSize || defaultNetwork.logSize
const logNum = options.logNum || networkConfig.logNum || defaultNetwork.logNum
await util.pm2SetupLogRotation(networkDir, logSize, logNum)
}
if (options['noStart'] === false) {
start(networkDir, num, 'start', args.pm2)
Expand Down Expand Up @@ -272,8 +273,7 @@ module.exports = async function (args, options, logger) {
await create(networkDir, config)

if (!options['noLogRotation']) {
await util.pm2InstallRotateLog(networkDir)
await util.pm2SetRotateLog(networkDir, options.logSizeMb, options.logSize)
await util.pm2SetupLogRotation(networkDir, config.logSize, config.logNum)
}
if (options['noStart'] === false) {
start(networkDir, num, 'create', args.pm2, options)
Expand All @@ -285,8 +285,7 @@ module.exports = async function (args, options, logger) {
inquirer.prompt(questions).then(async (answers) => {
await create(networkDir, answers)
if (!options['noLogRotation']) {
await util.pm2InstallRotateLog(networkDir)
await util.pm2SetRotateLog(networkDir, answers.logSize, answers.logNum)
await util.pm2SetupLogRotation(networkDir, answers.logSize, answers.logNum)
}
if (options['noStart'] === false) {
start(networkDir, num, 'create', args.pm2, options)
Expand Down
12 changes: 11 additions & 1 deletion src/actions/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ const util = require('../lib/util')
const create = require('../actions/create')
const fs = require('fs')

module.exports = function (args, options, logger) {
module.exports = async function (args, options, logger) {
try {
const networkDir = util.setNetworkDirOrErr(options.dir)
const configPath = path.join(networkDir, 'network-config.json')

// Setup logrotate if network exists and logrotate not disabled
if (fs.existsSync(configPath) && !options['noLogRotation']) {
const networkConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'))
const logSize = options.logSizeMb || networkConfig.logSize || 10
const logNum = options.logNum || networkConfig.logNum || 10
await util.pm2SetupLogRotation(networkDir, logSize, logNum)
}

start(networkDir, parseInt(args.num), 'create', args.pm2, options)
} catch (err) {
create(args, Object.assign(options, { noStart: false }), logger)
Expand Down
25 changes: 18 additions & 7 deletions src/lib/restart.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,20 @@ module.exports = async function (networkDir, options, args) {
activeArchiversCalculated = true
}

const restartPromises = []
for (let i = 0; i < count; i++) {
port = stoppedArchivers[i].port - 4000;
console.log("archive-server-" + (port + 1));
newArchiversInfo.push({ ip: stoppedArchivers[i].ip, port: stoppedArchivers[i].port, publicKey: stoppedArchivers[i].publicKey })
await util.pm2Restart(networkDir, `"archive-server-${port + 1}"`, {
restartPromises.push(util.pm2Restart(networkDir, `"archive-server-${port + 1}"`, {
ARCHIVER_PORT: stoppedArchivers[i].port,
ARCHIVER_PUBLIC_KEY: stoppedArchivers[i].publicKey,
ARCHIVER_SECRET_KEY: archiverKeys[port].secretKey,
ARCHIVER_INFO: activeArchiversEnv,
ARCHIVER_DB: `archiver-db-${stoppedArchivers[i].port}`,
});
}))
}
await Promise.all(restartPromises)
}

if (existingArchivers.length > 0) {
Expand All @@ -77,20 +79,22 @@ module.exports = async function (networkDir, options, args) {
activeArchiversEnv = activeArchivers.map((archiver) => `${archiver.ip}:${archiver.port}:${archiver.publicKey}`).join(',')
activeArchiversCalculated = true
}
// Restart archivers on ports following existingArchivers
// Restart archivers on ports following existingArchivers (parallel)
const archiverRestartPromises = []
for (let i = 0; i < restartArchiverCount; i++) {
port = existingArchivers[i].port - 4000;
console.log("archive-server-" + (port + 1));
newArchiversInfo.push({ ip: existingArchivers[i].ip, port: existingArchivers[i].port, publicKey: existingArchivers[i].publicKey })
await util.pm2Restart(networkDir, `"archive-server-${port + 1}"`, {
archiverRestartPromises.push(util.pm2Restart(networkDir, `"archive-server-${port + 1}"`, {
ARCHIVER_PORT: existingArchivers[i].port,
ARCHIVER_PUBLIC_KEY: existingArchivers[i].publicKey,
ARCHIVER_SECRET_KEY: archiverKeys[port].secretKey,
ARCHIVER_INFO: activeArchiversEnv,
ARCHIVER_DB: `archiver-db-${existingArchivers[i].port}`,
});
}))
port++;
}
await Promise.all(archiverRestartPromises)
}
activeArchivers = [...activeArchivers, ...newArchiversInfo]
activeArchivers.sort((a, b) => a.port - b.port)
Expand Down Expand Up @@ -147,20 +151,27 @@ module.exports = async function (networkDir, options, args) {
if (networkConfig.stoppedConsensors)
stoppedConsensors = networkConfig.stoppedConsensors;
else stoppedConsensors = [];
const consensorRestartPromises = []
for (let i = 0; i < restartConsensorCount; i++) {
await util.pm2Restart(networkDir, `"shardus-instance-${lowestPort}"`);
consensorRestartPromises.push(util.pm2Restart(networkDir, `"shardus-instance-${lowestPort}"`))
networkConfig.runningPorts.push(lowestPort);
}
await Promise.all(consensorRestartPromises)
const portRestartPromises = []
networkConfig.runningPorts.forEach((port) => {
if (num > 0) {
util.pm2Restart(networkDir, `"shardus-instance-${port}"`);
portRestartPromises.push(util.pm2Restart(networkDir, `"shardus-instance-${port}"`))
networkConfig.runningPorts = networkConfig.runningPorts.filter(
(p) => p !== port
);
stoppedConsensors.push(port);
}
num--;
});
await Promise.all(portRestartPromises)
if (portRestartPromises.length > 0) {
console.log(`✓ Restarted ${portRestartPromises.length} node(s)`)
}
networkConfig.stoppedConsensors = stoppedConsensors;
}
shell.ShellString(JSON.stringify(networkConfig, null, 2)).to(`network-config.json`)
Expand Down
85 changes: 58 additions & 27 deletions src/lib/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,20 @@ const path = require('path')
const util = require('./util')
const archiverKeys = require('../configs/archiver-config')

module.exports = async function (networkDir, num, type, pm2Args, options) {
module.exports = async function (networkDir, num, type, pm2Args, options = {}) {
// Resolve archiver and monitor paths BEFORE changing directory
const projectRoot = path.dirname(networkDir)
const archiverPath = require.resolve('@shardus/archiver', { paths: [projectRoot] })
const monitorPath = require.resolve('@shardus/monitor-server', { paths: [projectRoot] })

// Resolve explorer path (may not exist in all projects)
let explorerPath
try {
explorerPath = require.resolve('explorer-server', { paths: [projectRoot] })
} catch (e) {
// Explorer not installed, that's ok
}

shell.cd(networkDir)
const instancesPath = path.join(process.cwd())
const configPath = path.join(instancesPath, 'network-config.json')
Expand All @@ -28,22 +41,26 @@ module.exports = async function (networkDir, num, type, pm2Args, options) {
if (newArchiverCount > 9) newArchiverCount = 9

const existingArchiversEnv = existingArchivers.map((archiver) => `${archiver.ip}:${archiver.port}:${archiver.publicKey}`).join(',')
// Start new archivers on ports following existingArchivers
// Start new archivers on ports following existingArchivers (parallel)
const archiverStarts = []
for (let i = 0; i < newArchiverCount; i++) {
await util.pm2Start(
networkDir,
require.resolve('@shardus/archiver', { paths: [process.cwd()] }),
`archive-server-${i + 1 + existingArchivers.length}`,
{
ARCHIVER_PORT: existingArchivers[0].port + existingArchivers.length + i,
ARCHIVER_PUBLIC_KEY: archiverKeys[existingArchivers.length + i].publicKey,
ARCHIVER_SECRET_KEY: archiverKeys[existingArchivers.length + i].secretKey,
ARCHIVER_INFO: existingArchiversEnv,
ARCHIVER_DB: `archiver-db-${archiverKeys[existingArchivers.length + i].port}`
},
pm2Args
archiverStarts.push(
util.pm2Start(
networkDir,
archiverPath,
`archive-server-${i + 1 + existingArchivers.length}`,
{
ARCHIVER_PORT: existingArchivers[0].port + existingArchivers.length + i,
ARCHIVER_PUBLIC_KEY: archiverKeys[existingArchivers.length + i].publicKey,
ARCHIVER_SECRET_KEY: archiverKeys[existingArchivers.length + i].secretKey,
ARCHIVER_INFO: existingArchiversEnv,
ARCHIVER_DB: `archiver-db-${archiverKeys[existingArchivers.length + i].port}`
},
pm2Args
)
)
}
await Promise.all(archiverStarts)

// Add the newly started archivers to network-config.json existingArchivers
for (let i = 1; i <= newArchiverCount; i++) {
Expand All @@ -55,13 +72,13 @@ module.exports = async function (networkDir, num, type, pm2Args, options) {
return
}

// Start archiver
// Start archiver first (monitor needs it ready)
if (networkConfig.startArchiver) {
const existingArchivers = JSON.parse(networkConfig.existingArchivers)

await util.pm2Start(
networkDir,
require.resolve('@shardus/archiver', { paths: [process.cwd()] }),
archiverPath,
`archive-server-1`,
{
ARCHIVER_PORT: existingArchivers[0].port,
Expand All @@ -74,17 +91,18 @@ module.exports = async function (networkDir, num, type, pm2Args, options) {
)

networkConfig.startArchiver = false // Prevent this code from running twice

await util.sleep(1000) // Add 1sec delay to allow archiver to be ready, so that monitor can connect it with archiver discovery

// Small delay to allow archiver to be ready for monitor
await util.sleep(1000)
}

// Start monitor
// Start monitor (needs archiver to be ready)
if (networkConfig.startMonitor) {
let existingArchivers = JSON.parse(networkConfig.existingArchivers)
const existingArchiversEnv = existingArchivers.map((archiver) => `${archiver.ip}:${archiver.port}:${archiver.publicKey}`).join(',')
await util.pm2Start(
networkDir,
require.resolve("@shardus/monitor-server", { paths: [process.cwd()] }),
monitorPath,
"monitor-server",
{
PORT: new URL(networkConfig.monitorUrl).port,
Expand All @@ -98,11 +116,11 @@ module.exports = async function (networkDir, num, type, pm2Args, options) {
networkConfig.startMonitor = false; // Prevent this code from running twice
}

// Start explorer
if (networkConfig.startExplorerServer) {
// Start explorer (can be parallel with nodes)
if (networkConfig.startExplorerServer && explorerPath) {
await util.pm2Start(
networkDir,
require.resolve('explorer-server', { paths: [process.cwd()] }),
explorerPath,
'explorer-server',
{ PORT: networkConfig.explorerServerPort },
pm2Args
Expand All @@ -117,14 +135,20 @@ module.exports = async function (networkDir, num, type, pm2Args, options) {
console.log(err)
}

// Start all validator nodes in parallel (don't wait - fire and forget for speed)
if (type === 'create') {
console.log(`Starting ${nodesToStart} validator nodes in parallel...`)
for (let i = 0; i < nodesToStart; i++) {
if (!networkConfig.runningPorts.includes(networkConfig.lowestPort + i)) {
if (instances[i]) {
if (options?.inspect) {
await util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, [`pm2--node-args="--inspect=127.0.0.1:${networkConfig.inspectPort + i}"`, ...pm2Args])
util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, [`pm2--node-args="--inspect=127.0.0.1:${networkConfig.inspectPort + i}"`, ...pm2Args]).catch(err => {
console.error(`Error starting ${path.basename(instances[i])}:`, err.message)
})
} else {
await util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, pm2Args)
util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, pm2Args).catch(err => {
console.error(`Error starting ${path.basename(instances[i])}:`, err.message)
})
}
networkConfig.runningPorts.push(networkConfig.lowestPort + i)
}
Expand All @@ -135,16 +159,23 @@ module.exports = async function (networkDir, num, type, pm2Args, options) {
}

if (type === 'start') {
console.log(`Starting ${num} validator nodes in parallel...`)
for (let i = instances.length - num; i < instances.length; i++) {
if (options?.inspect) {
await util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, [`pm2--node-args="--inspect=127.0.0.1:${networkConfig.inspectPort + i}"`, ...pm2Args])
util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, [`pm2--node-args="--inspect=127.0.0.1:${networkConfig.inspectPort + i}"`, ...pm2Args]).catch(err => {
console.error(`Error starting ${path.basename(instances[i])}:`, err.message)
})
} else {
await util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, pm2Args)
util.pm2Start(networkDir, networkConfig.serverPath, path.basename(instances[i]), { BASE_DIR: instances[i] }, pm2Args).catch(err => {
console.error(`Error starting ${path.basename(instances[i])}:`, err.message)
})
}
let port = parseInt(instances[i].split('-').pop())
networkConfig.runningPorts.push(port)
}
}

console.log(`✓ Validator nodes starting (check with 'shardus pm2 list')`)

shell.ShellString(JSON.stringify(networkConfig, null, 2)).to(`network-config.json`)

Expand Down
23 changes: 17 additions & 6 deletions src/lib/stop.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ module.exports = async function (networkDir, num, options) {

if (existingArchivers.length > stopArchiverCount) {
const activeArchivers = existingArchivers.slice(stopArchiverCount, existingArchivers.length)
// Stop archivers on ports following existingArchivers
// Stop archivers on ports following existingArchivers (parallel)
const archiverStops = []
for (let i = 0; i < stopArchiverCount; i++) {
await util.pm2Stop(
networkDir,
`"archive-server-${stoppedArchiversCount + 1}"`
archiverStops.push(
util.pm2Stop(
networkDir,
`"archive-server-${stoppedArchiversCount + 1}"`
)
)
stoppedArchivers.push(existingArchivers[i])
stoppedArchiversCount++
}
await Promise.all(archiverStops)
activeArchivers.sort((a, b) => a.port - b.port)
networkConfig.existingArchivers = JSON.stringify(activeArchivers)
networkConfig.stoppedArchivers = JSON.stringify(stoppedArchivers)
Expand Down Expand Up @@ -73,17 +77,24 @@ module.exports = async function (networkDir, num, options) {
stoppedConsensors = networkConfig.stoppedConsensors
else
stoppedConsensors = []

// Stop nodes in parallel for speed
const nodeStops = []
networkConfig.runningPorts.forEach(port => {
if (num > 0) {
util.pm2Stop(networkDir, `"shardus-instance-${port}"`)
nodeStops.push(util.pm2Stop(networkDir, `"shardus-instance-${port}"`))
networkConfig.runningPorts = networkConfig.runningPorts.filter(p => p !== port)
stoppedConsensors.push(port)
}
num--
})
await Promise.all(nodeStops)
console.log(`✓ Stopped ${nodeStops.length} node(s)`)
networkConfig.stoppedConsensors = stoppedConsensors
} else {
util.pm2Stop(networkDir, 'all')
console.log('Stopping all processes...')
await util.pm2Stop(networkDir, 'all')
console.log('✓ All processes stopped')
networkConfig.runningPorts = []
networkConfig.startArchiver = true
networkConfig.startMonitor = true
Expand Down
Loading
Loading