fix(rng): create rng only within isMainModule blocks (#1523)

* fix(rng): create rng only within isMainModule blocks

* fix(rng): wakucanary rng

* fix(rng): address comments
This commit is contained in:
Aaryamann Challani 2023-02-06 17:23:05 +05:30 committed by GitHub
parent 4ea6039323
commit c9bc774895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 71 deletions

View File

@ -370,10 +370,12 @@ proc readInput(wfd: AsyncFD) {.thread, raises: [Defect, CatchableError].} =
discard waitFor transp.write(line & "\r\n")
{.pop.} # @TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError
proc processInput(rfd: AsyncFD) {.async.} =
proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} =
let
transp = fromPipe(rfd)
conf = Chat2Conf.load()
nodekey = if conf.nodekey.isSome(): conf.nodekey.get()
else: PrivateKey.random(Secp256k1, rng[]).tryGet()
# set log level
if conf.logLevel != LogLevel.NONE:
@ -383,7 +385,7 @@ proc processInput(rfd: AsyncFD) {.async.} =
(extIp, extTcpPort, extUdpPort) = setupNat(conf.nat, clientId,
Port(uint16(conf.tcpPort) + conf.portsShift),
Port(uint16(conf.udpPort) + conf.portsShift))
node = WakuNode.new(conf.nodekey, conf.listenAddress,
node = WakuNode.new(nodekey, conf.listenAddress,
Port(uint16(conf.tcpPort) + conf.portsShift),
extIp, extTcpPort,
wsBindPort = Port(uint16(conf.websocketPort) + conf.portsShift),
@ -593,7 +595,7 @@ proc processInput(rfd: AsyncFD) {.async.} =
runForever()
proc main() {.async.} =
proc main(rng: ref HmacDrbgContext) {.async.} =
let (rfd, wfd) = createAsyncPipe()
if rfd == asyncInvalidPipe or wfd == asyncInvalidPipe:
raise newException(ValueError, "Could not initialize pipe!")
@ -601,7 +603,7 @@ proc main() {.async.} =
var thread: Thread[AsyncFD]
thread.createThread(readInput, wfd)
try:
await processInput(rfd)
await processInput(rfd, rng)
# Handle only ConfigurationError for now
# TODO: Throw other errors from the mounting procedure
except ConfigurationError as e:
@ -609,8 +611,9 @@ proc main() {.async.} =
when isMainModule: # isMainModule = true when the module is compiled as the main file
let rng = crypto.newRng()
try:
waitFor(main())
waitFor(main(rng))
except CatchableError as e:
raise e

View File

@ -25,8 +25,7 @@ type
nodekey* {.
desc: "P2P node private key as 64 char hex string.",
defaultValue: crypto.PrivateKey.random(Secp256k1, crypto.newRng()[]).tryGet()
name: "nodekey" }: crypto.PrivateKey
name: "nodekey" }: Option[crypto.PrivateKey]
listenAddress* {.
defaultValue: defaultListenAddress(config)

View File

@ -53,8 +53,7 @@ type
nodekey* {.
desc: "P2P node private key as 64 char hex string.",
defaultValue: defaultPrivateKey()
name: "nodekey" }: PrivateKey
name: "nodekey" }: Option[PrivateKey]
listenAddress* {.
defaultValue: defaultListenAddress()
@ -465,9 +464,6 @@ proc parseCmdArg*(T: type crypto.PrivateKey, p: string): T =
proc completeCmdArg*(T: type crypto.PrivateKey, val: string): seq[string] =
return @[]
proc defaultPrivateKey*(): PrivateKey =
crypto.PrivateKey.random(Secp256k1, crypto.newRng()[]).value
proc parseCmdArg*(T: type ValidIpAddress, p: string): T =
try:

View File

@ -214,6 +214,7 @@ proc retrieveDynamicBootstrapNodes*(dnsDiscovery: bool, dnsDiscoveryUrl: string,
ok(newSeq[RemotePeerInfo]()) # Return an empty seq by default
proc initNode(conf: WakuNodeConf,
rng: ref HmacDrbgContext,
peerStore: Option[WakuPeerStorage],
dynamicBootstrapNodes: openArray[RemotePeerInfo] = @[]): SetupResult[WakuNode] =
@ -231,6 +232,13 @@ proc initNode(conf: WakuNodeConf,
dnsResolver = DnsResolver.new(nameServers)
let
nodekey = if conf.nodekey.isSome():
conf.nodekey.get()
else:
let nodekeyRes = crypto.PrivateKey.random(Secp256k1, rng[])
if nodekeyRes.isErr():
return err("failed to generate nodekey: " & $nodekeyRes.error)
nodekeyRes.get()
## `udpPort` is only supplied to satisfy underlying APIs but is not
## actually a supported transport for libp2p traffic.
udpPort = conf.tcpPort
@ -271,7 +279,7 @@ proc initNode(conf: WakuNodeConf,
let pStorage = if peerStore.isNone(): nil
else: peerStore.get()
try:
node = WakuNode.new(conf.nodekey,
node = WakuNode.new(nodekey,
conf.listenAddress, Port(uint16(conf.tcpPort) + conf.portsShift),
extIp, extPort,
extMultiAddrs,
@ -288,7 +296,8 @@ proc initNode(conf: WakuNodeConf,
dns4DomainName,
discv5UdpPort,
some(conf.agentString),
conf.peerStoreCapacity)
conf.peerStoreCapacity,
rng)
except:
return err("failed to create waku node instance: " & getCurrentExceptionMsg())
@ -318,7 +327,7 @@ proc initNode(conf: WakuNodeConf,
discv5UdpPort.get(),
discv5BootstrapEnrs,
conf.discv5EnrAutoUpdate,
keys.PrivateKey(conf.nodekey.skkey),
keys.PrivateKey(nodekey.skkey),
wakuFlags,
[], # Empty enr fields, for now
node.rng,
@ -570,6 +579,7 @@ when isMainModule:
## 6. Setup graceful shutdown hooks
const versionString = "version / git commit hash: " & git_version
let rng = crypto.newRng()
let confRes = WakuNodeConf.load(version=versionString)
if confRes.isErr():
@ -655,7 +665,7 @@ when isMainModule:
var node: WakuNode # This is the node we're going to setup using the conf
let initNodeRes = initNode(conf, peerStore, dynamicBootstrapNodes)
let initNodeRes = initNode(conf, rng, peerStore, dynamicBootstrapNodes)
if initNodeRes.isok():
node = initNodeRes.get()
else:

View File

@ -28,12 +28,12 @@ const bootstrapNodes = @["enr:-Nm4QOdTOKZJKTUUZ4O_W932CXIET-M9NamewDnL78P5u9DOGn
const wakuPort = 60000
const discv5Port = 9000
proc setupAndPublish() {.async.} =
proc setupAndPublish(rng: ref HmacDrbgContext) {.async.} =
# use notice to filter all waku messaging
setupLogLevel(logging.LogLevel.NOTICE)
notice "starting publisher", wakuPort=wakuPort, discv5Port=discv5Port
let
nodeKey = crypto.PrivateKey.random(Secp256k1, crypto.newRng()[])[]
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
ip = ValidIpAddress.init("0.0.0.0")
node = WakuNode.new(nodeKey, ip, Port(wakuPort))
flags = initWakuFlags(lightpush = false, filter = false, store = false, relay = true)
@ -84,5 +84,7 @@ proc setupAndPublish() {.async.} =
notice "published message", text = text, timestamp = message.timestamp, psTopic = pubSubTopic, contentTopic = contentTopic
await sleepAsync(5000)
asyncSpawn setupAndPublish()
runForever()
when isMainModule:
let rng = crypto.newRng()
asyncSpawn setupAndPublish(rng)
runForever()

View File

@ -24,12 +24,12 @@ const bootstrapNodes = @["enr:-Nm4QOdTOKZJKTUUZ4O_W932CXIET-M9NamewDnL78P5u9DOGn
const wakuPort = 50000
const discv5Port = 8000
proc setupAndSubscribe() {.async.} =
proc setupAndSubscribe(rng: ref HmacDrbgContext) {.async.} =
# use notice to filter all waku messaging
setupLogLevel(logging.LogLevel.NOTICE)
notice "starting subscriber", wakuPort=wakuPort, discv5Port=discv5Port
let
nodeKey = crypto.PrivateKey.random(Secp256k1, crypto.newRng()[])[]
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
ip = ValidIpAddress.init("0.0.0.0")
node = WakuNode.new(nodeKey, ip, Port(wakuPort))
flags = initWakuFlags(lightpush = false, filter = false, store = false, relay = true)
@ -79,6 +79,7 @@ proc setupAndSubscribe() {.async.} =
timestamp=message.timestamp
node.subscribe(pubSubTopic, handler)
asyncSpawn setupAndSubscribe()
runForever()
when isMainModule:
let rng = crypto.newRng()
asyncSpawn setupAndSubscribe(rng)
runForever()

View File

@ -10,6 +10,7 @@ import
stew/byteutils
import
../../waku/v2/node/wakuswitch,
../test_helpers,
./testlib/switch
proc newCircuitRelayClientSwitch(relayClient: RelayClient): Switch =
@ -28,7 +29,7 @@ procSuite "Waku Switch":
## Given
let
sourceSwitch = newTestSwitch()
wakuSwitch = newWakuSwitch()
wakuSwitch = newWakuSwitch(rng = rng())
await sourceSwitch.start()
await wakuSwitch.start()
@ -46,7 +47,7 @@ procSuite "Waku Switch":
asyncTest "Waku Switch acts as circuit relayer":
## Setup
let
wakuSwitch = newWakuSwitch()
wakuSwitch = newWakuSwitch(rng = rng())
sourceClient = RelayClient.new()
destClient = RelayClient.new()
sourceSwitch = newCircuitRelayClientSwitch(sourceClient)

View File

@ -86,7 +86,7 @@ proc areProtocolsSupported(
return false
proc main(): Future[int] {.async.} =
proc main(rng: ref HmacDrbgContext): Future[int] {.async.} =
let conf: WakuCanaryConf = WakuCanaryConf.load()
# create dns resolver
@ -113,7 +113,6 @@ proc main(): Future[int] {.async.} =
let
peer: RemotePeerInfo = parseRemotePeerInfo(conf.address)
rng = crypto.newRng()
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
node = WakuNode.new(
nodeKey,
@ -141,7 +140,8 @@ proc main(): Future[int] {.async.} =
return 0
when isMainModule:
let status = waitFor main()
let rng = crypto.newRng()
let status = waitFor main(rng)
if status == 0:
info "The node is reachable and supports all specified protocols"
else:

View File

@ -152,6 +152,8 @@ proc new*(T: type WakuNode,
discv5UdpPort = none(Port),
agentString = none(string), # defaults to nim-libp2p version
peerStoreCapacity = none(int), # defaults to 1.25 maxConnections
# TODO: make this argument required after tests are updated
rng: ref HmacDrbgContext = crypto.newRng()
): T {.raises: [Defect, LPError, IOError, TLSStreamProtocolError].} =
## Creates a Waku Node instance.
@ -198,7 +200,6 @@ proc new*(T: type WakuNode,
## Initialize peer
let
rng = crypto.newRng()
enrIp = if extIp.isSome(): extIp
else: some(bindIp)
enrTcpPort = if extPort.isSome(): extPort

View File

@ -63,7 +63,7 @@ proc newWakuSwitch*(
SecureProtocol.Noise,
],
transportFlags: set[ServerFlags] = {},
rng = crypto.newRng(),
rng: ref HmacDrbgContext,
inTimeout: Duration = 5.minutes,
outTimeout: Duration = 5.minutes,
maxConnections = MaxConnections,