Skip to content

feat(mesh): let one node hold several rooms - #23

Merged
ForeverInLaw merged 1 commit into
mainfrom
feat/one-node-many-rooms
Jul 29, 2026
Merged

feat(mesh): let one node hold several rooms#23
ForeverInLaw merged 1 commit into
mainfrom
feat/one-node-many-rooms

Conversation

@ForeverInLaw

Copy link
Copy Markdown
Contributor

Why

A host that gives each conversation its own room has to start a node per conversation. Node identity is per process, so every one of those nodes presents the same peer id from a different port. A remote peer keeps one session per identity: it closes the rest on arrival, and connectPeer declines to dial the others at all because it already has that peer id connected.

Measured over three days, mosh clients only:

node sessions dead <1s discarded handshakes/hour
A 15,494 14,799 205
B 9,772 9,419 131
C 8,527 8,112 113

95%+ of every session an active client opens dies inside a second, against only 6–8 distinct peers each. One identity appeared on 27 different ports inside a single hour. Those are full Noise handshakes — asymmetric crypto — thrown away.

What changed

A node is still born in one room, and every room-less call still means that room, so no existing behaviour moves. It can now join more:

  • Moss_JoinRoom / Moss_LeaveRoom
  • Moss_SubscribeRoom / Moss_UnsubscribeRoom / Moss_PublishRoom

The crypto is untouched — same derivation, same HMAC topic, same AEAD seal. What changed is which key is selected. That never needs guessing: a wire topic is an HMAC, so delivery reads the room off the subscription that created the topic instead of trying keys.

A room that was never joined is refused with MOSS_ERR_NOT_IN_ROOM rather than falling back to the node's own room — the fallback would publish where the intended peers are not listening and surface as lost messages hours later.

Compatibility

  • Existing symbols unchanged; a host that never joins a second room sees nothing different.
  • A joined room is byte-identical to the same room owned outright. TestJoinedRoomIsWireIdenticalToOwningIt pins exactly this: a consolidated client and an already-released one compute the same topic and can talk. Without it this change would silently cut off every shipped version.

Verification

  • 4 new tests: wire-identity, isolation between rooms on one node, unjoined-room refusal, and delivery opening with the subscribed room's key.
  • Each verified to fail when the key selection is reverted to single-room.
  • Full suite green across all 14 packages; go vet ./... clean; c-shared build ok.

A host that gives each conversation its own room had to start a node per
conversation. Node identity is per process, so all of those nodes present the
SAME peer id from different ports, and a remote peer keeps one session per
identity — it closes the rest on arrival and declines to dial the others at
all. Measured across three clients over three days: 33,715 sessions, 32,330 of
them dead inside one second (95%), sustained at 205 / 131 / 113 discarded Noise
handshakes an hour, against only 6-8 distinct peers each. One identity was seen
on 27 different ports within a single hour.

A node is still born in one room and every room-less call still means that one,
so nothing existing changes. It can now join more:

  Moss_JoinRoom / Moss_LeaveRoom
  Moss_SubscribeRoom / Moss_UnsubscribeRoom / Moss_PublishRoom

The crypto is untouched — same derivation, same HMAC topic, same AEAD seal.
What changed is which key is selected, and that never needs guessing: a wire
topic is an HMAC, so delivery reads the room off the subscription that created
it rather than trying keys. Rooms therefore stay isolated on one node, and a
joined room is byte-identical to the same room owned outright, which is what
keeps a consolidated client talking to every already-released one.

A room that was never joined is refused (MOSS_ERR_NOT_IN_ROOM) rather than
quietly falling back to the node's own — that fallback would publish where the
intended peers are not listening and surface as lost messages much later.

Four tests, each verified to fail when the key selection is reverted to
single-room.
@ForeverInLaw
ForeverInLaw merged commit 5391fb8 into main Jul 29, 2026
2 checks passed
@ForeverInLaw
ForeverInLaw deleted the feat/one-node-many-rooms branch July 29, 2026 00:30
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