From c48accb513f1197ea78513b0d9e0b625878c06b8 Mon Sep 17 00:00:00 2001 From: Ivan FB <128452529+Ivansete-status@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:32:39 +0100 Subject: [PATCH] waku_store: better response when the store is requested with wrong cursor (#2231) --- tests/waku_store/test_wakunode_store.nim | 41 ++++++++++++++++++++++++ waku/node/waku_node.nim | 4 +++ waku/waku_store/common.nim | 17 +++++++++- 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/tests/waku_store/test_wakunode_store.nim b/tests/waku_store/test_wakunode_store.nim index 117a1cc93..2eff88e22 100644 --- a/tests/waku_store/test_wakunode_store.nim +++ b/tests/waku_store/test_wakunode_store.nim @@ -259,3 +259,44 @@ procSuite "WakuNode - Store": ## Cleanup waitFor allFutures(client.stop(), server.stop(), filterSource.stop()) + + test "history query should return INVALID_CURSOR if the cursor has empty data in the request": + ## Setup + let + serverKey = generateSecp256k1Key() + server = newTestWakuNode(serverKey, ValidIpAddress.init("0.0.0.0"), Port(0)) + clientKey = generateSecp256k1Key() + client = newTestWakuNode(clientKey, ValidIpAddress.init("0.0.0.0"), Port(0)) + + waitFor allFutures(client.start(), server.start()) + + let mountArchiveRes = server.mountArchive(archiveA) + assert mountArchiveRes.isOk(), mountArchiveRes.error + + waitFor server.mountStore() + + client.mountStoreClient() + + ## Forcing a bad cursor with empty digest data + var data: array[32, byte] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + let cursor = HistoryCursor( + pubsubTopic: "pubsubTopic", + senderTime: now(), + storeTime: now(), + digest: waku_archive.MessageDigest(data: data) + ) + + ## Given + let req = HistoryQuery(contentTopics: @[DefaultContentTopic], cursor: some(cursor)) + let serverPeer = server.peerInfo.toRemotePeerInfo() + + ## When + let queryRes = waitFor client.query(req, peer=serverPeer) + + ## Then + check not queryRes.isOk() + + check queryRes.error == "BAD_REQUEST: invalid cursor" + + # Cleanup + waitFor allFutures(client.stop(), server.stop()) diff --git a/waku/node/waku_node.nim b/waku/node/waku_node.nim index 51362e50d..e09d1a27a 100644 --- a/waku/node/waku_node.nim +++ b/waku/node/waku_node.nim @@ -816,6 +816,10 @@ proc mountStore*(node: WakuNode) {.async, raises: [Defect, LPError].} = # TODO: Review this handler logic. Maybe, move it to the appplication code let queryHandler: HistoryQueryHandler = proc(request: HistoryQuery): Future[HistoryResult] {.async.} = + if request.cursor.isSome(): + request.cursor.get().checkHistCursor().isOkOr: + return err(error) + let request = request.toArchiveQuery() let response = await node.wakuArchive.findMessages(request) return response.toHistoryResult() diff --git a/waku/waku_store/common.nim b/waku/waku_store/common.nim index edd86ea4b..0af324ccc 100644 --- a/waku/waku_store/common.nim +++ b/waku/waku_store/common.nim @@ -4,7 +4,7 @@ else: {.push raises: [].} import - std/options, + std/[options,sequtils], stew/results, stew/byteutils, nimcrypto/sha2 @@ -99,3 +99,18 @@ proc `$`*(err: HistoryError): string = "SERVICE_UNAVAILABLE" of HistoryErrorKind.UNKNOWN: "UNKNOWN" + +proc checkHistCursor*(self: HistoryCursor): Result[void, HistoryError] = + if self.pubsubTopic.len == 0: + return err(HistoryError(kind: BAD_REQUEST, + cause: "empty pubsubTopic")) + if self.senderTime == 0: + return err(HistoryError(kind: BAD_REQUEST, + cause: "invalid senderTime")) + if self.storeTime == 0: + return err(HistoryError(kind: BAD_REQUEST, + cause: "invalid storeTime")) + if self.digest.data.all(proc (x: byte): bool = x == 0): + return err(HistoryError(kind: BAD_REQUEST, + cause: "empty digest")) + return ok()