summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-15 00:56:04 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-15 00:56:04 +0200
commit16d92c96bde3a65fc54a93b4662df30cafc831e4 (patch)
tree4dcdfccc8ed10d8ad28e2fc1935bdb5267c3698d /packages/meshbay-node/src/meshbay_node
parent2acd1b17ad94536e4a0504087adcd9dc936896ea (diff)
downloadmeshbay-16d92c96bde3a65fc54a93b4662df30cafc831e4.tar.gz
fix(node): a chat-epoch notice answers no request, not even the asker's
Revoking a device or removing a member opens a chat epoch, announced to everyone connected to the group, the asker included. Sent inside the handler, the asker's copy was stamped with its request's id and arrived as the answer to device_revoke, before the real one. It now leaves outside the reply context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py26
1 files changed, 17 insertions, 9 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py
index f200884..ed2c43a 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py
@@ -20,6 +20,7 @@ from meshbay_common.protocol import MNP
from meshbay_node import linkpreview, ops
from meshbay_node.chat import FORMAT_SEALED_V1, ReplayedMessage
+from meshbay_node.transport.webrtc.channel import _REPLY_TO
log = logging.getLogger("meshbay_node.transport.webrtc_server")
@@ -115,15 +116,22 @@ class ChatMixin:
self._audit("chat_epoch_failed", reason)
return
self._audit("chat_epoch", f"{reason}:{result['epoch']}")
- # Everyone still connected picks the new key up without reconnecting.
- for session in list(
- (self._ctx.get("groups") or {}).get(group_id, {})
- .get("_peers", {}).values()):
- try:
- session._send({"type": MNP.CHAT_EPOCH_ACK, "v": MNP_VERSION,
- "epoch": result["epoch"]})
- except Exception:
- pass
+ # Everyone still connected picks the new key up without reconnecting —
+ # this session too, which is why the notice leaves outside the reply
+ # context: stamped with the id of the request that caused it (a device
+ # revoked, a member removed), it would arrive as that request's answer.
+ token = _REPLY_TO.set((None, None))
+ try:
+ for session in list(
+ (self._ctx.get("groups") or {}).get(group_id, {})
+ .get("_peers", {}).values()):
+ try:
+ session._send({"type": MNP.CHAT_EPOCH_ACK, "v": MNP_VERSION,
+ "epoch": result["epoch"]})
+ except Exception:
+ pass
+ finally:
+ _REPLY_TO.reset(token)
def _do_chat_directory(self, msg: dict) -> None:
"""