import strformat, os, osproc, net, strformat, chronicles, confutils, json, eth/p2p/discoveryv5/enr, eth/keys, stew/shims/net as stewNet, libp2p/multiaddress, libp2p/crypto/crypto, libp2p/crypto/secp, libp2p/peerinfo # Fix ambiguous call error import strutils except fromHex const # Scenarios without discv5 # defaults ="--log-level:TRACE --metrics-logging --metrics-server --rpc" # # Scenarios using discv5 defaults ="--log-level:TRACE --metrics-logging --metrics-server --rpc --discv5-discovery --discv5-table-ip-limit=1024 --discv5-bucket-ip-limit=16 --discv5-bits-per-hop=1" wakuNodeBin = "build" / "wakunode2" metricsDir = "metrics" portOffset = 2 discv5ExtIpAddr = "127.0.0.1" # Scenarios using discv5 type NodeInfo* = object cmd: string master: bool address: string shift: int label: string enrUri: string # Scenarios using discv5 Topology = enum Star, FullMesh, BootstrapFleet # comprising one full-mesh core (fleet) and satellites (full nodes) using the fleet as bootstrap nodes WakuNetworkConf* = object topology* {. desc: "Set the network topology." defaultValue: FullMesh name: "topology" .}: Topology amount* {. desc: "Amount of relay nodes to be started." defaultValue: 16 name: "amount" .}: int numFleetNodes* {. desc: "Number of Fleetnodes." defaultValue: 3 name: "numFleetNodes" .}: int proc debugPrintEnrURI(enrUri: string) = var r: Record if not fromURI(r, enrUri): echo "could not read ENR URI" echo "ENR content: ", r # NOTE: Don't distinguish between node types here a la full node, light node etc proc initNodeCmd(shift: int, staticNodes: seq[string] = @[], master = false, label: string, discv5BootStrapEnrs: seq[string] = @[]): NodeInfo = let rng = crypto.newRng() key = SkPrivateKey.random(rng[]) hkey = key.getBytes().toHex() rkey = SkPrivateKey.init(fromHex(hkey))[] #assumes ok privKey = crypto.PrivateKey(scheme: Secp256k1, skkey: rkey) #privKey = PrivateKey.random(Secp256k1) pubkey = privKey.getPublicKey()[] #assumes ok keyPair = crypto.KeyPair(seckey: privKey, pubkey: pubkey) peerInfo = PeerInfo.new(privKey) port = 60000 + shift discv5Port = 9000 + shift #DefaultAddr = "/ip4/127.0.0.1/tcp/55505" address = "/ip4/127.0.0.1/tcp/" & $port hostAddress = MultiAddress.init(address).tryGet() info "Address", address # TODO: Need to port shift peerInfo.addrs.add(hostAddress) let id = $peerInfo.peerId info "PeerInfo", id = id, addrs = peerInfo.addrs let listenStr = $peerInfo.addrs[0] & "/p2p/" & id result.cmd = wakuNodeBin & " " & defaults & " " result.cmd &= "--nodekey:" & hkey & " " result.cmd &= "--ports-shift:" & $shift & " " if staticNodes.len > 0: for staticNode in staticNodes: result.cmd &= "--staticnode:" & staticNode & " " # Scenarios using discv5 result.cmd &= "--nat:extip:" & discv5ExtIpAddr & " " if discv5BootStrapEnrs.len > 0: for enr in discv5BootStrapEnrs: result.cmd &= "--discv5-bootstrap-node:" & enr & " " result.shift = shift result.label = label result.master = master result.address = listenStr # Scenarios using discv5 # We have to manually build the ENR which the node ran with the currently build node command will generate, # because we need to know it before the node starts in order to be able to provide it as bootstrap information. # Note: the ENR built here is not exactly the same as we don't integrate the waku2 key in this test scenario. let enr = enr.Record.init(1, keys.PrivateKey.fromHex(hkey).expect("could not convert priv key from hex"), some(stewNet.ValidIpAddress.init(discv5ExtIpAddr)), some(Port(discv5Port)), # tcp-port some(Port(discv5Port))) # udp-port .expect("Record within size limits") result.enrUri = "enr:" & enr.toBase64 info "Node command created.", cmd=result.cmd, address = result.address # # Scenarios without discv5 # proc starNetwork(amount: int): seq[NodeInfo] = # let masterNode = initNodeCmd(portOffset, master = true, label = "master node") # result.add(masterNode) # for i in 1..