fix(kademlia): allow clientMode without switch.mount

ServiceDiscovery.new(client=true) installs no inbound handler, so
switch.mount always failed. Skip mount for clientMode and keep the
protocol for outbound mix lookups only. Add a unit test and document
relative CHAT_UI paths in the mixnet chat-ui launcher.
This commit is contained in:
Prem Chaitanya Prathi 2026-07-09 18:41:49 +05:30
parent 03d3507db9
commit 4a3db364e7
No known key found for this signature in database
6 changed files with 57 additions and 5 deletions

View File

@ -391,6 +391,14 @@ proc mountKademlia*(
node.wakuKademlia = wk
# ServiceDiscovery.new(client=true) intentionally installs no inbound stream
# handler so this node is not dialable as a DHT peer. switch.mount requires a
# handler, so skip mount in clientMode. Outbound lookups still work: dial +
# GET_ADS use the codec string without advertising it in peerInfo.protocols.
if config.clientMode:
info "Kademlia service discovery ready (clientMode, lookup-only, not mounted)"
return ok()
let mountRes = catch:
node.switch.mount(wk.protocol)
mountRes.isOkOr:

View File

@ -83,10 +83,16 @@ cd simulations/mixnet/chat-ui
Each opens a GUI. The bottom status bar should show **`MIX 5/4`** (mix pool full)
with the send button enabled.
To iterate on a local chat-ui checkout instead of the pushed branch:
To iterate on a local chat-ui checkout instead of the pushed branch, clone it
**beside** `logos-delivery` and point `CHAT_UI` at it. The path is relative to
where you run the script (`run_chat_ui.sh` resolves it to an absolute path):
```bash
CHAT_UI="$HOME/Code/logos-chat-ui" ./run_chat_ui.sh A
# from the same parent dir where you cloned logos-delivery:
git clone -b feat/logos-testnetv02-mix https://github.com/logos-co/logos-chat-ui
# then, back in simulations/mixnet/chat-ui:
CHAT_UI=../../../../logos-chat-ui ./run_chat_ui.sh A
```
## 5. Exchange messages

View File

@ -21,6 +21,8 @@ export CHAT_SHARD_ID=0
export CHAT_MIN_MIX_POOL=4
export CHAT_MIX_REQUIRED=1 # force Required (mix) mode without the UI toggle
# logos-chat-ui flake to run. Override with a local checkout to iterate, e.g.
# CHAT_UI="$HOME/Code/logos-chat-ui" ./run_chat_ui.sh A
# logos-chat-ui flake to run. Override with a local checkout to iterate — a path
# relative to where you run the script works (run_chat_ui.sh resolves it to an
# absolute path). With logos-chat-ui cloned beside logos-delivery, e.g.:
# CHAT_UI=../../../../logos-chat-ui ./run_chat_ui.sh A
export CHAT_UI="${CHAT_UI:-github:logos-co/logos-chat-ui?ref=feat/logos-testnetv02-mix}"

View File

@ -32,5 +32,14 @@ cp -f "$SIM/rln_tree.db" "$DIR/" 2>/dev/null \
|| { echo "missing rln_tree.db — run ../build_setup.sh first"; exit 1; }
cp -f "$SIM"/rln_keystore_*.json "$DIR/"
# If CHAT_UI is a local checkout (not a flake ref like github:/git+/path:),
# resolve it to an absolute path NOW — before we cd into the per-client run dir
# below — so it can be passed relative to where you invoke this script (e.g.
# CHAT_UI=../../../../logos-chat-ui). Flake refs don't exist on disk, so the
# `-e` test skips them and they're left untouched.
if [ -e "$CHAT_UI" ]; then
CHAT_UI="$(cd "$CHAT_UI" && pwd)"
fi
cd "$DIR"
exec nix run "$CHAT_UI" --accept-flake-config

View File

@ -36,6 +36,31 @@ suite "Waku Kademlia service discovery":
await wk.stop()
await switch.stop()
asyncTest "clientMode starts without mounting (lookup-only)":
## ServiceDiscovery client=true omits the inbound handler; mount would raise.
## Client nodes must still construct + start the protocol for outbound lookups.
let
switch = newTestSwitch()
wk = kad_utils.newTestKademlia(
switch,
servicesToDiscover = @["/mix/1.0.0"],
clientMode = true,
xprPublishing = false,
)
await switch.start()
await wk.start()
await sleepAsync(FUTURE_TIMEOUT)
check:
not wk.protocol.isNil()
wk.protocol.clientMode
# Codec must not be advertised — peers should not dial us for kad.
wk.protocol.codec notin switch.peerInfo.protocols
await wk.stop()
await switch.stop()
suite "extractMixPubKey":
proc validKeyBytes(): seq[byte] =
var b = newSeq[byte](Curve25519KeySize)

View File

@ -41,7 +41,9 @@ proc newTestKademlia*(
)
.tryGet()
switch.mount(wk.protocol)
# clientMode has no inbound stream handler; mount would fail (see mountKademlia).
if not clientMode:
switch.mount(wk.protocol)
wk
proc buildExtendedPeerRecord*(