2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
import
|
2023-07-07 08:53:00 +00:00
|
|
|
std/[json,sequtils,times,strformat,options,atomics,strutils],
|
2023-05-12 16:08:41 +00:00
|
|
|
strutils,
|
|
|
|
os
|
|
|
|
import
|
|
|
|
chronicles,
|
|
|
|
chronos,
|
2023-05-17 16:32:53 +00:00
|
|
|
stew/shims/net
|
2023-05-12 16:08:41 +00:00
|
|
|
import
|
2023-06-29 19:59:53 +00:00
|
|
|
../../waku/common/enr/builder,
|
2023-05-12 16:08:41 +00:00
|
|
|
../../waku/v2/waku_enr/capabilities,
|
2023-06-29 19:59:53 +00:00
|
|
|
../../waku/v2/waku_enr/multiaddr,
|
|
|
|
../../waku/v2/waku_enr/sharding,
|
2023-05-12 16:08:41 +00:00
|
|
|
../../waku/v2/waku_core/message/message,
|
|
|
|
../../waku/v2/waku_core/topics/pubsub_topic,
|
|
|
|
../../waku/v2/node/peer_manager/peer_manager,
|
|
|
|
../../waku/v2/node/waku_node,
|
|
|
|
../../waku/v2/node/builder,
|
|
|
|
../../waku/v2/node/config,
|
|
|
|
../../waku/v2/waku_relay/protocol,
|
2023-07-07 08:53:00 +00:00
|
|
|
./events/[json_error_event,json_message_event,json_base_event],
|
|
|
|
./config
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
################################################################################
|
|
|
|
### Wrapper around the waku node
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
### Exported types
|
2023-07-07 08:53:00 +00:00
|
|
|
|
|
|
|
const RET_OK: cint = 0
|
|
|
|
const RET_ERR: cint = 1
|
|
|
|
const RET_MISSING_CALLBACK: cint = 2
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
### End of exported types
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
### Not-exported components
|
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
proc alloc(str: cstring): cstring =
|
|
|
|
# Byte allocation from the given address.
|
|
|
|
# There should be the corresponding manual deallocation with deallocShared !
|
|
|
|
let ret = cast[cstring](allocShared(len(str) + 1))
|
|
|
|
copyMem(ret, str, len(str) + 1)
|
|
|
|
return ret
|
|
|
|
|
2023-05-12 16:08:41 +00:00
|
|
|
type
|
2023-07-07 08:53:00 +00:00
|
|
|
WakuCallBack = proc(msg: ptr cchar, len: csize_t) {.cdecl, gcsafe.}
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
# May keep a reference to a callback defined externally
|
|
|
|
var extRelayEventCallback: WakuCallBack = nil
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-06-29 19:59:53 +00:00
|
|
|
proc relayEventCallback(pubsubTopic: string,
|
|
|
|
msg: WakuMessage):
|
|
|
|
Future[void] {.gcsafe, raises: [Defect].} =
|
2023-05-12 16:08:41 +00:00
|
|
|
# Callback that hadles the Waku Relay events. i.e. messages or errors.
|
2023-07-07 08:53:00 +00:00
|
|
|
if not isNil(extRelayEventCallback):
|
2023-05-12 16:08:41 +00:00
|
|
|
try:
|
2023-07-07 08:53:00 +00:00
|
|
|
let event = $JsonMessageEvent.new(pubsubTopic, msg)
|
|
|
|
extRelayEventCallback(unsafeAddr event[0], cast[csize_t](len(event)))
|
|
|
|
except Exception,CatchableError:
|
2023-05-12 16:08:41 +00:00
|
|
|
error "Exception when calling 'eventCallBack': " &
|
|
|
|
getCurrentExceptionMsg()
|
|
|
|
else:
|
2023-07-07 08:53:00 +00:00
|
|
|
error "extRelayEventCallback is nil"
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
var retFut = newFuture[void]()
|
|
|
|
retFut.complete()
|
|
|
|
return retFut
|
|
|
|
|
|
|
|
# WakuNode instance
|
|
|
|
var node {.threadvar.}: WakuNode
|
|
|
|
|
|
|
|
### End of not-exported components
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
### Exported procs
|
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
# Every Nim library must have this function called - the name is derived from
|
|
|
|
# the `--nimMainPrefix` command line option
|
|
|
|
proc NimMain() {.importc.}
|
|
|
|
|
|
|
|
var initialized: Atomic[bool]
|
|
|
|
|
|
|
|
proc waku_init_lib() {.dynlib, exportc, cdecl.} =
|
|
|
|
if not initialized.exchange(true):
|
|
|
|
NimMain() # Every Nim library needs to call `NimMain` once exactly
|
|
|
|
when declared(setupForeignThreadGc): setupForeignThreadGc()
|
|
|
|
when declared(nimGC_setStackBottom):
|
|
|
|
var locals {.volatile, noinit.}: pointer
|
|
|
|
locals = addr(locals)
|
|
|
|
nimGC_setStackBottom(locals)
|
|
|
|
|
|
|
|
proc waku_new(configJson: cstring,
|
|
|
|
onErrCb: WakuCallback): cint
|
|
|
|
{.dynlib, exportc, cdecl.} =
|
|
|
|
# Creates a new instance of the WakuNode.
|
|
|
|
# Notice that the ConfigNode type is also exported and available for users.
|
|
|
|
|
|
|
|
if isNil(onErrCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
2023-05-12 16:08:41 +00:00
|
|
|
var privateKey: PrivateKey
|
2023-07-07 08:53:00 +00:00
|
|
|
var netConfig = NetConfig.init(ValidIpAddress.init("127.0.0.1"),
|
|
|
|
Port(60000'u16)).value
|
|
|
|
var relay: bool
|
|
|
|
var topics = @[""]
|
|
|
|
var jsonResp: JsonEvent
|
|
|
|
|
|
|
|
let cj = configJson.alloc()
|
|
|
|
|
|
|
|
if not parseConfig($cj,
|
|
|
|
privateKey,
|
|
|
|
netConfig,
|
|
|
|
relay,
|
|
|
|
topics,
|
2023-05-12 16:08:41 +00:00
|
|
|
jsonResp):
|
2023-07-07 08:53:00 +00:00
|
|
|
deallocShared(cj)
|
|
|
|
let resp = $jsonResp
|
|
|
|
onErrCb(unsafeAddr resp[0], cast[csize_t](len(resp)))
|
|
|
|
return RET_ERR
|
|
|
|
|
|
|
|
deallocShared(cj)
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-06-29 19:59:53 +00:00
|
|
|
var enrBuilder = EnrBuilder.init(privateKey)
|
|
|
|
|
|
|
|
enrBuilder.withIpAddressAndPorts(
|
|
|
|
netConfig.enrIp,
|
|
|
|
netConfig.enrPort,
|
|
|
|
netConfig.discv5UdpPort
|
|
|
|
)
|
|
|
|
|
|
|
|
if netConfig.wakuFlags.isSome():
|
|
|
|
enrBuilder.withWakuCapabilities(netConfig.wakuFlags.get())
|
|
|
|
|
|
|
|
enrBuilder.withMultiaddrs(netConfig.enrMultiaddrs)
|
2023-07-07 08:53:00 +00:00
|
|
|
|
|
|
|
let addShardedTopics = enrBuilder.withShardedTopics(topics)
|
2023-06-29 19:59:53 +00:00
|
|
|
if addShardedTopics.isErr():
|
2023-07-07 08:53:00 +00:00
|
|
|
let resp = $addShardedTopics.error
|
|
|
|
onErrCb(unsafeAddr resp[0], cast[csize_t](len(resp)))
|
|
|
|
return RET_ERR
|
2023-06-29 19:59:53 +00:00
|
|
|
|
|
|
|
let recordRes = enrBuilder.build()
|
|
|
|
let record =
|
|
|
|
if recordRes.isErr():
|
2023-07-07 08:53:00 +00:00
|
|
|
let resp = $recordRes.error
|
|
|
|
onErrCb(unsafeAddr resp[0], cast[csize_t](len(resp)))
|
|
|
|
return RET_ERR
|
2023-06-29 19:59:53 +00:00
|
|
|
else: recordRes.get()
|
|
|
|
|
2023-05-12 16:08:41 +00:00
|
|
|
var builder = WakuNodeBuilder.init()
|
|
|
|
builder.withRng(crypto.newRng())
|
|
|
|
builder.withNodeKey(privateKey)
|
2023-06-29 19:59:53 +00:00
|
|
|
builder.withRecord(record)
|
2023-05-12 16:08:41 +00:00
|
|
|
builder.withNetworkConfiguration(netConfig)
|
|
|
|
builder.withSwitchConfiguration(
|
|
|
|
maxConnections = some(50.int)
|
|
|
|
)
|
|
|
|
|
|
|
|
let wakuNodeRes = builder.build()
|
|
|
|
if wakuNodeRes.isErr():
|
2023-07-07 08:53:00 +00:00
|
|
|
let errorMsg = "failed to create waku node instance: " & wakuNodeRes.error
|
|
|
|
let jsonErrEvent = $JsonErrorEvent.new(errorMsg)
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
onErrCb(unsafeAddr jsonErrEvent[0], cast[csize_t](len(jsonErrEvent)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
node = wakuNodeRes.get()
|
|
|
|
|
|
|
|
if relay:
|
2023-05-12 16:08:41 +00:00
|
|
|
waitFor node.mountRelay()
|
|
|
|
node.peerManager.start()
|
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
return RET_OK
|
|
|
|
|
|
|
|
proc waku_version(onOkCb: WakuCallBack): cint {.dynlib, exportc.} =
|
|
|
|
if isNil(onOkCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
onOkCb(cast[ptr cchar](WakuNodeVersionString),
|
|
|
|
cast[csize_t](len(WakuNodeVersionString)))
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
return RET_OK
|
|
|
|
|
|
|
|
proc waku_set_relay_callback(callback: WakuCallBack) {.dynlib, exportc.} =
|
|
|
|
extRelayEventCallback = callback
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
proc waku_content_topic(appName: cstring,
|
2023-07-07 08:53:00 +00:00
|
|
|
appVersion: cuint,
|
2023-05-12 16:08:41 +00:00
|
|
|
contentTopicName: cstring,
|
|
|
|
encoding: cstring,
|
2023-07-07 08:53:00 +00:00
|
|
|
onOkCb: WakuCallBack): cint {.dynlib, exportc.} =
|
2023-05-12 16:08:41 +00:00
|
|
|
# https://rfc.vac.dev/spec/36/#extern-char-waku_content_topicchar-applicationname-unsigned-int-applicationversion-char-contenttopicname-char-encoding
|
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
if isNil(onOkCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
|
|
|
let appStr = appName.alloc()
|
|
|
|
let ctnStr = contentTopicName.alloc()
|
|
|
|
let encodingStr = encoding.alloc()
|
|
|
|
|
|
|
|
let contentTopic = fmt"/{$appStr}/{appVersion}/{$ctnStr}/{$encodingStr}"
|
|
|
|
onOkCb(unsafeAddr contentTopic[0], cast[csize_t](len(contentTopic)))
|
|
|
|
|
|
|
|
deallocShared(appStr)
|
|
|
|
deallocShared(ctnStr)
|
|
|
|
deallocShared(encodingStr)
|
|
|
|
|
|
|
|
return RET_OK
|
|
|
|
|
|
|
|
proc waku_pubsub_topic(topicName: cstring,
|
|
|
|
onOkCb: WakuCallBack): cint {.dynlib, exportc, cdecl.} =
|
|
|
|
if isNil(onOkCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
|
|
|
let topicNameStr = topicName.alloc()
|
|
|
|
|
2023-05-12 16:08:41 +00:00
|
|
|
# https://rfc.vac.dev/spec/36/#extern-char-waku_pubsub_topicchar-name-char-encoding
|
2023-07-07 08:53:00 +00:00
|
|
|
let outPubsubTopic = fmt"/waku/2/{$topicNameStr}"
|
|
|
|
onOkCb(unsafeAddr outPubsubTopic[0], cast[csize_t](len(outPubsubTopic)))
|
|
|
|
|
|
|
|
deallocShared(topicNameStr)
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
return RET_OK
|
|
|
|
|
|
|
|
proc waku_default_pubsub_topic(onOkCb: WakuCallBack): cint {.dynlib, exportc.} =
|
2023-05-12 16:08:41 +00:00
|
|
|
# https://rfc.vac.dev/spec/36/#extern-char-waku_default_pubsub_topic
|
2023-07-07 08:53:00 +00:00
|
|
|
if isNil(onOkCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
|
|
|
onOkCb(cast[ptr cchar](DefaultPubsubTopic),
|
|
|
|
cast[csize_t](len(DefaultPubsubTopic)))
|
|
|
|
|
|
|
|
return RET_OK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
proc waku_relay_publish(pubSubTopic: cstring,
|
|
|
|
jsonWakuMessage: cstring,
|
2023-07-07 08:53:00 +00:00
|
|
|
timeoutMs: cuint,
|
|
|
|
onOkCb: WakuCallBack,
|
|
|
|
onErrCb: WakuCallBack): cint
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
{.dynlib, exportc, cdecl.} =
|
|
|
|
# https://rfc.vac.dev/spec/36/#extern-char-waku_relay_publishchar-messagejson-char-pubsubtopic-int-timeoutms
|
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
if isNil(onOkCb) or isNil(onErrCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
|
|
|
let jwm = jsonWakuMessage.alloc()
|
2023-05-12 16:08:41 +00:00
|
|
|
var jsonContent:JsonNode
|
|
|
|
try:
|
2023-07-07 08:53:00 +00:00
|
|
|
jsonContent = parseJson($jwm)
|
2023-05-12 16:08:41 +00:00
|
|
|
except JsonParsingError:
|
2023-07-07 08:53:00 +00:00
|
|
|
deallocShared(jwm)
|
|
|
|
let msg = fmt"Error parsing json message: {getCurrentExceptionMsg()}"
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
|
|
|
|
|
|
|
deallocShared(jwm)
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
var wakuMessage: WakuMessage
|
|
|
|
try:
|
|
|
|
var version = 0'u32
|
|
|
|
if jsonContent.hasKey("version"):
|
|
|
|
version = (uint32) jsonContent["version"].getInt()
|
|
|
|
|
|
|
|
wakuMessage = WakuMessage(
|
|
|
|
# Visit https://rfc.vac.dev/spec/14/ for further details
|
|
|
|
payload: jsonContent["payload"].getStr().toSeq().mapIt(byte (it)),
|
|
|
|
contentTopic: $jsonContent["content_topic"].getStr(),
|
|
|
|
version: version,
|
|
|
|
timestamp: getTime().toUnix(),
|
|
|
|
ephemeral: false
|
|
|
|
)
|
|
|
|
except KeyError:
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = fmt"Problem building the WakuMessage: {getCurrentExceptionMsg()}"
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
let pst = pubSubTopic.alloc()
|
|
|
|
|
|
|
|
let targetPubSubTopic = if len(pst) == 0:
|
2023-05-12 16:08:41 +00:00
|
|
|
DefaultPubsubTopic
|
|
|
|
else:
|
2023-07-07 08:53:00 +00:00
|
|
|
$pst
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
if node.wakuRelay.isNil():
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = "Can't publish. WakuRelay is not enabled."
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
let pubMsgFut = node.wakuRelay.publish(targetPubSubTopic, wakuMessage)
|
|
|
|
|
|
|
|
# With the next loop we convert an asynchronous call into a synchronous one
|
|
|
|
for i in 0 .. timeoutMs:
|
|
|
|
if pubMsgFut.finished():
|
|
|
|
break
|
|
|
|
sleep(1)
|
|
|
|
|
|
|
|
if pubMsgFut.finished():
|
|
|
|
let numPeers = pubMsgFut.read()
|
|
|
|
if numPeers == 0:
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = "Message not sent because no peers found."
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
elif numPeers > 0:
|
|
|
|
# TODO: pending to return a valid message Id (response when all is correct)
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = "hard-coded-message-id"
|
|
|
|
onOkCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_OK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
else:
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = "Timeout expired"
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
proc waku_start() {.dynlib, exportc.} =
|
|
|
|
waitFor node.start()
|
|
|
|
|
|
|
|
proc waku_stop() {.dynlib, exportc.} =
|
|
|
|
waitFor node.stop()
|
|
|
|
|
|
|
|
proc waku_relay_subscribe(
|
|
|
|
pubSubTopic: cstring,
|
2023-07-07 08:53:00 +00:00
|
|
|
onErrCb: WakuCallBack): cint
|
2023-05-12 16:08:41 +00:00
|
|
|
{.dynlib, exportc.} =
|
|
|
|
# @params
|
|
|
|
# topic: Pubsub topic to subscribe to. If empty, it subscribes to the default pubsub topic.
|
2023-07-07 08:53:00 +00:00
|
|
|
if isNil(onErrCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
|
|
|
if isNil(extRelayEventCallback):
|
|
|
|
let msg = $"""Cannot subscribe without a callback.
|
|
|
|
# Kindly set it with the 'waku_set_relay_callback' function"""
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_MISSING_CALLBACK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
if node.wakuRelay.isNil():
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = $"Cannot subscribe without Waku Relay enabled."
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
let pst = pubSubTopic.alloc()
|
|
|
|
node.wakuRelay.subscribe(PubsubTopic($pst),
|
2023-06-29 19:59:53 +00:00
|
|
|
WakuRelayHandler(relayEventCallback))
|
2023-07-07 08:53:00 +00:00
|
|
|
deallocShared(pst)
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
return RET_OK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
proc waku_relay_unsubscribe(
|
|
|
|
pubSubTopic: cstring,
|
2023-07-07 08:53:00 +00:00
|
|
|
onErrCb: WakuCallBack): cint
|
2023-05-12 16:08:41 +00:00
|
|
|
{.dynlib, exportc.} =
|
|
|
|
# @params
|
|
|
|
# topic: Pubsub topic to subscribe to. If empty, it unsubscribes to the default pubsub topic.
|
2023-07-07 08:53:00 +00:00
|
|
|
if isNil(onErrCb):
|
|
|
|
return RET_MISSING_CALLBACK
|
|
|
|
|
|
|
|
if isNil(extRelayEventCallback):
|
|
|
|
let msg = """Cannot unsubscribe without a callback.
|
|
|
|
# Kindly set it with the 'waku_set_relay_callback' function"""
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_MISSING_CALLBACK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
if node.wakuRelay.isNil():
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = "Cannot unsubscribe without Waku Relay enabled."
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
let pst = pubSubTopic.alloc()
|
|
|
|
node.wakuRelay.unsubscribe(PubsubTopic($pst))
|
|
|
|
deallocShared(pst)
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
return RET_OK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
proc waku_connect(peerMultiAddr: cstring,
|
2023-07-07 08:53:00 +00:00
|
|
|
timeoutMs: cuint,
|
|
|
|
onErrCb: WakuCallBack): cint
|
2023-05-12 16:08:41 +00:00
|
|
|
{.dynlib, exportc.} =
|
|
|
|
# peerMultiAddr: comma-separated list of fully-qualified multiaddresses.
|
2023-07-07 08:53:00 +00:00
|
|
|
# var ret = newString(len + 1)
|
|
|
|
# if len > 0:
|
|
|
|
# copyMem(addr ret[0], str, len + 1)
|
|
|
|
|
|
|
|
let address = peerMultiAddr.alloc()
|
|
|
|
let peers = ($address).split(",").mapIt(strip(it))
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
# TODO: the timeoutMs is not being used at all!
|
|
|
|
let connectFut = node.connectToNodes(peers, source="static")
|
|
|
|
while not connectFut.finished():
|
|
|
|
poll()
|
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
deallocShared(address)
|
|
|
|
|
2023-05-12 16:08:41 +00:00
|
|
|
if not connectFut.completed():
|
2023-07-07 08:53:00 +00:00
|
|
|
let msg = "Timeout expired."
|
|
|
|
onErrCb(unsafeAddr msg[0], cast[csize_t](len(msg)))
|
|
|
|
return RET_ERR
|
2023-05-12 16:08:41 +00:00
|
|
|
|
2023-07-07 08:53:00 +00:00
|
|
|
return RET_OK
|
2023-05-12 16:08:41 +00:00
|
|
|
|
|
|
|
proc waku_poll() {.dynlib, exportc, gcsafe.} =
|
|
|
|
poll()
|
|
|
|
|
|
|
|
### End of exported procs
|
2023-06-29 19:59:53 +00:00
|
|
|
################################################################################
|