From 1ce5cafc1c5073840cf00692ec889e4e237dec45 Mon Sep 17 00:00:00 2001 From: fryorcraken Date: Wed, 1 Oct 2025 16:00:22 +1000 Subject: [PATCH] stop range queries on messages with a causal history --- .../reliable_channel/reliable_channel.spec.ts | 67 +++++++++++++------ .../src/reliable_channel/reliable_channel.ts | 7 +- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/packages/sdk/src/reliable_channel/reliable_channel.spec.ts b/packages/sdk/src/reliable_channel/reliable_channel.spec.ts index a7e86e1e48..7b29a6b55d 100644 --- a/packages/sdk/src/reliable_channel/reliable_channel.spec.ts +++ b/packages/sdk/src/reliable_channel/reliable_channel.spec.ts @@ -823,7 +823,7 @@ describe("Reliable Channel", () => { "msg1", channelId, senderId, - [], + [{ messageId: "previous-msg-id" }], 1, undefined, utf8ToBytes("content message") @@ -1002,7 +1002,7 @@ describe("Reliable Channel", () => { }); }); - describe("isSyncOrContentMessage predicate", () => { + describe("isChannelMessageWithCausalHistory predicate", () => { let mockWakuNode: MockWakuNode; let reliableChannel: ReliableChannel; let encoder: IEncoder; @@ -1031,17 +1031,8 @@ describe("Reliable Channel", () => { payload: new Uint8Array([1, 2, 3]) } as IDecodedMessage; - // SDS Message decode throws on malformed payloads, so this will return false - // because decode returns undefined on error which is caught by null check - // However, in current implementation it throws, so we check the behavior - try { - const result = reliableChannel["isSyncOrContentMessage"](msg); - expect(result).to.be.false; - } catch (error) { - // If decode throws, the predicate should ideally handle it - // Current implementation doesn't catch, so we expect the throw - expect(error).to.not.be.undefined; - } + const result = reliableChannel["isChannelMessageWithCausalHistory"](msg); + expect(result).to.be.false; }); it("should return false for different channelId", () => { @@ -1059,11 +1050,11 @@ describe("Reliable Channel", () => { payload: sdsMsg.encode() } as IDecodedMessage; - const result = reliableChannel["isSyncOrContentMessage"](msg); + const result = reliableChannel["isChannelMessageWithCausalHistory"](msg); expect(result).to.be.false; }); - it("should return true for matching sync message", () => { + it("should return false for sync message without causal history", () => { const syncMsg = new SyncMessage( "sync-msg-id", "testChannel", @@ -1078,11 +1069,11 @@ describe("Reliable Channel", () => { payload: syncMsg.encode() } as IDecodedMessage; - const result = reliableChannel["isSyncOrContentMessage"](msg); - expect(result).to.be.true; + const result = reliableChannel["isChannelMessageWithCausalHistory"](msg); + expect(result).to.be.false; }); - it("should return true for matching content message", () => { + it("should return false for content message without causal history", () => { const contentMsg = new ContentMessage( "msg1", "testChannel", @@ -1097,7 +1088,45 @@ describe("Reliable Channel", () => { payload: contentMsg.encode() } as IDecodedMessage; - const result = reliableChannel["isSyncOrContentMessage"](msg); + const result = reliableChannel["isChannelMessageWithCausalHistory"](msg); + expect(result).to.be.false; + }); + + it("should return true for message with causal history", () => { + const contentMsg = new ContentMessage( + "msg1", + "testChannel", + "sender", + [{ messageId: "previous-msg-id" }], + 1, + undefined, + utf8ToBytes("content") + ); + + const msg = { + payload: contentMsg.encode() + } as IDecodedMessage; + + const result = reliableChannel["isChannelMessageWithCausalHistory"](msg); + expect(result).to.be.true; + }); + + it("should return true for sync message with causal history", () => { + const syncMsg = new SyncMessage( + "sync-msg-id", + "testChannel", + "sender", + [{ messageId: "previous-msg-id" }], + 1, + undefined, + undefined + ); + + const msg = { + payload: syncMsg.encode() + } as IDecodedMessage; + + const result = reliableChannel["isChannelMessageWithCausalHistory"](msg); expect(result).to.be.true; }); }); diff --git a/packages/sdk/src/reliable_channel/reliable_channel.ts b/packages/sdk/src/reliable_channel/reliable_channel.ts index 2b3e87bbf3..49b55aa495 100644 --- a/packages/sdk/src/reliable_channel/reliable_channel.ts +++ b/packages/sdk/src/reliable_channel/reliable_channel.ts @@ -15,7 +15,6 @@ import { import { type ChannelId, isContentMessage, - isSyncMessage, MessageChannel, MessageChannelEvent, type MessageChannelOptions, @@ -188,7 +187,7 @@ export class ReliableChannel< ) { this.queryOnConnect = new QueryOnConnect( [this.decoder], - this.isSyncOrContentMessage.bind(this), + this.isChannelMessageWithCausalHistory.bind(this), peerManagerEvents, node.events, this._retrieve.bind(this) @@ -581,7 +580,7 @@ export class ReliableChannel< this.messageChannel.sweepOutgoingBuffer(); } - private isSyncOrContentMessage(msg: T): boolean { + private isChannelMessageWithCausalHistory(msg: T): boolean { // TODO: we do end-up decoding messages twice as this is used to stop store queries. const sdsMessage = SdsMessage.decode(msg.payload); @@ -593,7 +592,7 @@ export class ReliableChannel< return false; } - return isSyncMessage(sdsMessage) || isContentMessage(sdsMessage); + return sdsMessage.causalHistory && sdsMessage.causalHistory.length > 0; } private setupEventListeners(): void {