mirror of
https://github.com/vacp2p/research.git
synced 2026-01-09 13:47:59 -05:00
Makefile and import start network
This commit is contained in:
4
hello_gossipsub/Makefile
Normal file
4
hello_gossipsub/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
all: start_network
|
||||
|
||||
start_network: src/start_network.nim
|
||||
nim c -o:build/start_network src/start_network.nim
|
||||
@@ -7,11 +7,5 @@ license = "MIT"
|
||||
srcDir = "src"
|
||||
bin = @["hello_gossipsub"]
|
||||
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
requires "nim >= 1.2.0"
|
||||
#requires "libp2p"
|
||||
#requires "nimbus"
|
||||
#requires "nim-eth"
|
||||
|
||||
Binary file not shown.
197
hello_gossipsub/src/start_network.nim
Normal file
197
hello_gossipsub/src/start_network.nim
Normal file
@@ -0,0 +1,197 @@
|
||||
import
|
||||
strformat, os, osproc, net, confutils, strformat, chronicles, json, strutils,
|
||||
eth/keys, eth/p2p/enode
|
||||
|
||||
const
|
||||
defaults ="--log-level:DEBUG --log-metrics --metrics-server --rpc"
|
||||
wakuNodeBin = "build" / "wakunode"
|
||||
metricsDir = "waku" / "metrics"
|
||||
portOffset = 2
|
||||
|
||||
type
|
||||
NodeType = enum
|
||||
FullNode = "",
|
||||
LightNode = "--light-node:on",
|
||||
|
||||
Topology = enum
|
||||
Star,
|
||||
FullMesh,
|
||||
DiscoveryBased # Whatever topology the discovery brings
|
||||
|
||||
WakuNetworkConf* = object
|
||||
topology* {.
|
||||
desc: "Set the network topology."
|
||||
defaultValue: Star
|
||||
name: "topology" }: Topology
|
||||
|
||||
amount* {.
|
||||
desc: "Amount of full nodes to be started."
|
||||
defaultValue: 4
|
||||
name: "amount" }: int
|
||||
|
||||
testNodePeers* {.
|
||||
desc: "Amount of peers a test node should connect to."
|
||||
defaultValue: 1
|
||||
name: "test-node-peers" }: int
|
||||
|
||||
NodeInfo* = object
|
||||
cmd: string
|
||||
master: bool
|
||||
enode: string
|
||||
shift: int
|
||||
label: string
|
||||
|
||||
proc initNodeCmd(nodeType: NodeType, shift: int, staticNodes: seq[string] = @[],
|
||||
discovery = false, bootNodes: seq[string] = @[], topicInterest = false,
|
||||
master = false, label: string): NodeInfo =
|
||||
let
|
||||
keypair = KeyPair.random().tryGet()
|
||||
address = Address(ip: parseIpAddress("127.0.0.1"),
|
||||
udpPort: (30303 + shift).Port, tcpPort: (30303 + shift).Port)
|
||||
enode = ENode(pubkey: keypair.pubkey, address: address)
|
||||
|
||||
result.cmd = wakuNodeBin & " " & defaults & " "
|
||||
result.cmd &= $nodeType & " "
|
||||
result.cmd &= "--waku-topic-interest:" & $topicInterest & " "
|
||||
result.cmd &= "--nodekey:" & $keypair.seckey & " "
|
||||
result.cmd &= "--ports-shift:" & $shift & " "
|
||||
if discovery:
|
||||
result.cmd &= "--discovery:on" & " "
|
||||
if bootNodes.len > 0:
|
||||
for bootNode in bootNodes:
|
||||
result.cmd &= "--bootnode:" & bootNode & " "
|
||||
else:
|
||||
result.cmd &= "--discovery:off" & " "
|
||||
if staticNodes.len > 0:
|
||||
for staticNode in staticNodes:
|
||||
result.cmd &= "--staticnode:" & staticNode & " "
|
||||
|
||||
result.master = master
|
||||
result.enode = $enode
|
||||
result.shift = shift
|
||||
result.label = label
|
||||
|
||||
debug "Node command created.", cmd=result.cmd
|
||||
|
||||
proc starNetwork(amount: int): seq[NodeInfo] =
|
||||
let masterNode = initNodeCmd(FullNode, portOffset, master = true,
|
||||
label = "master node")
|
||||
result.add(masterNode)
|
||||
for i in 1..<amount:
|
||||
result.add(initNodeCmd(FullNode, portOffset + i, @[masterNode.enode],
|
||||
label = "full node"))
|
||||
|
||||
proc fullMeshNetwork(amount: int): seq[NodeInfo] =
|
||||
debug "amount", amount
|
||||
for i in 0..<amount:
|
||||
var staticnodes: seq[string]
|
||||
for item in result:
|
||||
staticnodes.add(item.enode)
|
||||
result.add(initNodeCmd(FullNode, portOffset + i, staticnodes,
|
||||
label = "full node"))
|
||||
|
||||
proc discoveryNetwork(amount: int): seq[NodeInfo] =
|
||||
let bootNode = initNodeCmd(FullNode, portOffset, discovery = true,
|
||||
master = true, label = "boot node")
|
||||
result.add(bootNode)
|
||||
for i in 1..<amount:
|
||||
result.add(initNodeCmd(FullNode, portOffset + i, label = "full node",
|
||||
discovery = true, bootNodes = @[bootNode.enode]))
|
||||
|
||||
proc generatePrometheusConfig(nodes: seq[NodeInfo], outputFile: string) =
|
||||
var config = """
|
||||
global:
|
||||
scrape_interval: 1s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: "wakusim"
|
||||
static_configs:"""
|
||||
var count = 0
|
||||
for node in nodes:
|
||||
let port = 8008 + node.shift
|
||||
config &= &"""
|
||||
|
||||
- targets: ['127.0.0.1:{port}']
|
||||
labels:
|
||||
node: '{count}'"""
|
||||
count += 1
|
||||
|
||||
var (path, file) = splitPath(outputFile)
|
||||
createDir(path)
|
||||
writeFile(outputFile, config)
|
||||
|
||||
proc proccessGrafanaDashboard(nodes: int, inputFile: string,
|
||||
outputFile: string) =
|
||||
# from https://github.com/status-im/nim-beacon-chain/blob/master/tests/simulation/process_dashboard.nim
|
||||
var
|
||||
inputData = parseFile(inputFile)
|
||||
panels = inputData["panels"].copy()
|
||||
numPanels = len(panels)
|
||||
gridHeight = 0
|
||||
outputData = inputData
|
||||
|
||||
for panel in panels:
|
||||
if panel["gridPos"]["x"].getInt() == 0:
|
||||
gridHeight += panel["gridPos"]["h"].getInt()
|
||||
|
||||
outputData["panels"] = %* []
|
||||
for nodeNum in 0 .. (nodes - 1):
|
||||
var
|
||||
nodePanels = panels.copy()
|
||||
panelIndex = 0
|
||||
for panel in nodePanels.mitems:
|
||||
panel["title"] = %* replace(panel["title"].getStr(), "#0", "#" & $nodeNum)
|
||||
panel["id"] = %* (panelIndex + (nodeNum * numPanels))
|
||||
panel["gridPos"]["y"] = %* (panel["gridPos"]["y"].getInt() + (nodeNum * gridHeight))
|
||||
var targets = panel["targets"]
|
||||
for target in targets.mitems:
|
||||
target["expr"] = %* replace(target["expr"].getStr(), "{node=\"0\"}", "{node=\"" & $nodeNum & "\"}")
|
||||
outputData["panels"].add(panel)
|
||||
panelIndex.inc()
|
||||
|
||||
outputData["uid"] = %* (outputData["uid"].getStr() & "a")
|
||||
outputData["title"] = %* (outputData["title"].getStr() & " (all nodes)")
|
||||
writeFile(outputFile, pretty(outputData))
|
||||
|
||||
when isMainModule:
|
||||
let conf = WakuNetworkConf.load()
|
||||
|
||||
var nodes: seq[NodeInfo]
|
||||
case conf.topology:
|
||||
of Star:
|
||||
nodes = starNetwork(conf.amount)
|
||||
of FullMesh:
|
||||
nodes = fullMeshNetwork(conf.amount)
|
||||
of DiscoveryBased:
|
||||
nodes = discoveryNetwork(conf.amount)
|
||||
|
||||
var staticnodes: seq[string]
|
||||
for i in 0..<conf.testNodePeers:
|
||||
# TODO: could also select nodes randomly
|
||||
staticnodes.add(nodes[i].enode)
|
||||
# light node with topic interest
|
||||
nodes.add(initNodeCmd(LightNode, 0, staticnodes, topicInterest = true,
|
||||
label = "light node topic interest"))
|
||||
# Regular light node
|
||||
nodes.add(initNodeCmd(LightNode, 1, staticnodes, label = "light node"))
|
||||
|
||||
var commandStr = "multitail -s 2 -M 0 -x \"Waku Simulation\""
|
||||
var count = 0
|
||||
var sleepDuration = 0
|
||||
for node in nodes:
|
||||
if conf.topology in {Star, DiscoveryBased}:
|
||||
sleepDuration = if node.master: 0
|
||||
else: 1
|
||||
commandStr &= &" -cT ansi -t 'node #{count} {node.label}' -l 'sleep {sleepDuration}; {node.cmd}; echo [node execution completed]; while true; do sleep 100; done'"
|
||||
if conf.topology == FullMesh:
|
||||
sleepDuration += 1
|
||||
count += 1
|
||||
|
||||
generatePrometheusConfig(nodes, metricsDir / "prometheus" / "prometheus.yml")
|
||||
proccessGrafanaDashboard(nodes.len,
|
||||
"waku" / "examples" / "waku-grafana-dashboard.json",
|
||||
metricsDir / "waku-sim-all-nodes-grafana-dashboard.json")
|
||||
|
||||
let errorCode = execCmd(commandStr)
|
||||
if errorCode != 0:
|
||||
error "launch command failed", command=commandStr
|
||||
Reference in New Issue
Block a user