Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions library/libwaku.nim
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ivansete-status I wonder if we should rename this file to libwaku_ffi.nim as it is more focused on FFI than actual library.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can rename that

Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ proc initializeLibrary() {.exported.} =
################################################################################

################################################################################
### Exported procs
### FFI Exported procs

proc waku_new(
configJson: cstring, callback: WakuCallback, userData: pointer
Expand Down Expand Up @@ -849,5 +849,5 @@ proc waku_is_online(
userData,
)

### End of exported procs
### End of FFI exported procs
################################################################################
16 changes: 16 additions & 0 deletions library/libwaku_api.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import chronicles, chronos, results

import waku/factory/waku

import ./libwaku_conf

proc createNode*(config: LibWakuConfig): Future[Result[Waku, string]] {.async.} =
let wakuConf = toWakuConf(config).valueOr:
return err("Failed to handle the configuration: " & error)

## We are not defining app callbacks at node creation
let wakuRes = (await Waku.new(wakuConf)).valueOr:
error "waku initialization failed", error = error
return err("Failed setting up Waku: " & $error)

return ok(wakuRes)
149 changes: 149 additions & 0 deletions library/libwaku_conf.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, I would not add this file. It seems it adds an additional layer of possible bugs, when sending attributes between layers

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are defining a new API. These is the config for this new API. The existing API uses WakuNodeConf which is the CLI args one, and hence not adapted.

The intent is to move away from WakuNodeConf and have a config object that works for application developers.

std/options,
results,
waku/factory/waku_conf,
waku/factory/conf_builder/conf_builder,
waku/factory/networks_config

type ShardingMode* = enum
AutoSharding = "auto"
StaticSharding = "static"

type AutoShardingConfig* = object
numShardsInCluster*: uint16

type RlnConfig* = object
contractAddress*: string
chainId*: uint
epochSizeSec*: uint64

type MessageValidation* = object
maxMessageSizeBytes*: uint64
rlnConfig*: Option[RlnConfig]

type NetworkConfig* = object
bootstrapNodes*: seq[string]
staticStoreNodes*: seq[string]
clusterId*: uint16
shardingMode*: Option[ShardingMode]
autoShardingConfig*: Option[AutoShardingConfig]
messageValidation*: Option[MessageValidation]

type WakuMode* = enum
Edge = "edge"
Relay = "relay"

type LibWakuConfig* = object
mode*: WakuMode
networkConfig*: Option[NetworkConfig]
storeConfirmation*: bool
ethRpcEndpoints*: seq[string]

proc DefaultShardingMode(): ShardingMode =
return ShardingMode.Autosharding

proc DefaultAutoShardingConfig(): AutoShardingConfig =
return AutoShardingConfig(numShardsInCluster: 1)

proc DefaultNetworkConfig(): NetworkConfig =
return NetworkConfig(
bootstrapNodes:
@[
"enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im"
],
staticStoreNodes: @[], # TODO
clusterId: 1,
shardingMode: some(ShardingMode.AutoSharding),
autoShardingConfig: some(AutoShardingConfig(numShardsInCluster: 8)),
messageValidation: some(
MessageValidation(
maxMessageSizeBytes: 153600,
rlnConfig: some (
RlnConfig(
contractAddress: "0xB9cd878C90E49F797B4431fBF4fb333108CB90e6",
chain_id: 59141,
epoch_size_sec: 600, # 10 minutes
)
),
)
),
)

proc DefaultMessageValidation(): MessageValidation =
return MessageValidation(maxMessageSizeBytes: 153600, rlnConfig: none(RlnConfig))

proc toWakuConf*(config: LibWakuConfig): Result[WakuConf, string] =
var b = WakuConfBuilder.init()

case config.mode
of Relay:
b.withRelay(true)

b.filterServiceConf.withEnabled(true)
b.filterServiceConf.withMaxPeersToServe(20)

b.withLightPush(true)

b.discv5Conf.withEnabled(true)
b.withPeerExchange(true)

b.rateLimitConf.withRateLimits(@["filter:100/1s", "lightpush:5/1s", "px:5/1s"])
of Edge:
return err("Edge mode is not implemented")

#TODO: store confirmation

## Network Conf
let networkConfig = config.networkConfig.get(DefaultNetworkConfig())

# Set cluster ID
b.withClusterId(networkConfig.clusterId)

# Set sharding configuration
case networkConfig.shardingMode.get(DefaultShardingMode())
of AutoSharding:
b.withShardingConf(ShardingConfKind.AutoSharding)
let autoShardingConfig =
networkConfig.autoShardingConfig.get(DefaultAutoShardingConfig())
b.withNumShardsInCluster(autoShardingConfig.numShardsInCluster)
of StaticSharding:
b.withShardingConf(ShardingConfKind.StaticSharding)

# Set bootstrap nodes
if networkConfig.bootstrapNodes.len > 0:
b.discv5Conf.withBootstrapNodes(networkConfig.bootstrapNodes)

# TODO: verify behaviour
# Set static store nodes
if networkConfig.staticStoreNodes.len > 0:
b.withStaticNodes(networkConfig.staticStoreNodes)

# Set message validation

let msgValidation = networkConfig.messageValidation.get(DefaultMessageValidation())
b.withMaxMessageSize(msgValidation.maxMessageSizeBytes)

# Set RLN config if provided
if msgValidation.rlnConfig.isSome():
let rlnConfig = msgValidation.rlnConfig.get()
b.rlnRelayConf.withEnabled(true)
b.rlnRelayConf.withEthContractAddress(rlnConfig.contractAddress)
b.rlnRelayConf.withChainId(rlnConfig.chainId)
b.rlnRelayConf.withEpochSizeSec(rlnConfig.epochSizeSec)
b.rlnRelayConf.withDynamic(true)
b.rlnRelayConf.withEthClientUrls(config.ethRpcEndpoints)

# TODO: we should get rid of those two
b.rlnRelayconf.withUserMessageLimit(100)
b.rlnRelayConf.withTreePath("./rln_tree")

## Various configurations
b.withNatStrategy("any")

let wakuConf = b.build().valueOr:
return err("Failed to build configuration: " & error)

wakuConf.validate().isOkOr:
return err("Failed to validate configuration: " & error)

return ok(wakuConf)
3 changes: 3 additions & 0 deletions tests/all_tests_waku.nim
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,6 @@ import ./waku_rln_relay/test_all

# Node Factory
import ./factory/test_all

# Library tests
import ./library/test_all
3 changes: 3 additions & 0 deletions tests/library/test_all.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{.used.}

import ./test_libwaku_conf, ./test_libwaku
102 changes: 102 additions & 0 deletions tests/library/test_libwaku.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{.used.}

import std/options, results, chronos, testutils/unittests
import library/libwaku_api, library/libwaku_conf, waku/factory/waku

suite "LibWaku - createNode":
asyncTest "Create node with minimal Relay configuration":
## Given
let libConf = LibWakuConfig(
mode: Relay,
networkConfig: some(
libwaku_conf.NetworkConfig(
bootstrapNodes: @[],
staticStoreNodes: @[],
clusterId: 1,
shardingMode: some(StaticSharding),
autoShardingConfig: none(AutoShardingConfig),
messageValidation: none(MessageValidation),
)
),
storeConfirmation: false,
)

## When
let node = (await createNode(libConf)).valueOr:
raiseAssert error

## Then
check:
not node.isNil()
node.conf.clusterId == 1
node.conf.relay == true

asyncTest "Create node with auto-sharding configuration":
## Given
let libConf = LibWakuConfig(
mode: Relay,
networkConfig: some(
libwaku_conf.NetworkConfig(
bootstrapNodes: @[],
staticStoreNodes: @[],
clusterId: 42,
shardingMode: some(AutoSharding),
autoShardingConfig: some(AutoShardingConfig(numShardsInCluster: 8)),
messageValidation: none(MessageValidation),
)
),
storeConfirmation: false,
)

## When
let node = (await createNode(libConf)).valueOr:
raiseAssert error

## Then
check:
not node.isNil()
node.conf.clusterId == 42
node.conf.shardingConf.numShardsInCluster == 8

asyncTest "Create node with full configuration":
## Given
let libConf = LibWakuConfig(
mode: Relay,
networkConfig: some(
libwaku_conf.NetworkConfig(
bootstrapNodes:
@[
"enr:-QESuEC1p_s3xJzAC_XlOuuNrhVUETmfhbm1wxRGis0f7DlqGSw2FM-p2Vn7gmfkTTnAe8Ys2cgGBN8ufJnvzKQFZqFMBgmlkgnY0iXNlY3AyNTZrMaEDS8-D878DrdbNwcuY-3p1qdDp5MOoCurhdsNPJTXZ3c5g3RjcIJ2X4N1ZHCCd2g"
],
staticStoreNodes:
@[
"/ip4/127.0.0.1/tcp/60000/p2p/16Uuu2HBmAcHvhLqQKwSSbX6BG5JLWUDRcaLVrehUVqpw7fz1hbYc"
],
clusterId: 99,
shardingMode: some(AutoSharding),
autoShardingConfig: some(AutoShardingConfig(numShardsInCluster: 16)),
messageValidation: some(
MessageValidation(
maxMessageSizeBytes: 1024'u64 * 1024'u64, # 1MB
rlnConfig: none(RlnConfig),
)
),
)
),
storeConfirmation: true,
)

## When
let node = (await createNode(libConf)).valueOr:
raiseAssert error

## Then
check:
not node.isNil()
node.conf.clusterId == 99
node.conf.shardingConf.numShardsInCluster == 16
node.conf.maxMessageSizeBytes == 1024'u64 * 1024'u64
node.conf.staticNodes.len == 1
node.conf.relay == true
node.conf.lightPush == true
node.conf.peerExchangeService == true
Loading