Skip to content

Commit

Permalink
feat(c-bindings): rln relay
Browse files Browse the repository at this point in the history
  • Loading branch information
richard-ramos committed Mar 21, 2024
1 parent 2173fe2 commit 444a599
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 55 deletions.
66 changes: 66 additions & 0 deletions library/waku_thread/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ import
../../waku/node/config,
../events/json_base_event

type RLNConfig* = object
enabled*: bool
membershipIndex*: uint
dynamic*: bool
treePath*: string
bandwidthThreshold*: int
credentialPath*: string
ethClientAddress*: string
contractAddress*: string
credentialPassword*: string
userMessageLimit*: uint64
epochSizeSec*: uint64

proc parsePrivateKey(
jsonNode: JsonNode, privateKey: var PrivateKey, errorResp: var string
): bool =
Expand Down Expand Up @@ -80,6 +93,20 @@ proc parseRelay(jsonNode: JsonNode, relay: var bool, errorResp: var string): boo

return true

proc parseClusterId(jsonNode: JsonNode, clusterId: var uint32, errorResp: var string): bool =
if not jsonNode.contains("relay"):
errorResp = "relay attribute is required"
return false

if jsonNode.contains("clusterId"):
if jsonNode["clusterId"].kind != JsonNodeKind.JInt:
errorResp = "The clusterId config param should be a int"
return false
else:
clusterId = uint32(jsonNode["clusterId"].getInt())

return true

proc parseStore(
jsonNode: JsonNode,
store: var bool,
Expand Down Expand Up @@ -153,12 +180,33 @@ proc parseTopics(jsonNode: JsonNode, topics: var seq[string]) =
else:
topics = @["/waku/2/default-waku/proto"]

proc parseRLNRelay(jsonNode: JsonNode, rlnConfig: var RLNConfig, errorResp: var string): bool =
if not jsonNode.contains("rlnRelay"):
return true

let jsonNode = jsonNode["rlnRelay"]
if not jsonNode.contains("enabled"):
errorResp = "rlnRelay.enabled attribute is required"
return false
rlnConfig.enabled = jsonNode["enabled"].getBool()
rlnConfig.membershipIndex = uint(jsonNode{"membershipIndex"}.getInt())
rlnConfig.dynamic = jsonNode{"dynamic"}.getBool()
rlnConfig.treePath = jsonNode{"treePath"}.getStr()
rlnConfig.bandwidthThreshold = jsonNode{"bandwidthThreshold"}.getInt()
rlnConfig.ethClientAddress = jsonNode{"ethClientAddress"}.getStr("http://localhost:8540")
rlnConfig.contractAddress = jsonNode{"contractAddress"}.getStr()
rlnConfig.credentialPassword = jsonNode{"credentialPassword"}.getStr()
rlnConfig.userMessageLimit = uint64(jsonNode{"userMessageLimit"}.getInt(1))
rlnConfig.epochSizeSec = uint64(jsonNode{"epochSizeSec"}.getInt(1))
return true

proc parseConfig*(
configNodeJson: string,
privateKey: var PrivateKey,
netConfig: var NetConfig,
relay: var bool,
topics: var seq[string],
rlnRelay: var RLNConfig,
store: var bool,
storeNode: var string,
storeRetentionPolicy: var string,
Expand Down Expand Up @@ -227,6 +275,23 @@ proc parseConfig*(
errorResp = "Exception calling parseRelay: " & getCurrentExceptionMsg()
return false

# clusterId
var clusterId: uint32 = 0
try:
if not parseClusterId(jsonNode, clusterId, errorResp):
return false
except Exception, KeyError:
errorResp = "Exception calling parseClusterId: " & getCurrentExceptionMsg()
return false

# rln
try:
if not parseRLNRelay(jsonNode, rlnRelay, errorResp):
return false
except Exception, KeyError:
errorResp = "Exception calling parseRLNRelay: " & getCurrentExceptionMsg()
return false

# topics
try:
parseTopics(jsonNode, topics)
Expand Down Expand Up @@ -254,6 +319,7 @@ proc parseConfig*(
bindPort = Port(uint16(port)),
extIp = extIp,
extPort = extPort,
clusterId = clusterId,
wakuFlags = some(wakuFlags),
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import std/options
import std/sequtils
import chronos, chronicles, stew/results, stew/shims/net
import
../../../../waku/common/enr/builder,
../../../../waku/waku_enr/capabilities,
../../../../waku/waku_enr/multiaddr,
../../../../waku/waku_enr/sharding,
../../../../waku/waku_core/message/message,
../../../../waku/waku_core/message/default_values,
../../../../waku/waku_core/topics/pubsub_topic,
../../../../waku/node/peer_manager/peer_manager,
../../../../waku/waku_core,
../../../../waku/factory/external_config,
../../../../waku/node/waku_node,
../../../../waku/node/config,
../../../../waku/waku_archive/driver/builder,
Expand All @@ -18,6 +21,8 @@ import
../../../../waku/waku_relay/protocol,
../../../../waku/waku_store,
../../../../waku/factory/builder,
../../../../waku/factory/node_factory,
../../../apps/wakunode2/networks_config,
../../../events/[json_message_event, json_base_event],
../../../alloc,
../../config
Expand Down Expand Up @@ -108,6 +113,7 @@ proc createNode(configJson: cstring): Future[Result[WakuNode, string]] {.async.}
var storeVacuum: bool
var storeDbMigration: bool
var storeMaxNumDbConnections: int
var rlnRelay: RLNConfig

var errorResp: string

Expand All @@ -118,6 +124,7 @@ proc createNode(configJson: cstring): Future[Result[WakuNode, string]] {.async.}
netConfig,
relay,
topics,
rlnRelay,
store,
storeNode,
storeRetentionPolicy,
Expand All @@ -131,61 +138,64 @@ proc createNode(configJson: cstring): Future[Result[WakuNode, string]] {.async.}
except Exception:
return err("exception calling parseConfig: " & getCurrentExceptionMsg())

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)

let addShardedTopics = enrBuilder.withShardedTopics(topics)
if addShardedTopics.isErr():
let msg = "Error setting shared topics: " & $addShardedTopics.error
return err(msg)

let recordRes = enrBuilder.build()
let record =
if recordRes.isErr():
let msg = "Error building enr record: " & $recordRes.error
return err(msg)
var conf: WakuNodeConf

# TODO: figure out how to extract default values from the config pragma
conf.clusterId = netConfig.clusterId
conf.nodekey = some(privateKey)
conf.tcpPort = netConfig.extPort.get()
conf.nat = "any"
conf.maxConnections = 50.uint16
conf.relay = relay
conf.maxMessageSize = default_values.DefaultMaxWakuMessageSizeStr
conf.topics = topics
conf.store = store
conf.storenode = storeNode
conf.storeMessageRetentionPolicy = storeRetentionPolicy
conf.storeMessageDbUrl = storeDbUrl
conf.storeMessageDbVacuum = storeVacuum
conf.storeMessageDbMigration = storeDbMigration
conf.storeMaxNumDbConnections = storeMaxNumDbConnections
conf.rlnRelay = rlnRelay.enabled
if conf.rlnRelay:
conf.rlnRelayCredPath = rlnRelay.credentialPath
conf.rlnRelayEthClientAddress = EthRpcUrl.parseCmdArg(rlnRelay.ethClientAddress)
conf.rlnRelayEthContractAddress = rlnRelay.contractAddress
conf.rlnRelayCredPassword = rlnRelay.credentialPassword
conf.rlnRelayUserMessageLimit = rlnRelay.userMessageLimit
conf.rlnEpochSizeSec = rlnRelay.epochSizeSec
conf.rlnRelayCredIndex = some(rlnRelay.membershipIndex)
conf.rlnRelayDynamic = rlnRelay.dynamic
conf.rlnRelayTreePath = rlnRelay.treePath
conf.rlnRelayBandwidthThreshold = rlnRelay.bandwidthThreshold

# The Waku Network config (cluster-id=1)
if conf.clusterId == 1:
let twnClusterConf = ClusterConf.TheWakuNetworkConf()
if len(conf.shards) != 0:
conf.pubsubTopics = conf.shards.mapIt(twnClusterConf.pubsubTopics[it.uint16])
else:
recordRes.get()

## TODO: make the next const configurable from 'configJson'.
const MAX_CONNECTIONS = 50.int

var builder = WakuNodeBuilder.init()
builder.withRng(crypto.newRng())
builder.withNodeKey(privateKey)
builder.withRecord(record)
builder.withNetworkConfiguration(netConfig)
builder.withSwitchConfiguration(maxConnections = some(MAX_CONNECTIONS))

let wakuNodeRes = builder.build()
if wakuNodeRes.isErr():
let errorMsg = "failed to create waku node instance: " & wakuNodeRes.error
return err(errorMsg)

var newNode = wakuNodeRes.get()

if relay:
await newNode.mountRelay()
newNode.peerManager.start()

if store:
(
await newNode.configureStore(
storeNode, storeRetentionPolicy, storeDbUrl, storeVacuum, storeDbMigration,
storeMaxNumDbConnections,
)
).isOkOr:
return err("error configuring store: " & $error)

return ok(newNode)
conf.pubsubTopics = twnClusterConf.pubsubTopics

# Override configuration
conf.maxMessageSize = twnClusterConf.maxMessageSize
conf.clusterId = twnClusterConf.clusterId
conf.rlnRelay = twnClusterConf.rlnRelay
conf.rlnRelayEthContractAddress = twnClusterConf.rlnRelayEthContractAddress
conf.rlnRelayDynamic = twnClusterConf.rlnRelayDynamic
conf.rlnRelayBandwidthThreshold = twnClusterConf.rlnRelayBandwidthThreshold
conf.discv5Discovery = twnClusterConf.discv5Discovery
conf.discv5BootstrapNodes =
conf.discv5BootstrapNodes & twnClusterConf.discv5BootstrapNodes
conf.rlnEpochSizeSec = twnClusterConf.rlnEpochSizeSec
conf.rlnRelayUserMessageLimit = twnClusterConf.rlnRelayUserMessageLimit

let nodeRes = setupNode(conf)
if nodeRes.isErr():
error "Failed setting up node", error = nodeRes.error
return err("Failed setting up node: " & nodeRes.error)

return ok(nodeRes.value)

proc process*(
self: ptr NodeLifecycleRequest, node: ptr WakuNode
Expand Down
2 changes: 1 addition & 1 deletion waku/factory/external_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type ProtectedTopic* = object

type ShardIdx = distinct uint16

type EthRpcUrl = distinct string
type EthRpcUrl* = distinct string

type StartUpCommand* = enum
noCommand # default, runs waku
Expand Down

0 comments on commit 444a599

Please sign in to comment.