From 2cfeef588d654828a709ef1770b31589ff2032ea Mon Sep 17 00:00:00 2001 From: agessaman Date: Thu, 16 Jul 2026 23:22:02 -0700 Subject: [PATCH] fix(room_server): stop advancing the author sync watermark on post --- repeater/handler_helpers/room_server.py | 14 ++++++-------- tests/test_handler_helpers_room_server.py | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/repeater/handler_helpers/room_server.py b/repeater/handler_helpers/room_server.py index de3b85d..89a56e6 100644 --- a/repeater/handler_helpers/room_server.py +++ b/repeater/handler_helpers/room_server.py @@ -321,17 +321,15 @@ class RoomServer: f"{len(all_clients)} authenticated client(s)" ) - # Update client's sync_since to this message's timestamp - # This prevents the author from receiving their own message back - # Also update activity timestamp (they're clearly active if posting) - logger.debug( - f"Room '{self.room_name}': Updating author's sync_since to {post_timestamp} " - f"to prevent echo" - ) + # Refresh the author's activity timestamp (they're clearly active + # if posting). The sync_since watermark is deliberately NOT + # advanced here: it moves only when a push is ACKed, and self-echo + # is already prevented by the author exclusion in the + # unsynced-message query. Advancing it on post would skip other + # authors' older, still-unsynced messages for this client. self.db.upsert_client_sync( room_hash=f"0x{self.room_hash:02X}", client_pubkey=client_pubkey.hex(), - sync_since=post_timestamp, # Don't send this message back to author last_activity=time.time(), ) diff --git a/tests/test_handler_helpers_room_server.py b/tests/test_handler_helpers_room_server.py index 2754113..1dc8f03 100644 --- a/tests/test_handler_helpers_room_server.py +++ b/tests/test_handler_helpers_room_server.py @@ -85,6 +85,28 @@ async def test_room_server_add_post_stores_message_and_updates_sync_state(): assert kwargs["client_pubkey"] == (b"A" * 32).hex() +@pytest.mark.asyncio +async def test_room_server_add_post_does_not_advance_author_sync_watermark(): + """Posting must not move the author's sync_since watermark: it advances only + when a push is ACKed. Self-echo is prevented by the author exclusion in the + unsynced-message query, so an on-post advance would only skip OTHER authors' + older, still-unsynced messages for this client. Activity is still refreshed.""" + db = _FakeDB() + rs = _make_room_server(db=db, acl=_FakeACL([_FakeClient(b"C" * 32)])) + + ok = await rs.add_post( + client_pubkey=b"A" * 32, + message_text="newer post", + sender_timestamp=222, + txt_type=TXT_TYPE_PLAIN, + ) + + assert ok is True + kwargs = db.upsert_client_sync.call_args.kwargs + assert "sync_since" not in kwargs + assert kwargs["last_activity"] > 0 + + @pytest.mark.asyncio async def test_room_server_add_post_truncates_and_rate_limits_client(): db = _FakeDB()