Skip to content

chore!: separate internal and CLI configurations #3357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

fryorcraken
Copy link
Collaborator

@fryorcraken fryorcraken commented Apr 4, 2025

Description

Split WakuNodeConfig object for better separation of concerns and to introduce a tree-like structure to configuration.

Notes:

  • decoupling does increase the codebase, but it seems ultimately necessary, keen to hear opinion of WakuNodeConf usage in c-bindings for examples
  • I am trying to NOT implement added improvements as I go along, because the PR is already huge. But I expect to do after that:
    • get all configs closer to their users (ie relay conf defined by relay protocol)
    • tidy up the sharding/autosharding conf logic (avoid 1024 default, make it clearer what content-topics do, etc)
    • some tidy up on types (usage of uint instead of int)
    • all the TODO introduced in this PR and my previous one feat: introduce preset option #3346
    • nest or use enum on RlnRelayConf so that it's clear what parameters are needed for dynamic or static modes
    • use --preset in nwaku-compose

Changes

  1. Use of Option to avoid dummy defaults. Also, nesting configurations such as RlnRelayConf so that parameters need to be set only if the parent service is enabled; later, it opens the option for each protocol to define their own configuration and then be importer by WakuConf
  2. WakuConf validation logic is better contained; also see (1) where each protocol defining their config parameters can define their own logic; currently, validation logic are scattered between node_factory.nim, waku.nim, etc
  3. the WakuConfBuilder becomes to stop gap shop to build a valid config. It is lenient/flexible (everything is an option). This will enable WakuNodeConf to be translated to a config.
  4. all the above mean that when creating a new libwaku based binary, a minimal CLI Args can be created, and WakuConfBuilder can be used; no need to use the giant WakuNodeConf anymore.
  5. Decoupling WakuNodeConf and WakuConf can also simplify things. for example discv5Only can be a WakuNodeConf only property, that translates to the right parameters on WakuConf (e.g. relay: false, store: false, etc)
  6. Tests! Tests being added to confirm config behaviour (more to be added)
  7. This also enables the creation of edge mode or service mode as per message API, as it will be easy to create an easy CLI/builder option for those, and convert it to the right WakuConf setup.
  8. WakuConfBuilder will provide sane defaults, so that it's easy to build binaries using nwaku (see how chat2.nim is cluttered with config irrelevant to chat). What does not have a default because dev has to choose (eg clusterId), should be provided by a preset/ClusterConf
  9. Removed some CLI args that were not used internally

How to test

  1. use wakunode2 with various CLI args and confirm expected behaviour.
  2. confirm nwaku-compose would work on TWN with this

@fryorcraken fryorcraken force-pushed the separate-node-config branch 3 times, most recently from 0d18e4f to b09f19b Compare April 8, 2025 05:49
wsExtAddress = some(
ip4TcpEndPoint(extIp.get(), wsBindPort.get(DefaultWsBindPort)) &
wsFlag(wssEnabled)
)
except CatchableError:
Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't we just catch that exception in one place in wider try-catch? Seems this function distracted with this exception handling.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll review that for a follow-up PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds like an improvement unrelated to my changes so I'll keep it for a follow-up PR

Copy link
Collaborator

@Ivansete-status Ivansete-status left a comment

Choose a reason for hiding this comment

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

It is getting awesome! Thanks so much for it! 💯
I'm just adding some nitpick comments that I hope you find useful.
Also, not approving yet as I guess there will be more changes in the future.

) == clusterConf.discv5BootstrapNodes

if clusterConf.rlnRelay:
assert conf.rlnRelayConf.isSome
Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpick comment: in "verbs" statements the use of parenthesis is the tendency
Only in "nouns" we avoid parenthesis, such as in len

Suggested change
assert conf.rlnRelayConf.isSome
assert conf.rlnRelayConf.isSome()

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll try to follow this :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Do note that std/options doc do not use () so you may be at odd with the ecosystem: https://nim-lang.org/docs/options.html#isSome%2COption%5BT%5D

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do note that std/options doc do not use () so you may be at odd with the ecosystem: https://nim-lang.org/docs/options.html#isSome%2COption%5BT%5D

ah wow , I didn't know that. Thanks for sharing!
We try to align with the following: https://hackmd.io/@vac/main/%2F5oIVOuQcSM2WKrnDLUPcpg

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Do note that std/options doc do not use () so you may be at odd with the ecosystem: nim-lang.org/docs/options.html#isSome%2COption[T]

ah wow , I didn't know that. Thanks for sharing! We try to align with the following: hackmd.io/@vac/main/%2F5oIVOuQcSM2WKrnDLUPcpg

This is different coding than what was share to me by other members of the nwaku team: https://status-im.github.io/nim-style-guide/language.result.html

I suggest you decide on which one to use and make it obvious in the README

Comment on lines 142 to 145
dns4DomainName = conf.dns4DomainName.map(
proc(dn: DomainName): string =
dn.string
),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shall we also change the dns4DomainName init's parameter's type to DomainName?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not yet sure what is the best usage of the distinct types.

It's best if the sub-protocol define its own distinct types from its own config object. But I don't think I'll do that in this PR. I think I will want to tidy up and have the "one config object per protocol, defined in the protocol module, and imported + nested in WakuConf" approach done in a follow-up PR. When I do that, then we can review distinct type usatge.

Comment on lines 3 to 4
# TODO: this file should be called cluster_conf.nim

Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of renaming the file I think is better to rename the type because we are used to that file/module name when looking for in on VScode

@@ -86,17 +86,24 @@ proc initNode(
else:
peerStore.get()

let (secureKey, secureCert) =
if conf.webSocketConf.isSome and conf.webSocketConf.get().secureConf.isSome:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if conf.webSocketConf.isSome and conf.webSocketConf.get().secureConf.isSome:
if conf.webSocketConf.isSome() and conf.webSocketConf.get().secureConf.isSome():

@@ -86,17 +86,24 @@ proc initNode(
else:
peerStore.get()

let (secureKey, secureCert) =
if conf.webSocketConf.isSome and conf.webSocketConf.get().secureConf.isSome:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if conf.webSocketConf.isSome and conf.webSocketConf.get().secureConf.isSome:
if conf.webSocketConf.isSome() and conf.webSocketConf.get().secureConf.isSome():

relayShardedPeerManagement*: bool
relayServiceRatio*: string

proc log*(conf: WakuConf) =
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think is much better to have a more especific proc name. Having too generic proc names makes it more difficult to lookup in VSCode.

Suggested change
proc log*(conf: WakuConf) =
proc logWakuConf*(conf: WakuConf) =

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think is much better to have a more especific proc name. Having too generic proc names makes it more difficult to lookup in VSCode.

that sucks (lookup in VSCode).

I am a big proponent of "don't repeat context" but I see your point. I'll think on how I can cope with it :)

@fryorcraken fryorcraken force-pushed the separate-node-config branch from b09f19b to 63f0f20 Compare April 10, 2025 11:13
@fryorcraken
Copy link
Collaborator Author

One note on defaults.

I think that the builder should apply agnostic defaults, that work for both wakunode2, libwaku in a desktop app, libwaku in a mobile app, etc.
And that then, the CLI WakuNodeConf can apply/override defaults that are good for wakunode2, probably as a service node.
This raise the whole problem of wakunode2 being an everything binary. My intent is to split wakunode2 in more specialised binaries (I will leave wakunode2 as it is but I hope we can use my new binaries and deprecate it over time).

The first point means that most likely, the config builders should be near their config, in the module of the logic (eg rln relay), because this module is best to know/define good agnostic defaults. And then force setting the parameters that don't have a good generalized/agnostic default (ie, they can change widely from an edge node to a service node).
I'll do that in a follow-up PR.

cc @gabrielmer

Finally, regarding wakunode2 and binaries. It is interesting to have a "everyting" binary for simulation and research, so one can tweak parameters etc.

But I wonder if a better approach would be either:

  1. A new protocol is likely to be contextual. Eg store sync is for store nodes. hence using a more specialized service-node is adapted
  2. Or, encouraging research team to just create a new binary to PoC new protocols.

For (2) to happen, messaging API, and the work I am doing here, should useful so it's super easy to create a new binary, without having to copy-past WakuNodeConf etc, and just have the parameters you need.

WDYT @jm-clius @Ivansete-status @AlbertoSoutullo

Copy link

github-actions bot commented Apr 11, 2025

You can find the image built from this PR at

quay.io/wakuorg/nwaku-pr:3357

Built from 9ee3d27

@fryorcraken fryorcraken force-pushed the separate-node-config branch from 8c587c9 to a3addba Compare April 11, 2025 11:35
rlnRelayTreePath* {.
desc: "Path to the RLN merkle tree sled db (https://github.com/spacejam/sled)",
defaultValue: "",
name: "rln-relay-tree-path"
.}: string

rlnRelayBandwidthThreshold* {.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the one deleted were actually not used

Copy link
Collaborator

Choose a reason for hiding this comment

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

We may only need to adjust the README in the following: https://github.com/vacp2p/rln-interep-contract

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would suggest instead to archive the rln-interep-contract repo cc @jm-clius @kaiserd

@jm-clius
Copy link
Contributor

For (2) to happen, messaging API, and the work I am doing here, should useful so it's super easy to create a new binary, without having to copy-past WakuNodeConf etc, and just have the parameters you need.

For research dev testing, it could be workable - presumably a researcher developing e.g. a new protocol for lightpush incentivisation, would then have to create new binaries based on the existing edge and service specialised binaries? Regression testing could be more difficult, as we will constrain the use case to what is set up for that specific binary.

What would the impact be on QA/DST - they might want to start testing new protocols in parallel (as with Waku Sync). Would they now need to run simulation frameworks for each of n binaries? Also, what are your thoughts on heterogenous use cases? I know for now we often have clear service nodes and clear edge nodes, but I think that we'd see nodes act as both service and edge nodes in any combination or gradient if Waku is to work (e.g. a Store service node for a specific application would act as filter client on that application's content topics). The advantage of an everything binary is that we can see adaptive nodes in practice.

@AlbertoSoutullo
Copy link

AlbertoSoutullo commented Apr 11, 2025

I might have a huge lack of context here, but I can share the PoV from DST.

Nwaku CLI arguments is something that I talked with @Ivansete-status sometimes already.
I have worked in the past with binaries that could easily have more than 150 arguments. Having a lot of arguments is of course something that scares at the beginning, but I can say that there are 3 major things that decreases that difficulty substantially:

  1. Modular configurations. Basically, arguments that depend on other ones. I imagine this like a tree, where the bottom ones are "refinements", and the higher you go, the most important ones you find. This allows you to work with only the most important ones, unless you want to have something very specific, then you can add more arguments to reach the behaviour you want.
  2. Following closely to point 1, the default values are also something extremely important. In this case I think nwaku does a good work, because follows the conservative approach as in not adding functionalities.
  3. Hidden behaviours / related arguments. The perfect example here is --max-connections.
    Description in the Waku documentation: Maximum allowed number of libp2p connections.
    Questions that I might have when I read this: Does this mean full-peers? full-peers + metadata connections? Is it per stream?
    Then, what impact do we have with --max-connections?:
  • Are max-relay-peers affected? Can I have more relay peers than --max-connections? (It should be obvious that no, but there is no harm on clarifying it.). Also, I see that this parameter was deprecated on v0.35.0.
  • New parameter comes in play, relay-service-ratio (it does not appear in the documentation page yet). Very coupled to max-connections.

Another example that come to my mind is --cluster-id, --shard, --content-topic and --num-shards-in-network.
This one is actually crazy imo. It is very confusing and you have to dig a lot (or directly ask the developers) to understand what is going on here. I cannot even remember right now what the latest one could affect, and I have been using nwaku quite a bit.

--filter and --lightpush can also be confusing when you are using them for the first time. You tell the user that they can use waku as a service node, using "light protocols". Then what do I do? I go to my binary and set up filter to true, because I want my node to "use that protocol". The reality is literally the other way around, you want to use filternode to connect to another node that HAS to have filter flag enabled. So yeah, you are using "filter", but it is the node you are connecting to the one enabling that protocol. I am not saying this is correct or not, but I can confidently say this is confusing.

What do I want to say with all of this? I can see the point on (if I understood correctly) separate functionalities in different binaries, but I don't still know why, but this doesn't feel quire right to me. I guess it would depend on where you draw the line.
Do you want a binary for relay protocol and another one for filter? Does that mean that you want to run 2 binaries? If relay filter depends on relay, then you need to interconnect somehow your 2 local binaries.

To me, the current approach of nWaku looks OK, the problem that I see is how the information is delivered to the user, and the problems that there are in the argument themselves as in coupled behaviours.

Of course, again, I might not have the entire context here, and my opinion could change a bit depending on the information that I have. Because indeed this topic is quite complicated on its own, and then there is Waku itself, that it is not precisely an easy project.

Edit: Also, we have to take into account the importance of the previous points. Sadly, in Waku's case, we are not talking about minor optimization issues, like the node is a bit slower, consumes more RAM, or things like that.
Something as confusing as sharding and relay-service-ratio could literally imply the node to not connect properly in the network. Those are the ones (imo) that should be more carefully designed.

@fryorcraken fryorcraken force-pushed the separate-node-config branch from a3addba to aca1512 Compare April 12, 2025 00:53
Copy link

This PR may contain changes to configuration options of one of the apps.

If you are introducing a breaking change (i.e. the set of options in latest release would no longer be applicable) make sure the original option is preserved with a deprecation note for 2 following releases before it is actually removed.

Please also make sure the label release-notes is added to make sure any changes to the user interface are properly announced in changelog and release notes.

@fryorcraken
Copy link
Collaborator Author

  1. Modular configurations. Basically, arguments that depend on other ones. I imagine this like a tree, where the bottom ones are "refinements", and the higher you go, the most important ones you find. This allows you to work with only the most important ones, unless you want to have something very specific, then you can add more arguments to reach the behaviour you want.

This is something I am doing internally (see WakuConf), where indeed, it's a tree.

However, the tooling nim-confutils stops us to do something like that. We would need to do something different.
One option would be a new toml config file that matches the WakuConf tree structure and not use CLI args or nim-confutils.

  1. Hidden behaviours / related arguments. The perfect example here is --max-connections.

Yes, I have also thought the same , filter has a maxPeersToServe, but then there is also a maxConnections. I am guessing they all act as threshold? meaning having maxPeersToServe > maxConnections is equivalent to not setting the maxPeersToServer? Maybe @NagyZoltanPeter can highlight his thought on the matter and the ideal configuration for this

Another example that come to my mind is --cluster-id, --shard, --content-topic and --num-shards-in-network.
This one is actually crazy imo. It is very confusing and you have to dig a lot (or directly ask the developers) to understand what is going on here. I cannot even remember right now what the latest one could affect, and I have been using nwaku quite a bit.

Yep, I totally agree. I first fixed that by adding a --preset option, and then I am fixing the rest with a new draft PR (literally doing it now).
Again, the problem is the flat config. The (internal) tree structure fixes that.

--filter and --lightpush can also be confusing when you are using them for the first time.

Absolutely, in this PR, I am chaing the name to FilterService, etc to help.

What do I want to say with all of this? I can see the point on (if I understood correctly) separate functionalities in different binaries, but I don't still know why, but this doesn't feel quire right to me. I guess it would depend on where you draw the line.
Do you want a binary for relay protocol and another one for filter? Does that mean that you want to run 2 binaries? If relay filter depends on relay, then you need to interconnect somehow your 2 local binaries.

and

Also, what are your thoughts on heterogenous use cases?

My opinion is that the adaptive concept as a full gradient creates both engineer overload and UX/DevEx issues. @AlbertoSoutullo's witness statement reinforcing the case.

While Waku nodes are adaptive, I believe we should provide discreet configurations that we expect 80% (80/20 rule) of users and developers to use.
If developers/users want something outside these discreet configurations, we can always review, or they can always build their own using the library. The idea is to make those configuration easy to deploy (and leave the harder stuff for research or expert users).

I believe this actually matters a lot for Vac-DST. Because at the end of the day, we want simulation to match what users have in their hands. Namely, either a js-waku based web app, or a status app.

My intent is to provide several modes:

  • edge
  • relay
  • service
  • bootstrap

These should end up defined in the Messaging API. These are the mode that must be used by Status app, hence libwaku/c-binding should use those modes instead of enabling individual protocols.

For example relay is the relay mode as of today in Status Desktop (really happy if you have a better name):

  • uses relay to receive and send messages
  • uses p2p reliability protocol to send and receive messages
  • provide filter, light push and peer exchange services
  • uses rendezvous, discv5 and peer exchange for discovery

Now, when running simulations, this is what DST should be using. Because running a bandwidth simulation with only relay, is not really meaning full as Status Desktop also provide those services. So if we want to tell Status users that their bandwidth will average to X, then it needs to be done with filter and light push service enabled (as they are enabled in desktop)

Now, wakunode2 could remain for very specific simulations, such as "relay only", etc. But even tho, it should be possible to take the relay mode and disable discv5 and re-run a simulation. So that the default/baseline parameters are those of relay mode, but we tweak things to test simulations.

WDYT?

--

For research dev testing, it could be workable - presumably a researcher developing e.g. a new protocol for lightpush incentivisation, would then have to create new binaries based on the existing edge and service specialised binaries? Regression testing could be more difficult, as we will constrain the use case to what is set up for that specific binary.

Looking at chat2.nim, I can see that currently this would be a big ask. But the intent is that a researcher should be able to load a preset and a mode, and then just configured whatever they want for their new protocols.

I am not too sure what do you mean regarding regression testing. The researcher's code should still be in nwaku codebase. It just changing the way it's consumed:

  • old: add a config on wakunode2 and use wakunode2
  • new: add a config to WakuConf and build one or two new binaries

So I'd expect the tests to still run as expected.

@fryorcraken fryorcraken changed the title chore: split internal and CLI Waku Configs chore!: split internal and CLI Waku Configs Apr 12, 2025
@fryorcraken fryorcraken changed the title chore!: split internal and CLI Waku Configs chore!: separate internal and CLI configurations Apr 12, 2025
@fryorcraken fryorcraken force-pushed the separate-node-config branch 5 times, most recently from e051473 to 06444ad Compare April 13, 2025 14:50
@fryorcraken
Copy link
Collaborator Author

Not sure why libwaku does not build:

src/waku-org/nwaku  separate-node-config ✔                                                                                                                                                                                                9d19h  
▶ make -j10 libwaku
Building: build/libwaku.so
[NimScript] exec: nim c --out:build/libwaku.so --threads:on --app:lib --opt:size --noMain --mm:refc --header --undef:metrics --nimMainPrefix:libwaku --skipParentCfg:on -d:chronicles_line_numbers \
       -d:chronicles_runtime_filtering=on \
       -d:chronicles_sinks="textlines,json" \
       -d:chronicles_default_output_device=Dynamic \
       -d:chronicles_disabled_topics="eth,dnsdisc.client" \
       --warning:Deprecated:off \
       --warning:UnusedImport:on \
       -d:chronicles_log_level=TRACE  --verbosity:0 --hints:off -d:git_version="v0.35.1-43-g06444a" -d:debug --passL:librln_v0.5.1.a --passL:-lm library/libwaku.nim
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-libp2p/libp2p/transports/wstransport.nim(176, 35) template/generic instantiation of `async` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-libp2p/libp2p/transports/wstransport.nim(186, 17) template/generic instantiation of `checkFutures` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-libp2p/libp2p/errors.nim(30, 24) template/generic instantiation of `readError` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronos/chronos/internal/raisesfutures.nim(247, 12) Warning: No exceptions possible with this operation, `readError` always raises [User]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_enr/capabilities.nim(33, 35) Warning: lightpush, filter, store, relay, sync all have default value 'false', this may be unintentional, either use ';' (semicolon) or explicitly write each default value [ImplicitDefaultValue]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(138, 35) template/generic instantiation of `async` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(169, 10) template/generic instantiation of `setResult` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(165, 7) template/generic instantiation of `warn` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronicles/chronicles.nim(380, 10) template/generic instantiation of `log` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(165, 60) template/generic instantiation of `error` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronos/chronos/internal/raisesfutures.nim(241, 12) Warning: No exceptions possible with this operation, `error` always returns nil [User]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(173, 35) template/generic instantiation of `async` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(214, 10) template/generic instantiation of `setResult` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(200, 7) template/generic instantiation of `warn` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronicles/chronicles.nim(380, 10) template/generic instantiation of `log` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(200, 54) template/generic instantiation of `error` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronos/chronos/internal/raisesfutures.nim(241, 12) Warning: No exceptions possible with this operation, `error` always returns nil [User]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rln_relay/protocol_metrics.nim(3, 78) Warning: imported and not used: 'collector' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_lightpush/common.nim(37, 36) Warning: conversion to enum with holes is unsafe: LightpushStatusCode(response.statusCode) [HoleEnumConv]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_message_event.nim(1, 38) Warning: imported and not used: 'strutils' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_topic_health_change_event.nim(3, 25) Warning: imported and not used: 'base64' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_topic_health_change_event.nim(1, 16) Warning: imported and not used: 'results' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_topic_health_change_event.nim(2, 12) Warning: imported and not used: 'byteutils' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_connection_change_event.nim(3, 25) Warning: imported and not used: 'base64' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_connection_change_event.nim(1, 47) Warning: imported and not used: 'peerid' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-dnsdisc/dnsdisc/client.nim(67, 1) Warning: The raises pragma doesn't work on async procedures - use `async: (raises: [...]) instead. [User]
/home/fryorcraken/src/waku-org/nwaku/waku/node/waku_metrics.nim(34, 47) Error: type mismatch
Expression: parseAndAccumulate(waku_node_errors, cumulativeErrors)
  [1] waku_node_errors: typedesc[IgnoredCollector]
  [2] cumulativeErrors: float64

Expected one of (first mismatch at [position]):
[1] template parseAndAccumulate(collector: Collector; cumulativeValue: float64): float64

stack trace: (most recent call last)
/home/fryorcraken/src/waku-org/nwaku/vendor/nimbus-build-system/vendor/Nim/lib/system/nimscript.nim(421, 18)
/home/fryorcraken/src/waku-org/nwaku/waku.nimble(179, 3) libwakuDynamicTask
/home/fryorcraken/src/waku-org/nwaku/waku.nimble(72, 5) buildLibrary
/home/fryorcraken/src/waku-org/nwaku/vendor/nimbus-build-system/vendor/Nim/lib/system/nimscript.nim(265, 7) exec
/home/fryorcraken/src/waku-org/nwaku/vendor/nimbus-build-system/vendor/Nim/lib/system/nimscript.nim(265, 7) Error: unhandled exception: FAILED: nim c --out:build/libwaku.so --threads:on --app:lib --opt:size --noMain --mm:refc --header --undef:metrics --nimMainPrefix:libwaku --skipParentCfg:on -d:chronicles_line_numbers \
       -d:chronicles_runtime_filtering=on \
       -d:chronicles_sinks="textlines,json" \
       -d:chronicles_default_output_device=Dynamic \
       -d:chronicles_disabled_topics="eth,dnsdisc.client" \
       --warning:Deprecated:off \
       --warning:UnusedImport:on \
       -d:chronicles_log_level=TRACE  --verbosity:0 --hints:off -d:git_version="v0.35.1-43-g06444a" -d:debug --passL:librln_v0.5.1.a --passL:-lm library/libwaku.nim [OSError]
make: *** [Makefile:383: libwaku] Error 1

@fryorcraken
Copy link
Collaborator Author

Not sure why libwaku does not build:

src/waku-org/nwaku  separate-node-config ✔                                                                                                                                                                                                9d19h  
▶ make -j10 libwaku
Building: build/libwaku.so
[NimScript] exec: nim c --out:build/libwaku.so --threads:on --app:lib --opt:size --noMain --mm:refc --header --undef:metrics --nimMainPrefix:libwaku --skipParentCfg:on -d:chronicles_line_numbers \
       -d:chronicles_runtime_filtering=on \
       -d:chronicles_sinks="textlines,json" \
       -d:chronicles_default_output_device=Dynamic \
       -d:chronicles_disabled_topics="eth,dnsdisc.client" \
       --warning:Deprecated:off \
       --warning:UnusedImport:on \
       -d:chronicles_log_level=TRACE  --verbosity:0 --hints:off -d:git_version="v0.35.1-43-g06444a" -d:debug --passL:librln_v0.5.1.a --passL:-lm library/libwaku.nim
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-libp2p/libp2p/transports/wstransport.nim(176, 35) template/generic instantiation of `async` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-libp2p/libp2p/transports/wstransport.nim(186, 17) template/generic instantiation of `checkFutures` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-libp2p/libp2p/errors.nim(30, 24) template/generic instantiation of `readError` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronos/chronos/internal/raisesfutures.nim(247, 12) Warning: No exceptions possible with this operation, `readError` always raises [User]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_enr/capabilities.nim(33, 35) Warning: lightpush, filter, store, relay, sync all have default value 'false', this may be unintentional, either use ';' (semicolon) or explicitly write each default value [ImplicitDefaultValue]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(138, 35) template/generic instantiation of `async` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(169, 10) template/generic instantiation of `setResult` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(165, 7) template/generic instantiation of `warn` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronicles/chronicles.nim(380, 10) template/generic instantiation of `log` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(165, 60) template/generic instantiation of `error` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronos/chronos/internal/raisesfutures.nim(241, 12) Warning: No exceptions possible with this operation, `error` always returns nil [User]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(173, 35) template/generic instantiation of `async` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(214, 10) template/generic instantiation of `setResult` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(200, 7) template/generic instantiation of `warn` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronicles/chronicles.nim(380, 10) template/generic instantiation of `log` from here
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rendezvous/protocol.nim(200, 54) template/generic instantiation of `error` from here
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-chronos/chronos/internal/raisesfutures.nim(241, 12) Warning: No exceptions possible with this operation, `error` always returns nil [User]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_rln_relay/protocol_metrics.nim(3, 78) Warning: imported and not used: 'collector' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/waku/waku_lightpush/common.nim(37, 36) Warning: conversion to enum with holes is unsafe: LightpushStatusCode(response.statusCode) [HoleEnumConv]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_message_event.nim(1, 38) Warning: imported and not used: 'strutils' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_topic_health_change_event.nim(3, 25) Warning: imported and not used: 'base64' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_topic_health_change_event.nim(1, 16) Warning: imported and not used: 'results' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_topic_health_change_event.nim(2, 12) Warning: imported and not used: 'byteutils' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_connection_change_event.nim(3, 25) Warning: imported and not used: 'base64' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/library/events/json_connection_change_event.nim(1, 47) Warning: imported and not used: 'peerid' [UnusedImport]
/home/fryorcraken/src/waku-org/nwaku/vendor/nim-dnsdisc/dnsdisc/client.nim(67, 1) Warning: The raises pragma doesn't work on async procedures - use `async: (raises: [...]) instead. [User]
/home/fryorcraken/src/waku-org/nwaku/waku/node/waku_metrics.nim(34, 47) Error: type mismatch
Expression: parseAndAccumulate(waku_node_errors, cumulativeErrors)
  [1] waku_node_errors: typedesc[IgnoredCollector]
  [2] cumulativeErrors: float64

Expected one of (first mismatch at [position]):
[1] template parseAndAccumulate(collector: Collector; cumulativeValue: float64): float64

stack trace: (most recent call last)
/home/fryorcraken/src/waku-org/nwaku/vendor/nimbus-build-system/vendor/Nim/lib/system/nimscript.nim(421, 18)
/home/fryorcraken/src/waku-org/nwaku/waku.nimble(179, 3) libwakuDynamicTask
/home/fryorcraken/src/waku-org/nwaku/waku.nimble(72, 5) buildLibrary
/home/fryorcraken/src/waku-org/nwaku/vendor/nimbus-build-system/vendor/Nim/lib/system/nimscript.nim(265, 7) exec
/home/fryorcraken/src/waku-org/nwaku/vendor/nimbus-build-system/vendor/Nim/lib/system/nimscript.nim(265, 7) Error: unhandled exception: FAILED: nim c --out:build/libwaku.so --threads:on --app:lib --opt:size --noMain --mm:refc --header --undef:metrics --nimMainPrefix:libwaku --skipParentCfg:on -d:chronicles_line_numbers \
       -d:chronicles_runtime_filtering=on \
       -d:chronicles_sinks="textlines,json" \
       -d:chronicles_default_output_device=Dynamic \
       -d:chronicles_disabled_topics="eth,dnsdisc.client" \
       --warning:Deprecated:off \
       --warning:UnusedImport:on \
       -d:chronicles_log_level=TRACE  --verbosity:0 --hints:off -d:git_version="v0.35.1-43-g06444a" -d:debug --passL:librln_v0.5.1.a --passL:-lm library/libwaku.nim [OSError]
make: *** [Makefile:383: libwaku] Error 1

ok confirmed, this also happens on 6ebb49a14bc59aed03054b1d9f7bf79efbeb195a and doesn't come from my changes.

@fryorcraken fryorcraken marked this pull request as ready for review April 14, 2025 03:17
@fryorcraken
Copy link
Collaborator Author

running fine in nwaku compose:

  • http://waku.fryorcraken.xyz:3000/d/yns_4vFVk/nwaku-monitoring?orgId=1&from=now-6h&to=now
  • /dns4/waku.fryorcraken.xyz/tcp/30304/p2p/16Uiu2HAmMRvhDHrtiHft1FTUYnn6cVA8AWVrTyLUayJJ3MWpUZDB
  • /dns4/waku.fryorcraken.xyz/tcp/8000/wss/p2p/16Uiu2HAmMRvhDHrtiHft1FTUYnn6cVA8AWVrTyLUayJJ3MWpUZDB
  • enr=enr:-O64QDahznjDPhHx3fnMz-X3TqvQJiJDh3BydJ8ICCt9bkPYONbHnaEwhzL0Rx9-OO1NkU8TOsVY1oE8ohANEKxlr-ABgmlkgnY0gmlwhItjh0OKbXVsdGlhZGRyc7g4ABk2FHdha3UuZnJ5b3JjcmFrZW4ueHl6BnZgABs2FHdha3UuZnJ5b3JjcmFrZW4ueHl6Bh9A3gOCcnOTAAEIAAAAAQACAAMABAAFAAYAB4lzZWNwMjU2azGhA4Jgf1WCYre-vaDwlC3GGA3bVyaVbwBK7H6vL2_8AZeKg3RjcIJ2YIN1ZHCCIy2Fd2FrdTIP

Split `WakuNodeConfig` object for better separation of concerns and to introduce a tree-like structure to configuration.
@fryorcraken fryorcraken force-pushed the separate-node-config branch from 06444ad to 239a489 Compare April 14, 2025 03:20
@fryorcraken

This comment was marked as resolved.

@AlbertoSoutullo
Copy link

Now, when running simulations, this is what DST should be using. Because running a bandwidth simulation with only relay, is not really meaning full as Status Desktop also provide those services. So if we want to tell Status users that their bandwidth will average to X, then it needs to be done with filter and light push service enabled (as they are enabled in desktop)

Now, wakunode2 could remain for very specific simulations, such as "relay only", etc. But even tho, it should be possible to take the relay mode and disable discv5 and re-run a simulation. So that the default/baseline parameters are those of relay mode, but we tweak things to test simulations.

WDYT?

I don't think this would involve too much changes from our side.
But I also think we need to analyse what impact protocols have in the bandwidth consumption. So having a baseline of only relay is already very useful when comparing other scenarios with more protocols. Not to mention discovery bandwidth.

@gabrielmer
Copy link
Contributor

ok confirmed, this also happens on 6ebb49a14bc59aed03054b1d9f7bf79efbeb195a and doesn't come from my changes.

Sure? libwaku currently builds properly for me on latest master, at least locally. And the CI passed for that last commit, so looks weird - we should for sure look into it and take care before merging this PR

Copy link
Contributor

@gabrielmer gabrielmer left a comment

Choose a reason for hiding this comment

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

Wooow amazing work! 😍 😍

Thanks so much!

We should double check about why the build fails and added a small remark, really elegant refactor!

@fryorcraken
Copy link
Collaborator Author

ok confirmed, this also happens on 6ebb49a14bc59aed03054b1d9f7bf79efbeb195a and doesn't come from my changes.

Sure? libwaku currently builds properly for me on latest master, at least locally. And the CI passed for that last commit, so looks weird - we should for sure look into it and take care before merging this PR

Indeed, I tried again master and it compiles, will investigate.

@fryorcraken
Copy link
Collaborator Author

ok confirmed, this also happens on 6ebb49a14bc59aed03054b1d9f7bf79efbeb195a and doesn't come from my changes.

Sure? libwaku currently builds properly for me on latest master, at least locally. And the CI passed for that last commit, so looks weird - we should for sure look into it and take care before merging this PR

Indeed, I tried again master and it compiles, will investigate.

libwaku compilation failure is odd, but fixed

@fryorcraken
Copy link
Collaborator Author

running fine in nwaku compose:

* http://waku.fryorcraken.xyz:3000/d/yns_4vFVk/nwaku-monitoring?orgId=1&from=now-6h&to=now

* `/dns4/waku.fryorcraken.xyz/tcp/30304/p2p/16Uiu2HAmMRvhDHrtiHft1FTUYnn6cVA8AWVrTyLUayJJ3MWpUZDB`

* `/dns4/waku.fryorcraken.xyz/tcp/8000/wss/p2p/16Uiu2HAmMRvhDHrtiHft1FTUYnn6cVA8AWVrTyLUayJJ3MWpUZDB`

* `enr=enr:-O64QDahznjDPhHx3fnMz-X3TqvQJiJDh3BydJ8ICCt9bkPYONbHnaEwhzL0Rx9-OO1NkU8TOsVY1oE8ohANEKxlr-ABgmlkgnY0gmlwhItjh0OKbXVsdGlhZGRyc7g4ABk2FHdha3UuZnJ5b3JjcmFrZW4ueHl6BnZgABs2FHdha3UuZnJ5b3JjcmFrZW4ueHl6Bh9A3gOCcnOTAAEIAAAAAQACAAMABAAFAAYAB4lzZWNwMjU2azGhA4Jgf1WCYre-vaDwlC3GGA3bVyaVbwBK7H6vL2_8AZeKg3RjcIJ2YIN1ZHCCIy2Fd2FrdTIP`

dogfooding via nwaku-compose looks good.

@fryorcraken
Copy link
Collaborator Author

all green on commit 55ab0eb

Copy link
Collaborator

@Ivansete-status Ivansete-status left a comment

Choose a reason for hiding this comment

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

Thanks so much for it! 🙌
Adding some more comments that I hope you find useful!
Not approving yet as there are some points that I don't fully agree :)
Also, I'm super impressed how fast you got the Nim skills 🥳

of generateRlnKeystore:
let conf = wakuNodeConf.toKeystoreGeneratorConf().valueOr:
error "Configuration failed", error = error
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
error "Configuration failed", error = error
error "Configuration failed in toKeystoreGeneratorConf", error = error

doRlnKeystoreGenerator(conf)
of inspectRlnDb:
let conf = wakuNodeConf.toInspectRlnDbConf().valueOr:
error "Configuration failed", error = error
Copy link
Collaborator

Choose a reason for hiding this comment

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

Even though chronicles gives line number I like to be as much explicit as possible ;P

Suggested change
error "Configuration failed", error = error
error "Configuration toInspectRlnDbConf failed", error = error

var waku = Waku.new(confCopy).valueOr:
var restServer: WakuRestServerRef = nil

if conf.restServerConf.isSome:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if conf.restServerConf.isSome:
if conf.restServerConf.isSome():

# TODO: severals parameters are only needed when it's dynamic
# change the config to either nest or use enum/type variant so it's obvious
# and then it can be set to `requiresInit`
dynamic*: bool
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think is better the old name because it is much easier to lookup in the code. I suggest adding at least rln prefix to all params :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you can search rln.*dynamic no? The naming redundancy makes the code very verbose.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not super comfy :) but not blocking anyways

name: "discv5-discovery"
.}: bool
.}: Option[bool]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I can't quite agree with that. I prefer not use of Option in this case but I might be missing something :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The Option here allows you to use the twn preset, and yet deactivate discv5 (eg you are running an edge node).

But I can see some counter arguments/alternative solutions:

  1. All waku networks use discv5. So discv5Enabled should not actually be part of the TWN ClusterConf
  2. wakunode2 is not an edge node, so when can assume this option would be barely used.

I am inclined to go with (1). Do you agree?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, 1 sounds good to me. Maybe when using the edge preset option, the discv5-discovery should be false and, as you mention, in all service preset options, the discv5 should be true.

Comment on lines +235 to +236
conf.clusterId, conf.networkConf, conf.discv5Conf, conf.webSocketConf,
conf.wakuFlags, conf.dnsAddrsNameServers, conf.portsShift, clientId,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I prefer less parameters

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree. I added a todo. this should be done as we reduce the number of parameters on Netconfig.init.

I suggest we do it in a follow pr to limit the scope of this PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I started to look into this.

I think we can overhaul NetConfig to align it with `WakuConf. But the scale of change is such that I think it's wiser to just leave it as it is and tackle it in a follow up PR.

Ideally, NetConfig should just be nested in WakuConf. And that will solve this kind of problem because anything needed network conf, such as enr generation, can just get this new NetConfig/NetworkConf parameter.

error "Retrieving dynamic bootstrap nodes failed",
error = dynamicBootstrapNodesRes.error
continue
if waku.conf.dnsDiscoveryConf.isSome:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if waku.conf.dnsDiscoveryConf.isSome:
if waku.conf.dnsDiscoveryConf.isSome():

@@ -387,10 +357,17 @@ proc startWaku*(waku: ptr Waku): Future[Result[void, string]] {.async.} =
return err("Error in updateApp: " & $error)

## Discv5
if waku[].conf.discv5Discovery or waku[].conf.discv5Only:
if conf.discv5Conf.isSome:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if conf.discv5Conf.isSome:
if conf.discv5Conf.isSome():

return ok()

proc validateNoEmptyStrings(wakuConf: WakuConf): Result[void, string] =
if wakuConf.networkConf.dns4DomainName.isSome and
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if wakuConf.networkConf.dns4DomainName.isSome and
if wakuConf.networkConf.dns4DomainName.isSome() and

There are some more in the rest of the proc

Comment on lines +53 to +54
macro with(builderType: untyped, argName: untyped, argType: untyped) =
result = generateWithProc(builderType, argName, argType, argType)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would avoid the use of macro's as much as possible.
I encourage to use the same approach being used in the following, which is simpler and more explicit:

Also, is a good opportunity to split this file in different modules :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would avoid the use of macro's as much as possible.

Why?

Copy link
Collaborator

@Ivansete-status Ivansete-status Apr 17, 2025

Choose a reason for hiding this comment

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

Why?

Macros cause huge difficulties when debugging. We experience that when dealing with web3.
Besides, the suggested change breaks consistency with other builder-patterns, that have a more explicit "with..." procs. Using a too generic proc name, e.g,. with, makes it more difficult to look up where it is being used.

@fryorcraken
Copy link
Collaborator Author

@Ivansete-status can you please clarify the points that are blocking the approval? I will not be able to tackle everything before my break.

@Ivansete-status
Copy link
Collaborator

@Ivansete-status can you please clarify the points that are blocking the approval? I will not be able to tackle everything before my break.

IMO, the most important point is related to macro. I think it will be better if we can simplify it somehow. Thanks for the patience! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants