Skip to content

Demo: Feat/messaging conf proof#3973

Closed
fcecin wants to merge 1 commit into
poc/structured-api-interfacefrom
feat/messaging-conf-proof
Closed

Demo: Feat/messaging conf proof#3973
fcecin wants to merge 1 commit into
poc/structured-api-interfacefrom
feat/messaging-conf-proof

Conversation

@fcecin

@fcecin fcecin commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is a WIP that demonstrates a partial direction for closing #3845, developed on top of #3946. This code can be adapted in any case if we don't merge #3946 (i.e. scrapped for ideas or parts). This code does not include the recently merged refactor #3970, since that isn't (or wasn't, at the time I branched off) in the commit history of the #3946 branch.

Even as an AI tracer, this isn't complete. This was submitted as a communication artifact (I think we are going to be incorporating this more in our workflow -- PRs/commits as communication/intent/design artifacts, not for code review or merge, which should always depend on split-up commits of manageable size). So the idea here is using code to communicate intent. This is not to be tracked as something pending merge; this will be probably closed (or maybe it gets an upgrade -- we can "draw" the real stuff on top of AI tracers...).

Changes

(Note: full genAI)

Summary

This changeset introduces an explicit, layered configuration model for the delivery node and wires it into the library entry points. It adds three configuration types, one per API layer, and the downward inference between them; it relocates the operation-mode protocol expansion out of the kernel configuration and into the messaging-layer inference; it resolves network presets at the messaging layer; and it makes the reliable-channels configuration a live, caller-supplied object rather than a set of hardcoded constants.

The change is built on the structured API interface introduced in PR #3946 (the LogosDelivery facade and its broker-based sub-interfaces). It implements the three-configuration-object direction recorded in the review discussion of PR #3925 and addresses requirements stated in issue #3845 (a developer-facing messaging entry shaped as (mode, preset, overrides), a separate full-configuration node entry, and the removal of the --mode CLI option).

Scope is limited to the library and CLI surfaces and their tests. The C FFI surface is not migrated in this changeset; see "Out of scope" below. Footprint: 18 files changed, 374 insertions, 181 deletions.

New configuration types

logos_delivery/api/kernel_conf.nim (new)

Introduces KernelConf as a type alias of the existing WakuNodeConf:

type KernelConf* = WakuNodeConf

The module re-exports tools/confutils/cli_args so that the alias carries the full configuration machinery (field accessors, ConfResult, defaultWakuNodeConf, toWakuConf). Using an alias rather than a new type makes the kernel-layer naming available to new code with no churn at existing call sites, which continue to reference WakuNodeConf.

logos_delivery/api/messaging_conf.nim (new)

Defines MessagingConf, the messaging-layer configuration, as an all-Option partial of twelve fields. Each field is Option[T]; a set value expresses caller intent, and an unset value defers to the kernel default. The fields and their kernel-configuration counterparts are:

MessagingConf field Kernel field Conversion
clusterId: Option[uint16] clusterId direct (Option to Option)
numShardsInCluster: Option[uint16] numShardsInNetwork unwrap
p2pTcpPort: Option[Port] tcpPort unwrap
discv5UdpPort: Option[Port] discv5UdpPort unwrap
listenIpv4: Option[IpAddress] listenAddress unwrap
maxMessageSize: Option[string] maxMessageSize unwrap
entryNodes: Option[seq[string]] entryNodes unwrap
ethRpcEndpoints: Option[seq[string]] ethClientUrls: seq[EthRpcUrl] map each element through EthRpcUrl(...)
rlnContractAddress: Option[string] rlnRelayEthContractAddress plus rlnRelay = some(true) unwrap; setting the address enables RLN
rlnChainId: Option[uint] rlnRelayChainId unwrap
rlnEpochSizeSec: Option[uint] rlnEpochSizeSec: Option[uint64] widen uint to uint64, wrap
reliabilityEnabled: Option[bool] reliabilityEnabled direct

The inference is performed by proc toKernelConf*(m: MessagingConf, mode: WakuMode): ConfResult[KernelConf]. It begins from defaultWakuNodeConf() and applies the work in two stages.

First, operation-mode expansion: the mode parameter (Core or Edge) is expanded into the kernel's flat protocol flags. Core sets relay, filter, lightpush, discv5Discovery = some(true), peerExchange, rendezvous, and, when no rate limits are otherwise present, a default set of per-protocol rate limits (filter:100/1s, lightpush:5/1s, px:5/1s). Edge sets peerExchange = true and disables relay, filter, lightpush, and store.

Second, field inference: for each MessagingConf field, a set value is written to the corresponding kernel field; an unset value leaves the kernel default in place.

logos_delivery/channels/channels_conf.nim (new)

Defines ChannelsConf, the reliable-channels configuration, as an all-Option partial of nine fields grouped by concern: segmentation (segmentationEnableReedSolomon: Option[bool], segmentationSegmentSizeBytes: Option[int]); scalable data sync (sdsAcknowledgementTimeoutMs: Option[int], sdsMaxRetransmissions: Option[int], sdsCausalHistorySize: Option[int]); rate limiting (rateLimitEnabled: Option[bool], rateLimitEpochPeriodSec: Option[int]); and pluggable dependency-injection backends (segmentationPersistence: Option[SegmentationPersistence], sdsPersistence: Option[Persistence]).

The numeric field types are int, matching the underlying segmentation, SDS, and rate-limit configuration structs. The two persistence fields reference the existing component backend types (SegmentationPersistence from the segmentation module and the nim-sds Persistence from types/persistence).

logos_delivery/api/messaging_conf_preset.nim (new)

Provides preset resolution and override merging for the messaging layer: proc resolvePreset*(preset: string): ConfResult[MessagingConf] and proc merge*(base, overrides: MessagingConf): MessagingConf.

resolvePreset looks the preset name up through toNetworkPresetConf (the existing name-to-NetworkPresetConf lookup, now exported; see CLI changes below) and maps the resulting NetworkPresetConf into the messaging-layer fields it implies: clusterId from clusterId; numShardsInCluster from shardingConf.numShardsInCluster when sharding is automatic; maxMessageSize from maxMessageSize; entryNodes from entryNodes when non-empty; rlnContractAddress, rlnChainId, and rlnEpochSizeSec when RLN relay is enabled and the contract address is non-empty (with rlnChainId truncated from the preset's UInt256 chain id to uint, and rlnEpochSizeSec narrowed from uint64 to uint); and reliabilityEnabled from the preset's reliability flag. Node-local fields that presets do not define (listening port, discovery UDP port, bind address, Ethereum RPC endpoints) are left unset. An empty preset name resolves to an empty MessagingConf.

merge combines two MessagingConf values field by field: a set field in overrides takes precedence, otherwise the value from base is retained.

Entry-point and inference wiring

logos_delivery/api/logos_delivery_interface.nim

Imports and re-exports messaging_conf and channels_conf so consumers of the facade interface obtain MessagingConf and ChannelsConf. The startAsClient broker method signature gains two parameters; it changes from (mode: WakuMode, preset: string) to (mode: WakuMode, preset: string, overrides: MessagingConf, channelsConf: ChannelsConf).

logos_delivery/logos_delivery.nim (facade implementation)

The LogosDelivery type gains a private channelsConf: ChannelsConf field, set at client start and applied when the reliable-channel manager is mounted. startAsClient is updated to match the new interface signature; its body now resolves the preset into a base MessagingConf, merges the caller's overrides on top, and infers the kernel configuration from the result:

let base = ?resolvePreset(preset)
let msgConf = base.merge(overrides)
var conf: KernelConf = ?msgConf.toKernelConf(mode)
conf.preset = preset

The kernel configuration continues to carry preset, so the kernel performs its own preset resolution for the node-local and protocol fields the messaging layer does not model; explicitly set values win over the preset through the existing builder precedence machinery. initReliableChannelManager passes the stored channelsConf to the manager. startAsNode receives a brief doc comment describing it as the full-configuration node entry that starts a kernel node without a messaging client. The previous direct construction of the kernel configuration in startAsClient (defaultWakuNodeConf() followed by conf.mode = some(mode)) is removed, and the now-unused std/options import is dropped.

logos_delivery/channels/reliable_channel_manager.nim

Imports and re-exports channels_conf. The manager type gains a private channelsConf: ChannelsConf field; the new constructor gains a corresponding channelsConf parameter. createReliableChannel now sources segmentation, SDS, and rate-limit settings from the manager's ChannelsConf, each falling back to the previous default constant when unset. The segmentation persistence backend is sourced from segmentationPersistence (default nil); the SDS persistence backend uses sdsPersistence when present and otherwise the existing persistency helper. The rate-limit configuration now sets its enabled field from rateLimitEnabled (default false), which preserves the prior behavior in which the rate limiter was constructed but not enabled.

logos_delivery/waku/api/api.nim

The legacy mountReliableChannelManager call site is updated to pass a default ChannelsConf() to the manager constructor, preserving its prior behavior (all unset, hence component defaults).

CLI configuration surface

tools/confutils/cli_args.nim

The mode field is removed from WakuNodeConf. As this field backed the --mode CLI option, the option is removed from the node binary, consistent with the direction in issue #3845 that the operation mode is a messaging-API concept. The operation-mode expansion branch is removed from toWakuConf(n: WakuNodeConf): the builder no longer derives protocol flags from a mode value and reads the flat protocol flags directly, with the equivalent expansion now occurring at the messaging layer in toKernelConf. toNetworkPresetConf is exported so the preset lookup can be reused by resolvePreset; it remains the single source of preset definitions (twn, logos.dev/logosdev, logos.test/logostest).

Test changes

tests/api/test_messaging_conf.nim adds a suite covering toKernelConf inference (operation-mode expansion for Core and Edge; per-field application including cluster id, listening port, reliability, RLN contract enabling RLN relay, Ethereum RPC endpoint mapping, and RLN chain id and epoch size) and a suite covering preset resolution and merge (preset-to-field mapping for representative presets, the empty preset producing a no-op, and override precedence in merge).

tests/api/test_node_conf.nim: the mode-driven configuration suite is reframed to exercise the messaging-to-kernel-to-built-configuration path (MessagingConf().toKernelConf(mode) followed by toWakuConf()); tests whose subject was the removed kernel mode field (including JSON parsing of a mode key and a "mode overrides explicit flags" case) are removed.

tests/api/test_api_send.nim, tests/api/test_api_receive.nim, tests/api/test_api_subscription.nim, tests/api/test_api_health.nim, tests/channels/test_reliable_channel_send_receive.nim, and tests/test_waku.nim: node setup helpers that previously set conf.mode are migrated to construct the kernel configuration through MessagingConf().toKernelConf(mode), routing the tests through the new production path. tests/api/test_all.nim registers the messaging configuration test module.

Behavioral and compatibility notes

The --mode CLI option is removed from the node binary; operation mode is expressed at the messaging entry point. The startAsClient entry point gains two required parameters (overrides and channelsConf). The operation-mode enumeration in use is {Core, Edge}; there is no unset/none mode. The default kernel configuration corresponds to a full-routing node, with mode expansion applied only through the messaging entry point. The reliable-channels configuration object is supplied at client start; when all of its fields are unset (including the default supplied on the legacy mount path), channel behavior is identical to the previous hardcoded defaults.

Validation

The library and node binary both compile (build/wakunode2, build/liblogosdelivery.so). The full test suite passes: 42 common tests, 826 library tests (13 skipped), 36 node tests, with zero failures.

Out of scope (follow-ups)

The C FFI surface is not migrated to the layered entry points in this changeset; the FFI continues to use its existing configuration path. A separate effort is required to route the FFI through the facade entry points, to parse the messaging entry as {mode, preset, overrides, channelconf} and the node entry as a full kernel configuration, and to retire the FFI's own legacy configuration object and reliability carrier.

Two configuration fields described in the PR #3925 review discussion are not included, as they have no current backing: a prioritized store-node list at the messaging layer (the kernel exposes only a single store node) and a configuration-installable channel encryption backend (channel encryption is currently installed at runtime through the request-broker mechanism).

@fcecin
fcecin changed the base branch from master to poc/structured-api-interface June 23, 2026 11:13
@fcecin

fcecin commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Obsolete, to be replaced by new config PR soon.

@fcecin fcecin closed this Jul 2, 2026
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.

1 participant