From d2dada68a80f8b57a516a7a3c61a713b5936b79f Mon Sep 17 00:00:00 2001 From: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Thu, 3 Feb 2022 18:11:45 +0100 Subject: [PATCH 01/22] Refactor timestamps type from float64 to int64 (milliseconds resolution) --- tests/v2/test_jsonrpc_waku.nim | 8 +- tests/v2/test_message_store.nim | 20 ++--- tests/v2/test_waku_pagination.nim | 6 +- tests/v2/test_waku_store.nim | 76 +++++++++---------- tests/v2/test_wakunode.nim | 2 +- waku/common/wakubridge.nim | 2 +- waku/v2/node/jsonrpc/jsonrpc_callsigs.nim | 2 +- waku/v2/node/jsonrpc/jsonrpc_types.nim | 2 +- waku/v2/node/jsonrpc/jsonrpc_utils.nim | 8 +- waku/v2/node/jsonrpc/store_api.nim | 6 +- waku/v2/node/quicksim2.nim | 10 +-- .../v2/node/storage/message/message_store.nim | 2 +- .../storage/message/waku_message_store.nim | 10 +-- .../message/00002_addSenderTimeStamp.up.sql | 4 +- waku/v2/protocol/waku_message.nim | 10 ++- .../waku_rln_relay/waku_rln_relay_utils.nim | 15 ++-- waku/v2/protocol/waku_store/waku_store.nim | 50 ++++++------ .../protocol/waku_store/waku_store_types.nim | 4 +- waku/v2/utils/pagination.nim | 4 +- 19 files changed, 126 insertions(+), 115 deletions(-) diff --git a/tests/v2/test_jsonrpc_waku.nim b/tests/v2/test_jsonrpc_waku.nim index 973d4e3137..a3cb320a7f 100644 --- a/tests/v2/test_jsonrpc_waku.nim +++ b/tests/v2/test_jsonrpc_waku.nim @@ -102,7 +102,7 @@ procSuite "Waku v2 JSON-RPC API": response == true # Publish a message on the default topic - response = await client.post_waku_v2_relay_v1_message(defaultTopic, WakuRelayMessage(payload: @[byte 1], contentTopic: some(defaultContentTopic), timestamp: some(epochTime()))) + response = await client.post_waku_v2_relay_v1_message(defaultTopic, WakuRelayMessage(payload: @[byte 1], contentTopic: some(defaultContentTopic), timestamp: some(int64(epochTime())))) check: # @TODO poll topic to verify message has been published @@ -260,7 +260,7 @@ procSuite "Waku v2 JSON-RPC API": let client = newRpcHttpClient() await client.connect("127.0.0.1", rpcPort, false) - let response = await client.get_waku_v2_store_v1_messages(some(defaultTopic), some(@[HistoryContentFilter(contentTopic: defaultContentTopic)]), some(0.float64), some(9.float64), some(StorePagingOptions())) + let response = await client.get_waku_v2_store_v1_messages(some(defaultTopic), some(@[HistoryContentFilter(contentTopic: defaultContentTopic)]), some(0.int64), some(9.int64), some(StorePagingOptions())) check: response.messages.len() == 8 response.pagingOptions.isSome() @@ -573,7 +573,7 @@ procSuite "Waku v2 JSON-RPC API": pubSubTopic = "polling" contentTopic = defaultContentTopic payload = @[byte 9] - message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(epochTime())) + message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(int64(epochTime()))) topicCache = newTable[string, seq[WakuMessage]]() await node1.start() @@ -664,7 +664,7 @@ procSuite "Waku v2 JSON-RPC API": pubSubTopic = "polling" contentTopic = defaultContentTopic payload = @[byte 9] - message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(epochTime())) + message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(int64(epochTime()))) topicCache = newTable[string, seq[WakuMessage]]() await node1.start() diff --git a/tests/v2/test_message_store.nim b/tests/v2/test_message_store.nim index 0f898d4c0a..8c500f9a46 100644 --- a/tests/v2/test_message_store.nim +++ b/tests/v2/test_message_store.nim @@ -16,9 +16,9 @@ suite "Message Store": topic = ContentTopic("/waku/2/default-content/proto") pubsubTopic = "/waku/2/default-waku/proto" - t1 = epochTime() - t2 = epochTime() - t3 = high(float64) + t1 = int64(epochTime()) + t2 = int64(epochTime()) + t3 = int64(high(float64)) var msgs = @[ WakuMessage(payload: @[byte 1, 2, 3], contentTopic: topic, version: uint32(0), timestamp: t1), WakuMessage(payload: @[byte 1, 2, 3, 4], contentTopic: topic, version: uint32(1), timestamp: t2), @@ -45,7 +45,7 @@ suite "Message Store": var msgFlag, psTopicFlag = true var responseCount = 0 - proc data(receiverTimestamp: float64, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = + proc data(receiverTimestamp: int64, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = responseCount += 1 # Note: cannot use `check` within `{.raises: [Defect].}` block: @@ -136,7 +136,7 @@ suite "Message Store": for i in 1..capacity: let - msg = WakuMessage(payload: @[byte i], contentTopic: contentTopic, version: uint32(0), timestamp: i.float) + msg = WakuMessage(payload: @[byte i], contentTopic: contentTopic, version: uint32(0), timestamp: i.int64) index = computeIndex(msg) output = store.put(index, msg, pubsubTopic) @@ -145,9 +145,9 @@ suite "Message Store": var responseCount = 0 - lastMessageTimestamp = 0.float + lastMessageTimestamp = 0.int64 - proc data(receiverTimestamp: float64, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = + proc data(receiverTimestamp: int64, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = responseCount += 1 lastMessageTimestamp = msg.timestamp @@ -157,7 +157,7 @@ suite "Message Store": check: resMax.isOk responseCount == capacity # We retrieved all items - lastMessageTimestamp == capacity.float # Returned rows were ordered correctly + lastMessageTimestamp == capacity.int64 # Returned rows were ordered correctly # Now test getAll with a limit smaller than total stored items responseCount = 0 # Reset response count @@ -167,7 +167,7 @@ suite "Message Store": check: resLimit.isOk responseCount == capacity - 2 # We retrieved limited number of items - lastMessageTimestamp == capacity.float # We retrieved the youngest items in the store, in order + lastMessageTimestamp == capacity.int64 # We retrieved the youngest items in the store, in order # Test zero limit responseCount = 0 # Reset response count @@ -177,4 +177,4 @@ suite "Message Store": check: resZero.isOk responseCount == 0 # No items retrieved - lastMessageTimestamp == 0.float # No items retrieved + lastMessageTimestamp == 0.int64 # No items retrieved diff --git a/tests/v2/test_waku_pagination.nim b/tests/v2/test_waku_pagination.nim index 55c52c3df6..a5e15f457e 100644 --- a/tests/v2/test_waku_pagination.nim +++ b/tests/v2/test_waku_pagination.nim @@ -12,7 +12,7 @@ proc createSampleList(s: int): seq[IndexedWakuMessage] = var data {.noinit.}: array[32, byte] for x in data.mitems: x = 1 for i in 0.. end time - let rpc = HistoryQuery(contentFilters: @[HistoryContentFilter(contentTopic: ContentTopic("1"))], startTime: float(5), endTime: float(2)) + let rpc = HistoryQuery(contentFilters: @[HistoryContentFilter(contentTopic: ContentTopic("1"))], startTime: int64(5), endTime: int64(2)) await proto.query(rpc, handler) check: @@ -689,18 +689,18 @@ procSuite "Waku Store": test "find last seen message": var msgList = @[IndexedWakuMessage(msg: WakuMessage(payload: @[byte 0], contentTopic: ContentTopic("2"))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 1],contentTopic: ContentTopic("1"), timestamp: float(1))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 2],contentTopic: ContentTopic("2"), timestamp: float(2))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 3],contentTopic: ContentTopic("1"), timestamp: float(3))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 4],contentTopic: ContentTopic("2"), timestamp: float(4))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 5],contentTopic: ContentTopic("1"), timestamp: float(9))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 6],contentTopic: ContentTopic("2"), timestamp: float(6))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 7],contentTopic: ContentTopic("1"), timestamp: float(7))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 8],contentTopic: ContentTopic("2"), timestamp: float(8))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 9],contentTopic: ContentTopic("1"),timestamp: float(5)))] + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 1],contentTopic: ContentTopic("1"), timestamp: int64(1))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 2],contentTopic: ContentTopic("2"), timestamp: int64(2))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 3],contentTopic: ContentTopic("1"), timestamp: int64(3))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 4],contentTopic: ContentTopic("2"), timestamp: int64(4))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 5],contentTopic: ContentTopic("1"), timestamp: int64(9))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 6],contentTopic: ContentTopic("2"), timestamp: int64(6))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 7],contentTopic: ContentTopic("1"), timestamp: int64(7))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 8],contentTopic: ContentTopic("2"), timestamp: int64(8))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 9],contentTopic: ContentTopic("1"),timestamp: int64(5)))] check: - findLastSeen(msgList) == float(9) + findLastSeen(msgList) == int64(9) asyncTest "resume message history": # starts a new node @@ -727,7 +727,7 @@ procSuite "Waku Store": response.messages.len() == 4 completionFut.complete(true) - let rpc = HistoryQuery(startTime: float(2), endTime: float(5)) + let rpc = HistoryQuery(startTime: int64(2), endTime: int64(5)) let successResult = await proto.queryFrom(rpc, handler, listenSwitch.peerInfo.toRemotePeerInfo()) check: @@ -737,7 +737,7 @@ procSuite "Waku Store": asyncTest "queryFromWithPaging with empty pagingInfo": - let rpc = HistoryQuery(startTime: float(2), endTime: float(5)) + let rpc = HistoryQuery(startTime: int64(2), endTime: int64(5)) let messagesResult = await proto.queryFromWithPaging(rpc, listenSwitch.peerInfo.toRemotePeerInfo()) @@ -747,7 +747,7 @@ procSuite "Waku Store": asyncTest "queryFromWithPaging with pagination": var pinfo = PagingInfo(direction:PagingDirection.FORWARD, pageSize: 1) - let rpc = HistoryQuery(startTime: float(2), endTime: float(5), pagingInfo: pinfo) + let rpc = HistoryQuery(startTime: int64(2), endTime: int64(5), pagingInfo: pinfo) let messagesResult = await proto.queryFromWithPaging(rpc, listenSwitch.peerInfo.toRemotePeerInfo()) diff --git a/tests/v2/test_wakunode.nim b/tests/v2/test_wakunode.nim index f9ed67d069..c83f8811fe 100644 --- a/tests/v2/test_wakunode.nim +++ b/tests/v2/test_wakunode.nim @@ -1099,7 +1099,7 @@ procSuite "WakuNode": # count the total number of retrieved messages from the database var responseCount = 0 - proc data(receiverTimestamp: float64, msg: WakuMessage, psTopic: string) = + proc data(receiverTimestamp: int64, msg: WakuMessage, psTopic: string) = responseCount += 1 # retrieve all the messages in the db let res = store.getAll(data) diff --git a/waku/common/wakubridge.nim b/waku/common/wakubridge.nim index b134ce0754..f97a3cb6d0 100644 --- a/waku/common/wakubridge.nim +++ b/waku/common/wakubridge.nim @@ -91,7 +91,7 @@ func toWakuMessage(env: Envelope): WakuMessage = # Translate a Waku v1 envelope to a Waku v2 message WakuMessage(payload: env.data, contentTopic: toV2ContentTopic(env.topic), - timestamp: float64(env.expiry - env.ttl), + timestamp: int64(env.expiry - env.ttl), version: 1) proc toWakuV2(bridge: WakuBridge, env: Envelope) {.async.} = diff --git a/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim b/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim index 240fcca3cc..330317e072 100644 --- a/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim +++ b/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim @@ -16,7 +16,7 @@ proc delete_waku_v2_relay_v1_subscriptions(topics: seq[string]): bool # Store API -proc get_waku_v2_store_v1_messages(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[float64], endTime: Option[float64], pagingOptions: Option[StorePagingOptions]): StoreResponse +proc get_waku_v2_store_v1_messages(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[int64], endTime: Option[int64], pagingOptions: Option[StorePagingOptions]): StoreResponse # Filter API diff --git a/waku/v2/node/jsonrpc/jsonrpc_types.nim b/waku/v2/node/jsonrpc/jsonrpc_types.nim index fa4219744c..611eb2e20f 100644 --- a/waku/v2/node/jsonrpc/jsonrpc_types.nim +++ b/waku/v2/node/jsonrpc/jsonrpc_types.nim @@ -21,7 +21,7 @@ type payload*: seq[byte] contentTopic*: Option[ContentTopic] # sender generated timestamp - timestamp*: Option[float64] + timestamp*: Option[int64] WakuPeer* = object multiaddr*: string diff --git a/waku/v2/node/jsonrpc/jsonrpc_utils.nim b/waku/v2/node/jsonrpc/jsonrpc_utils.nim index d4ddaa2371..1243f0c678 100644 --- a/waku/v2/node/jsonrpc/jsonrpc_utils.nim +++ b/waku/v2/node/jsonrpc/jsonrpc_utils.nim @@ -41,12 +41,12 @@ proc toStoreResponse*(historyResponse: HistoryResponse): StoreResponse = proc toWakuMessage*(relayMessage: WakuRelayMessage, version: uint32): WakuMessage = const defaultCT = ContentTopic("/waku/2/default-content/proto") - var t: float64 + var t: int64 if relayMessage.timestamp.isSome: t = relayMessage.timestamp.get else: # incoming WakuRelayMessages with no timestamp will get 0 timestamp - t = float64(0) + t = int64(0) WakuMessage(payload: relayMessage.payload, contentTopic: if relayMessage.contentTopic.isSome: relayMessage.contentTopic.get else: defaultCT, version: version, @@ -60,12 +60,12 @@ proc toWakuMessage*(relayMessage: WakuRelayMessage, version: uint32, rng: ref Br dst: pubKey, symkey: symkey) - var t: float64 + var t: int64 if relayMessage.timestamp.isSome: t = relayMessage.timestamp.get else: # incoming WakuRelayMessages with no timestamp will get 0 timestamp - t = float64(0) + t = int64(0) WakuMessage(payload: payload.encode(version, rng[]).get(), contentTopic: if relayMessage.contentTopic.isSome: relayMessage.contentTopic.get else: defaultCT, diff --git a/waku/v2/node/jsonrpc/store_api.nim b/waku/v2/node/jsonrpc/store_api.nim index 0914ce8a61..474de64841 100644 --- a/waku/v2/node/jsonrpc/store_api.nim +++ b/waku/v2/node/jsonrpc/store_api.nim @@ -17,7 +17,7 @@ proc installStoreApiHandlers*(node: WakuNode, rpcsrv: RpcServer) = ## Store API version 1 definitions - rpcsrv.rpc("get_waku_v2_store_v1_messages") do(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[float64], endTime: Option[float64], pagingOptions: Option[StorePagingOptions]) -> StoreResponse: + rpcsrv.rpc("get_waku_v2_store_v1_messages") do(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[int64], endTime: Option[int64], pagingOptions: Option[StorePagingOptions]) -> StoreResponse: ## Returns history for a list of content topics with optional paging debug "get_waku_v2_store_v1_messages" @@ -29,8 +29,8 @@ proc installStoreApiHandlers*(node: WakuNode, rpcsrv: RpcServer) = let historyQuery = HistoryQuery(pubsubTopic: if pubsubTopicOption.isSome: pubsubTopicOption.get() else: "", contentFilters: if contentFiltersOption.isSome: contentFiltersOption.get() else: @[], - startTime: if startTime.isSome: startTime.get() else: 0.float64, - endTime: if endTime.isSome: endTime.get() else: 0.float64, + startTime: if startTime.isSome: startTime.get() else: 0.int64, + endTime: if endTime.isSome: endTime.get() else: 0.int64, pagingInfo: if pagingOptions.isSome: pagingOptions.get.toPagingInfo() else: PagingInfo()) await node.query(historyQuery, queryFuncHandler) diff --git a/waku/v2/node/quicksim2.nim b/waku/v2/node/quicksim2.nim index 3273889474..de1614e6dd 100644 --- a/waku/v2/node/quicksim2.nim +++ b/waku/v2/node/quicksim2.nim @@ -63,11 +63,11 @@ os.sleep(2000) for i in 0..lastSeenTime: lastSeenTime = iwmsg.msg.timestamp @@ -663,12 +669,12 @@ proc resume*(ws: WakuStore, peerList: Option[seq[RemotePeerInfo]] = none(seq[Rem ## The history gets fetched successfully if the dialed peer has been online during the queried time window. ## the resume proc returns the number of retrieved messages if no error occurs, otherwise returns the error string - var currentTime = epochTime() - var lastSeenTime: float = findLastSeen(ws.messages.allItems()) + var currentTime = int64(epochTime()*1000) + var lastSeenTime: int64 = findLastSeen(ws.messages.allItems()) debug "resume", currentEpochTime=currentTime # adjust the time window with an offset of 20 seconds - let offset: float64 = 200000 + let offset: int64 = 200000 currentTime = currentTime + offset lastSeenTime = max(lastSeenTime - offset, 0) debug "the offline time window is", lastSeenTime=lastSeenTime, currentTime=currentTime diff --git a/waku/v2/protocol/waku_store/waku_store_types.nim b/waku/v2/protocol/waku_store/waku_store_types.nim index 8184d1a1ed..7174933da3 100644 --- a/waku/v2/protocol/waku_store/waku_store_types.nim +++ b/waku/v2/protocol/waku_store/waku_store_types.nim @@ -65,8 +65,8 @@ type contentFilters*: seq[HistoryContentFilter] pubsubTopic*: string pagingInfo*: PagingInfo # used for pagination - startTime*: float64 # used for time-window query - endTime*: float64 # used for time-window query + startTime*: int64 # used for time-window query + endTime*: int64 # used for time-window query HistoryResponseError* {.pure.} = enum ## HistoryResponseError contains error message to inform the querying node about the state of its request diff --git a/waku/v2/utils/pagination.nim b/waku/v2/utils/pagination.nim index d2c617e7ab..99087e9a20 100644 --- a/waku/v2/utils/pagination.nim +++ b/waku/v2/utils/pagination.nim @@ -10,5 +10,5 @@ type Index* = object ## This type contains the description of an Index used in the pagination of WakuMessages digest*: MDigest[256] - receiverTime*: float64 - senderTime*: float64 # the time at which the message is generated + receiverTime*: int64 + senderTime*: int64 # the time at which the message is generated From 05c5ce6b7f605746899e0a7493253cb68867a123 Mon Sep 17 00:00:00 2001 From: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Thu, 3 Feb 2022 20:31:39 +0100 Subject: [PATCH 02/22] Revert epochs to float64 --- .../waku_rln_relay/waku_rln_relay_utils.nim | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index 41bdc77744..cd842ad49e 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -406,11 +406,10 @@ proc fromEpoch*(epoch: Epoch): uint64 = let t = fromBytesLE(uint64, array[32,byte](epoch)) return t -proc calcEpoch*(t: int64): Epoch = - ## gets time `t` as `int64` with milliseconds resolution +proc calcEpoch*(t: float64): Epoch = + ## gets time `t` as `flaot64` with subseconds resolution in the fractional part ## and returns its corresponding rln `Epoch` value - ## TODO: check the uint64 cast doesn't induce overflows - let e = uint64(t/(EPOCH_UNIT_SECONDS*1000)) + let e = uint64(t/EPOCH_UNIT_SECONDS) return toEpoch(e) proc getCurrentEpoch*(): Epoch = @@ -428,7 +427,7 @@ proc compare*(e1, e2: Epoch): int64 = return int64(epoch1) - int64(epoch2) -proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Option[int64] = none(int64)): MessageValidationResult = +proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Option[float64] = none(float64)): MessageValidationResult = ## validate the supplied `msg` based on the waku-rln-relay routing protocol i.e., ## the `msg`'s epoch is within MAX_EPOCH_GAP of the current epoch ## the `msg` has valid rate limit proof @@ -474,10 +473,10 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Optio return MessageValidationResult.Valid -proc appendRLNProof*(rlnPeer: WakuRLNRelay, msg: var WakuMessage, senderEpochTime: int64): bool = +proc appendRLNProof*(rlnPeer: WakuRLNRelay, msg: var WakuMessage, senderEpochTime: float64): bool = ## returns true if it can create and append a `RateLimitProof` to the supplied `msg` ## returns false otherwise - ## `senderEpochTime` indicates the number of milliseconds passed since Unix epoch. + ## `senderEpochTime` indicates the number of seconds passed since Unix epoch. The fractional part holds sub-seconds. ## The `epoch` field of `RateLimitProof` is derived from the provided `senderEpochTime` (using `calcEpoch()`) let From 6eb37302fba15b9302cd4289af20ac95380672b4 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Thu, 3 Feb 2022 20:43:12 +0100 Subject: [PATCH 03/22] Update 00002_addSenderTimeStamp.up.sql --- .../message/00002_addSenderTimeStamp.up.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql b/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql index 5b6606bc88..4a6852053b 100644 --- a/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql +++ b/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql @@ -13,12 +13,12 @@ DROP TABLE Message; CREATE TABLE IF NOT EXISTS Message( id BLOB PRIMARY KEY, - receiverTimestamp INTEGER NOT NULL, + receiverTimestamp REAL NOT NULL, contentTopic BLOB NOT NULL, pubsubTopic BLOB NOT NULL, payload BLOB, version INTEGER NOT NULL, - senderTimestamp INTEGER NOT NULL + senderTimestamp REAL NOT NULL ) WITHOUT ROWID; @@ -26,4 +26,4 @@ INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, SELECT id, timestamp, contentTopic, pubsubTopic, payload, version, 0 FROM Message_backup; -DROP TABLE Message_backup; \ No newline at end of file +DROP TABLE Message_backup; From 8e9f19e9348a6dae7bb0a377b2ff92489d8f8108 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Thu, 3 Feb 2022 21:12:08 +0100 Subject: [PATCH 04/22] Update quicksim2.nim --- waku/v2/node/quicksim2.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/waku/v2/node/quicksim2.nim b/waku/v2/node/quicksim2.nim index de1614e6dd..b8ad02e2db 100644 --- a/waku/v2/node/quicksim2.nim +++ b/waku/v2/node/quicksim2.nim @@ -63,11 +63,11 @@ os.sleep(2000) for i in 0.. Date: Thu, 3 Feb 2022 22:02:53 +0100 Subject: [PATCH 05/22] Add files via upload --- .../00003_convertTimestampsToInts.up.sql | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql diff --git a/waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql b/waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql new file mode 100644 index 0000000000..1e64e370ce --- /dev/null +++ b/waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql @@ -0,0 +1,31 @@ +CREATE TABLE IF NOT EXISTS Message_backup ( + id BLOB PRIMARY KEY, + receiverTimestamp REAL NOT NULL, + contentTopic BLOB NOT NULL, + pubsubTopic BLOB NOT NULL, + payload BLOB, + version INTEGER NOT NULL, + senderTimestamp REAL NOT NULL + ) WITHOUT ROWID; + + +INSERT INTO Message_backup SELECT id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp FROM Message; + +DROP TABLE Message; + +CREATE TABLE IF NOT EXISTS Message ( + id BLOB PRIMARY KEY, + receiverTimestamp INTEGER NOT NULL, + contentTopic BLOB NOT NULL, + pubsubTopic BLOB NOT NULL, + payload BLOB, + version INTEGER NOT NULL, + senderTimestamp INTEGER NOT NULL + ) WITHOUT ROWID; + + +INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp) + SELECT id, FLOOR(receiverTimestamp*1000), contentTopic, pubsubTopic, payload, version, FLOOR(senderTimestamp*1000) + FROM Message_backup; + +DROP TABLE Message_backup; \ No newline at end of file From 6a0ab69585c0018b6691f949ff49544ac657f044 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Thu, 3 Feb 2022 22:04:42 +0100 Subject: [PATCH 06/22] Delete 00003_convertTimestampsToInts.up.sql --- .../00003_convertTimestampsToInts.up.sql | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql diff --git a/waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql b/waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql deleted file mode 100644 index 1e64e370ce..0000000000 --- a/waku/v2/node/storage/migration/00003_convertTimestampsToInts.up.sql +++ /dev/null @@ -1,31 +0,0 @@ -CREATE TABLE IF NOT EXISTS Message_backup ( - id BLOB PRIMARY KEY, - receiverTimestamp REAL NOT NULL, - contentTopic BLOB NOT NULL, - pubsubTopic BLOB NOT NULL, - payload BLOB, - version INTEGER NOT NULL, - senderTimestamp REAL NOT NULL - ) WITHOUT ROWID; - - -INSERT INTO Message_backup SELECT id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp FROM Message; - -DROP TABLE Message; - -CREATE TABLE IF NOT EXISTS Message ( - id BLOB PRIMARY KEY, - receiverTimestamp INTEGER NOT NULL, - contentTopic BLOB NOT NULL, - pubsubTopic BLOB NOT NULL, - payload BLOB, - version INTEGER NOT NULL, - senderTimestamp INTEGER NOT NULL - ) WITHOUT ROWID; - - -INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp) - SELECT id, FLOOR(receiverTimestamp*1000), contentTopic, pubsubTopic, payload, version, FLOOR(senderTimestamp*1000) - FROM Message_backup; - -DROP TABLE Message_backup; \ No newline at end of file From 5b20f08de60b9d8f338d821631cbf9b2165a8f4e Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Thu, 3 Feb 2022 22:05:01 +0100 Subject: [PATCH 07/22] Add files via upload --- .../00003_convertTimestampsToInts.up.sql | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql diff --git a/waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql b/waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql new file mode 100644 index 0000000000..1e64e370ce --- /dev/null +++ b/waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql @@ -0,0 +1,31 @@ +CREATE TABLE IF NOT EXISTS Message_backup ( + id BLOB PRIMARY KEY, + receiverTimestamp REAL NOT NULL, + contentTopic BLOB NOT NULL, + pubsubTopic BLOB NOT NULL, + payload BLOB, + version INTEGER NOT NULL, + senderTimestamp REAL NOT NULL + ) WITHOUT ROWID; + + +INSERT INTO Message_backup SELECT id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp FROM Message; + +DROP TABLE Message; + +CREATE TABLE IF NOT EXISTS Message ( + id BLOB PRIMARY KEY, + receiverTimestamp INTEGER NOT NULL, + contentTopic BLOB NOT NULL, + pubsubTopic BLOB NOT NULL, + payload BLOB, + version INTEGER NOT NULL, + senderTimestamp INTEGER NOT NULL + ) WITHOUT ROWID; + + +INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp) + SELECT id, FLOOR(receiverTimestamp*1000), contentTopic, pubsubTopic, payload, version, FLOOR(senderTimestamp*1000) + FROM Message_backup; + +DROP TABLE Message_backup; \ No newline at end of file From 029acd2afceac88a52c8732e2619ebc39098ddb6 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Fri, 4 Feb 2022 00:13:56 +0100 Subject: [PATCH 08/22] Rename 00003_convertTimestampsToInts.up.sql to 00003_addTimestampsToInts.up.sql --- ...TimestampsToInts.up.sql => 00003_addTimestampsToInts.up.sql} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename waku/v2/node/storage/migration/migrations_scripts/message/{00003_convertTimestampsToInts.up.sql => 00003_addTimestampsToInts.up.sql} (97%) diff --git a/waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql b/waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql similarity index 97% rename from waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql rename to waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql index 1e64e370ce..67bd54c908 100644 --- a/waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInts.up.sql +++ b/waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql @@ -28,4 +28,4 @@ INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, SELECT id, FLOOR(receiverTimestamp*1000), contentTopic, pubsubTopic, payload, version, FLOOR(senderTimestamp*1000) FROM Message_backup; -DROP TABLE Message_backup; \ No newline at end of file +DROP TABLE Message_backup; From f9720e4d1284301da36dfe9ae36add5f2240a96c Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Fri, 4 Feb 2022 00:30:41 +0100 Subject: [PATCH 09/22] Delete 00003_addTimestampsToInts.up.sql --- .../message/00003_addTimestampsToInts.up.sql | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql diff --git a/waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql b/waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql deleted file mode 100644 index 67bd54c908..0000000000 --- a/waku/v2/node/storage/migration/migrations_scripts/message/00003_addTimestampsToInts.up.sql +++ /dev/null @@ -1,31 +0,0 @@ -CREATE TABLE IF NOT EXISTS Message_backup ( - id BLOB PRIMARY KEY, - receiverTimestamp REAL NOT NULL, - contentTopic BLOB NOT NULL, - pubsubTopic BLOB NOT NULL, - payload BLOB, - version INTEGER NOT NULL, - senderTimestamp REAL NOT NULL - ) WITHOUT ROWID; - - -INSERT INTO Message_backup SELECT id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp FROM Message; - -DROP TABLE Message; - -CREATE TABLE IF NOT EXISTS Message ( - id BLOB PRIMARY KEY, - receiverTimestamp INTEGER NOT NULL, - contentTopic BLOB NOT NULL, - pubsubTopic BLOB NOT NULL, - payload BLOB, - version INTEGER NOT NULL, - senderTimestamp INTEGER NOT NULL - ) WITHOUT ROWID; - - -INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp) - SELECT id, FLOOR(receiverTimestamp*1000), contentTopic, pubsubTopic, payload, version, FLOOR(senderTimestamp*1000) - FROM Message_backup; - -DROP TABLE Message_backup; From 6aea51d94aa387c6682c27fae2d519122e17aedd Mon Sep 17 00:00:00 2001 From: Sanaz Taheri Boshrooyeh <35961250+staheri14@users.noreply.github.com> Date: Fri, 4 Feb 2022 15:58:27 -0800 Subject: [PATCH 10/22] Rln-relay integration into chat2 (#835) * adds ProofMetadata * adds EPOCH_INTERVAL * adds messageLog field * adds updateLog, toEpoch, fromEpoch, getEpoch, compareTo * adds unit test for toEpoch and fromEpoch * adds unit test for Epoch comparison * adds result codes for updateLog * adds unit test for update log * renames epoch related consts * modifies updateLog with new return type and new logic of spam detection * adds unit text for the modified updateLog * changes max epoch gap type size * splits updateLog into two procs isSpam and updateLog * updates unittests * fixes a bug, returns false when the message is not spam * renames messageLog to nullifierLog * renames isSpam to hasDuplicate * updates the rln validator, adds comments * adds appendRLNProof proc plus some code beatification * unit test for validate message * adds unhappy test to validateMessage unit test * renames EPOCH_UNIT_SECONDS * renames MAX_CLOCK_GAP_SECONDS * WIP: integration test * fixes compile errors * sets a real epoch value * updates on old unittests * adds comments to the rln relay tests * adds more comments * makes rln import conditional * adds todos * adds more todos * adds rln-relay mount process into chat2 * further todos * logs contentTopic * introduces rln relay configs * changes default pubsub topic * adds contentTopic config * imports rln relay dependencies * consolidates imports * removes module identifier from ContentTopic * adds contentTopic field * adds contentTopic argument to mountRlnRelay calls * appends rln proof to chat2 messages * changes the default chat2 contentTopic * adds missing content topic fields * fixes a bug * adds a new logic about empty content topics * appends proof only when rln flag is active * removes unnecessary todos * fixes an indentation issue * adds log messages * verifies the proof against the concatenation of msg payload and content topic * a bug fix * removes duplicate epoch time calculation * updates log level to trace * updates default rln-relay content topic * adds support for empty content topics * updates changelog * changelog updates * removes a commented code block * updates addRLNRelayValidator string doc --- CHANGELOG.md | 19 ++++++ examples/v2/chat2.nim | 61 +++++++++++++++++-- examples/v2/config_chat2.nim | 32 +++++++--- tests/v2/test_waku_rln_relay.nim | 17 +++++- tests/v2/test_wakunode.nim | 57 +++++++++-------- waku/v2/node/config.nim | 10 ++- waku/v2/node/wakunode2.nim | 36 ++++++----- .../waku_rln_relay/waku_rln_relay_types.nim | 3 + .../waku_rln_relay/waku_rln_relay_utils.nim | 8 ++- 9 files changed, 186 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c97cda90..27437ad3f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## Next Release +Release highlights: + +- + +The full list of changes is below. + +### Features + +- The `waku-rln-relay` now supports spam-protection for a specific combination of `pubsubTopic` and `contentTopic` (available under the `rln` compiler flag). +- The `waku-rln-relay` protocol in integrated into `chat2` (available under the`rln` compiler flag) + +### Changes + +- ... +### Fixes + +- ... + ## 2021-01-19 v0.7 Release highlights: diff --git a/examples/v2/chat2.nim b/examples/v2/chat2.nim index f1de1361b9..3fc8438776 100644 --- a/examples/v2/chat2.nim +++ b/examples/v2/chat2.nim @@ -27,6 +27,13 @@ import ../../waku/v2/node/[wakunode2, waku_payload], ../../waku/common/utils/nat, ./config_chat2 +when defined(rln): + import + libp2p/protocols/pubsub/rpc/messages, + libp2p/protocols/pubsub/pubsub, + web3, + ../../waku/v2/protocol/waku_rln_relay/[rln, waku_rln_relay_utils] + const Help = """ Commands: /[?|help|connect|nick|exit] help: Prints this help @@ -191,7 +198,8 @@ proc readNick(transp: StreamTransport): Future[string] {.async.} = proc publish(c: Chat, line: string) = # First create a Chat2Message protobuf with this line of text - let chat2pb = Chat2Message(timestamp: getTime().toUnix(), + let time = getTime().toUnix() + let chat2pb = Chat2Message(timestamp: time, nick: c.nick, payload: line.toBytes()).encode() @@ -206,8 +214,17 @@ proc publish(c: Chat, line: string) = version = 1'u32 encodedPayload = payload.encode(version, c.node.rng[]) if encodedPayload.isOk(): - let message = WakuMessage(payload: encodedPayload.get(), + var message = WakuMessage(payload: encodedPayload.get(), contentTopic: c.contentTopic, version: version) + when defined(rln): + if not isNil(c.node.wakuRlnRelay): + # for future version when we support more than one rln protected content topic, + # we should check the message content topic as well + let success = c.node.wakuRlnRelay.appendRLNProof(message, float64(time)) + if not success: + debug "could not append rate limit proof to the message", success=success + else: + debug "rate limit proof is appended to the message", success=success if not c.node.wakuLightPush.isNil(): # Attempt lightpush asyncSpawn c.node.lightpush(DefaultTopic, message, handler) @@ -217,8 +234,18 @@ proc publish(c: Chat, line: string) = warn "Payload encoding failed", error = encodedPayload.error else: # No payload encoding/encryption from Waku - let message = WakuMessage(payload: chat2pb.buffer, + var message = WakuMessage(payload: chat2pb.buffer, contentTopic: c.contentTopic, version: 0) + when defined(rln): + if not isNil(c.node.wakuRlnRelay): + # for future version when we support more than one rln protected content topic, + # we should check the message content topic as well + let success = c.node.wakuRlnRelay.appendRLNProof(message, float64(time)) + if not success: + debug "could not append rate limit proof to the message", success=success + else: + debug "rate limit proof is appended to the message", success=success + if not c.node.wakuLightPush.isNil(): # Attempt lightpush asyncSpawn c.node.lightpush(DefaultTopic, message, handler) @@ -326,7 +353,6 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} = wsBindPort = Port(uint16(conf.websocketPort) + conf.portsShift), wsEnabled = conf.websocketSupport, wssEnabled = conf.websocketSecureSupport) - await node.start() node.mountRelay(conf.topics.split(" "), @@ -465,6 +491,33 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} = let topic = cast[Topic](DefaultTopic) node.subscribe(topic, handler) + when defined(rln): + if conf.rlnRelay: + info "WakuRLNRelay is enabled" + + # set up rln relay inputs + let (groupOpt, memKeyPairOpt, memIndexOpt) = rlnRelaySetUp(conf.rlnRelayMemIndex) + if memIndexOpt.isNone: + error "failed to mount WakuRLNRelay" + else: + # mount rlnrelay in offline mode (for now) + waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic) + + trace "membership id key", idkey=memKeyPairOpt.get().idKey.toHex + trace "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex + + # check the correct construction of the tree by comparing the calculated root against the expected root + # no error should happen as it is already captured in the unit tests + # TODO have added this check to account for unseen corner cases, will remove it later + let + root = node.wakuRlnRelay.rlnInstance.getMerkleRoot.value.toHex() + expectedRoot = STATIC_GROUP_MERKLE_ROOT + if root != expectedRoot: + error "root mismatch: something went wrong not in Merkle tree construction" + trace "the calculated root", root + trace "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic, contentTopic=conf.rlnRelayContentTopic + + await chat.readWriteLoop() if conf.keepAlive: diff --git a/examples/v2/config_chat2.nim b/examples/v2/config_chat2.nim index 7519afcfc2..75fb331832 100644 --- a/examples/v2/config_chat2.nim +++ b/examples/v2/config_chat2.nim @@ -5,8 +5,9 @@ import libp2p/crypto/crypto, libp2p/crypto/secp, nimcrypto/utils, - eth/keys - + eth/keys, + ../../waku/v2/protocol/waku_rln_relay/waku_rln_relay_types, + ../../waku/v2/protocol/waku_message type Fleet* = enum none @@ -75,11 +76,6 @@ type defaultValue: true name: "relay" }: bool - rlnRelay* {. - desc: "Enable spam protection through rln-relay: true|false", - defaultValue: false - name: "rln-relay" }: bool - staticnodes* {. desc: "Peer multiaddr to directly connect with. Argument may be repeated." name: "staticnode" }: seq[string] @@ -231,6 +227,28 @@ type defaultValue: false name: "websocket-secure-support" }: bool + ## rln-relay configuration + + rlnRelay* {. + desc: "Enable spam protection through rln-relay: true|false", + defaultValue: false + name: "rln-relay" }: bool + + rlnRelayMemIndex* {. + desc: "(experimental) the index of node in the rln-relay group: a value between 0-99 inclusive", + defaultValue: MembershipIndex(0) + name: "rln-relay-membership-index" }: MembershipIndex + + rlnRelayContentTopic* {. + desc: "the pubsub topic for which rln-relay gets enabled", + defaultValue: "waku/2/rln-relay/proto" + name: "rln-relay-content-topic" }: ContentTopic + + rlnRelayPubsubTopic* {. + desc: "the pubsub topic for which rln-relay gets enabled", + defaultValue: "/waku/2/default-waku/proto" + name: "rln-relay-pubsub-topic" }: string + # NOTE: Keys are different in nim-libp2p proc parseCmdArg*(T: type crypto.PrivateKey, p: TaintedString): T = try: diff --git a/tests/v2/test_waku_rln_relay.nim b/tests/v2/test_waku_rln_relay.nim index 2b8655fa78..a26fe70a6e 100644 --- a/tests/v2/test_waku_rln_relay.nim +++ b/tests/v2/test_waku_rln_relay.nim @@ -12,6 +12,7 @@ import ./test_utils const RLNRELAY_PUBSUB_TOPIC = "waku/2/rlnrelay/proto" +const RLNRELAY_CONTENT_TOPIC = "waku/2/rlnrelay/proto" # POSEIDON_HASHER_CODE holds the bytecode of Poseidon hasher solidity smart contract: # https://github.com/kilic/rlnapp/blob/master/packages/contracts/contracts/crypto/PoseidonHasher.sol @@ -250,7 +251,14 @@ procSuite "Waku rln relay": # start rln-relay node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC]) - await node.mountRlnRelay(ethClientAddrOpt = some(ETH_CLIENT), ethAccAddrOpt = some(ethAccountAddress), memContractAddOpt = some(membershipContractAddress), groupOpt = some(group), memKeyPairOpt = some(keypair.get()), memIndexOpt = some(index), pubsubTopic = RLNRELAY_PUBSUB_TOPIC) + await node.mountRlnRelay(ethClientAddrOpt = some(EthClient), + ethAccAddrOpt = some(ethAccountAddress), + memContractAddOpt = some(membershipContractAddress), + groupOpt = some(group), + memKeyPairOpt = some(keypair.get()), + memIndexOpt = some(index), + pubsubTopic = RLNRELAY_PUBSUB_TOPIC, + contentTopic = RLNRELAY_CONTENT_TOPIC) let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex debug "calculated root ", calculatedRoot @@ -286,7 +294,12 @@ procSuite "Waku rln relay": # -------- mount rln-relay in the off-chain mode node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC]) - await node.mountRlnRelay(groupOpt = some(groupIDCommitments), memKeyPairOpt = some(groupKeyPairs[index]), memIndexOpt = some(index), onchainMode = false, pubsubTopic = RLNRELAY_PUBSUB_TOPIC) + await node.mountRlnRelay(groupOpt = some(groupIDCommitments), + memKeyPairOpt = some(groupKeyPairs[index]), + memIndexOpt = some(index), + onchainMode = false, + pubsubTopic = RLNRELAY_PUBSUB_TOPIC, + contentTopic = RLNRELAY_CONTENT_TOPIC) # get the root of Merkle tree which is constructed inside the mountRlnRelay proc let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex diff --git a/tests/v2/test_wakunode.nim b/tests/v2/test_wakunode.nim index c83f8811fe..06637fbc1a 100644 --- a/tests/v2/test_wakunode.nim +++ b/tests/v2/test_wakunode.nim @@ -2,6 +2,7 @@ import testutils/unittests, + std/sequtils, chronicles, chronos, stew/shims/net as stewNet, stew/byteutils, std/os, libp2p/crypto/crypto, libp2p/crypto/secp, @@ -617,7 +618,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt1, memIndexOpt= memIndexOpt1, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node1.start() # node 2 @@ -628,7 +630,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt2, memIndexOpt= memIndexOpt2, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node2.start() # node 3 @@ -639,7 +642,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt3, memIndexOpt= memIndexOpt3, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node3.start() # connect them together @@ -663,19 +667,11 @@ procSuite "WakuNode": let payload = "Hello".toBytes() # prepare the epoch - let epoch = getCurrentEpoch() + let epoch = getCurrentEpoch() - # prepare the proof - let rateLimitProofRes = node1.wakuRlnRelay.rlnInstance.proofGen(data = payload, - memKeys = node1.wakuRlnRelay.membershipKeyPair, - memIndex = node1.wakuRlnRelay.membershipIndex, - epoch = epoch) - doAssert(rateLimitProofRes.isOk()) - let rateLimitProof = rateLimitProofRes.value - - let message = WakuMessage(payload: @payload, - contentTopic: contentTopic, - proof: rateLimitProof) + var message = WakuMessage(payload: @payload, + contentTopic: contentTopic) + doAssert(node1.wakuRlnRelay.appendRLNProof(message, epochTime())) ## node1 publishes a message with a rate limit proof, the message is then relayed to node2 which in turn @@ -715,7 +711,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt1, memIndexOpt= memIndexOpt1, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node1.start() # node 2 @@ -726,7 +723,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt2, memIndexOpt= memIndexOpt2, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node2.start() # node 3 @@ -737,7 +735,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt3, memIndexOpt= memIndexOpt3, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node3.start() # connect them together @@ -765,7 +764,10 @@ procSuite "WakuNode": let epoch = getCurrentEpoch() # prepare the proof - let rateLimitProofRes = node1.wakuRlnRelay.rlnInstance.proofGen(data = payload, + let + contentTopicBytes = contentTopic.toBytes + input = concat(payload, contentTopicBytes) + rateLimitProofRes = node1.wakuRlnRelay.rlnInstance.proofGen(data = input, memKeys = node1.wakuRlnRelay.membershipKeyPair, memIndex = MembershipIndex(4), epoch = epoch) @@ -817,7 +819,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt1, memIndexOpt= memIndexOpt1, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node1.start() # node 2 @@ -828,7 +831,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt2, memIndexOpt= memIndexOpt2, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node2.start() # node 3 @@ -839,7 +843,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt3, memIndexOpt= memIndexOpt3, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node3.start() # connect the nodes together node1 <-> node2 <-> node3 @@ -850,15 +855,15 @@ procSuite "WakuNode": let time = epochTime() # create some messages with rate limit proofs var - wm1 = WakuMessage(payload: "message 1".toBytes()) + wm1 = WakuMessage(payload: "message 1".toBytes(), contentTopic: contentTopic) proofAdded1 = node3.wakuRlnRelay.appendRLNProof(wm1, time) # another message in the same epoch as wm1, it will break the messaging rate limit - wm2 = WakuMessage(payload: "message2".toBytes()) + wm2 = WakuMessage(payload: "message2".toBytes(), contentTopic: contentTopic) proofAdded2 = node3.wakuRlnRelay.appendRLNProof(wm2, time) # wm3 points to the next epoch - wm3 = WakuMessage(payload: "message 3".toBytes()) + wm3 = WakuMessage(payload: "message 3".toBytes(), contentTopic: contentTopic) proofAdded3 = node3.wakuRlnRelay.appendRLNProof(wm3, time+EPOCH_UNIT_SECONDS) - wm4 = WakuMessage(payload: "message4".toBytes()) + wm4 = WakuMessage(payload: "message4".toBytes(), contentTopic: contentTopic) # check proofs are added correctly check: diff --git a/waku/v2/node/config.nim b/waku/v2/node/config.nim index 2bd283e16c..cd6a239bd7 100644 --- a/waku/v2/node/config.nim +++ b/waku/v2/node/config.nim @@ -6,7 +6,8 @@ import libp2p/crypto/secp, nimcrypto/utils, eth/keys, - ../protocol/waku_rln_relay/[waku_rln_relay_types] + ../protocol/waku_rln_relay/waku_rln_relay_types, + ../protocol/waku_message type WakuNodeConf* = object @@ -83,8 +84,13 @@ type rlnRelayPubsubTopic* {. desc: "the pubsub topic for which rln-relay gets enabled", - defaultValue: "waku/2/rlnrelay/proto" + defaultValue: "/waku/2/default-waku/proto" name: "rln-relay-pubsub-topic" }: string + + rlnRelayContentTopic* {. + desc: "the pubsub topic for which rln-relay gets enabled", + defaultValue: "/toy-chat/2/huilong/proto" + name: "rln-relay-content-topic" }: ContentTopic staticnodes* {. desc: "Peer multiaddr to directly connect with. Argument may be repeated." diff --git a/waku/v2/node/wakunode2.nim b/waku/v2/node/wakunode2.nim index 67dd16630e..6b18cb1554 100644 --- a/waku/v2/node/wakunode2.nim +++ b/waku/v2/node/wakunode2.nim @@ -468,26 +468,30 @@ proc mountStore*(node: WakuNode, store: MessageStore = nil, persistMessages: boo node.switch.mount(node.wakuStore, protocolMatcher(WakuStoreCodec)) when defined(rln): - proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: string) = + proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: string, contentTopic: ContentTopic) = ## this procedure is a thin wrapper for the pubsub addValidator method - ## it sets message validator on the given pubsubTopic, the validator will check that - ## all the messages published in the pubsubTopic have a valid zero-knowledge proof + ## it sets a validator for the waku messages published on the supplied pubsubTopic and contentTopic + ## if contentTopic is empty, then validation takes place for All the messages published on the given pubsubTopic + ## the message validation logic is according to https://rfc.vac.dev/spec/17/ proc validator(topic: string, message: messages.Message): Future[pubsub.ValidationResult] {.async.} = let msg = WakuMessage.init(message.data) if msg.isOk(): - let - wakumessage = msg.value() - # validate the message - validationRes = node.wakuRlnRelay.validateMessage(wakumessage) + let wakumessage = msg.value() + # check the contentTopic + if (wakumessage.contentTopic != "") and (contentTopic != "") and (wakumessage.contentTopic != contentTopic): + trace "content topic did not match:", contentTopic=wakumessage.contentTopic, payload=string.fromBytes(wakumessage.payload) + return pubsub.ValidationResult.Accept + # validate the message + let validationRes = node.wakuRlnRelay.validateMessage(wakumessage) case validationRes: of Valid: - info "message validity is verified, relaying:", wakumessage=wakumessage + trace "message validity is verified, relaying:", wakumessage=wakumessage, payload=string.fromBytes(wakumessage.payload) return pubsub.ValidationResult.Accept of Invalid: - info "message validity could not be verified, discarding:", wakumessage=wakumessage + trace "message validity could not be verified, discarding:", wakumessage=wakumessage, payload=string.fromBytes(wakumessage.payload) return pubsub.ValidationResult.Reject of Spam: - info "A spam message is found! yay! discarding:", wakumessage=wakumessage + trace "A spam message is found! yay! discarding:", wakumessage=wakumessage, payload=string.fromBytes(wakumessage.payload) return pubsub.ValidationResult.Reject # set a validator for the supplied pubsubTopic let pb = PubSub(node.wakuRelay) @@ -501,7 +505,8 @@ when defined(rln): memKeyPairOpt: Option[MembershipKeyPair] = none(MembershipKeyPair), memIndexOpt: Option[MembershipIndex] = none(MembershipIndex), onchainMode: bool = true, - pubsubTopic: string) {.async.} = + pubsubTopic: string, + contentTopic: ContentTopic) {.async.} = # TODO return a bool value to indicate the success of the call # check whether inputs are provided @@ -581,7 +586,8 @@ when defined(rln): ethClientAddress: ethClientAddr, ethAccountAddress: ethAccAddr, rlnInstance: rln, - pubsubTopic: pubsubTopic) + pubsubTopic: pubsubTopic, + contentTopic: contentTopic) if onchainMode: # register the rln-relay peer to the membership contract @@ -593,7 +599,7 @@ when defined(rln): # adds a topic validator for the supplied pubsub topic at the relay protocol # messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped # the topic validator checks for the correct non-spamming proof of the message - addRLNRelayValidator(node, pubsubTopic) + addRLNRelayValidator(node, pubsubTopic, contentTopic) debug "rln relay topic validator is mounted successfully", pubsubTopic=pubsubTopic node.wakuRlnRelay = rlnPeer @@ -1071,7 +1077,7 @@ when isMainModule: error "failed to mount WakuRLNRelay" else: # mount rlnrelay in offline mode (for now) - waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic) + waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic) info "membership id key", idkey=memKeyPairOpt.get().idKey.toHex info "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex @@ -1085,7 +1091,7 @@ when isMainModule: if root != expectedRoot: error "root mismatch: something went wrong not in Merkle tree construction" debug "the calculated root", root - info "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic + info "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic, contentTopic=conf.rlnRelayContentTopic if conf.swap: mountSwap(node) diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim index 9d38d41553..131577b6b5 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim @@ -77,6 +77,9 @@ type WakuRLNRelay* = ref object ethAccountPrivateKey*: Option[PrivateKey] rlnInstance*: RLN[Bn256] pubsubTopic*: string # the pubsub topic for which rln relay is mounted + # contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead + # TODO a long-term solution is to place types with recursive dependency inside one file + contentTopic*: string # the log of nullifiers and Shamir shares of the past messages grouped per epoch nullifierLog*: Table[Epoch, seq[ProofMetadata]] diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index cd842ad49e..28562fc9d0 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -454,16 +454,22 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Optio if abs(gap) >= MAX_EPOCH_GAP: # message's epoch is too old or too ahead # accept messages whose epoch is within +-MAX_EPOCH_GAP from the current epoch + debug "invalid message: epoch gap exceeds a threshold",gap=gap return MessageValidationResult.Invalid # verify the proof - if not rlnPeer.rlnInstance.proofVerify(msg.payload, msg.proof): + let + contentTopicBytes = msg.contentTopic.toBytes + input = concat(msg.payload, contentTopicBytes) + if not rlnPeer.rlnInstance.proofVerify(input, msg.proof): # invalid proof + debug "invalid message: invalid proof" return MessageValidationResult.Invalid # check if double messaging has happened let hasDup = rlnPeer.hasDuplicate(msg) if hasDup.isOk and hasDup.value == true: + debug "invalid message: message is a spam" return MessageValidationResult.Spam # insert the message to the log From 81834026bdc6cb8c13f9856e1eeee75f8c59e6fd Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Sat, 5 Feb 2022 01:59:55 +0100 Subject: [PATCH 11/22] Squashed commit of the following: commit bc36c99ab202d07baa0a5f0100bd10d1d76fdfa1 Merge: dc2b2946 5a77d6e2 Author: G <28568419+s1fr0@users.noreply.github.com> Date: Sat Feb 5 01:10:06 2022 +0100 Merge branch 'master' into int64-timestamps-ns commit dc2b294667bb5770cc32b93cc560638cf5ce7087 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Sat Feb 5 00:24:45 2022 +0100 Fix commit f97b95a036a197938df38a5adaea46fca778016d Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Sat Feb 5 00:13:18 2022 +0100 Missing import commit 060c4f8d64e1b6e7c0593540fa8fa7f4cadf6df7 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Sat Feb 5 00:10:36 2022 +0100 Fixed typo commit 08ca99b6f692d3df6d4c7c2312c7cada05fc0041 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 23:59:20 2022 +0100 Time util file commit 2b5c360746990936dec256e90d08dae3c3e35a94 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 23:33:20 2022 +0100 Moved time utility functions to utils/time commit fdaf121f089aa011855303cc8dd1ce52aec506ad Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 23:10:25 2022 +0100 Fix comment commit c7e06ab4e7618d9a3fe8aa744dd48bf3f7d8754c Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 23:04:13 2022 +0100 Restore previous migration script commit 80282db1d79df676255d4b8e6e09d9f8a2b00fd3 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 22:54:15 2022 +0100 Typo commit b9d67f89b0eea11a8362dbb10b5f9d6894343352 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 22:49:29 2022 +0100 Added utilities to get int64 nanosecond, microsecond, millisecond time resolution from float commit 0130d496e694a01cfc9eeb90b7cbc77764490bf9 Author: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Fri Feb 4 22:36:35 2022 +0100 Switched to nanoseconds support. --- tests/v2/test_jsonrpc_waku.nim | 7 ++++--- tests/v2/test_message_store.nim | 7 ++++--- waku/v2/node/quicksim2.nim | 11 ++++++----- .../waku_rln_relay/waku_rln_relay_utils.nim | 3 +-- waku/v2/protocol/waku_store/waku_store.nim | 5 +++-- waku/v2/utils/pagination.nim | 2 +- waku/v2/utils/time.nim | 15 +++++++++++++++ 7 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 waku/v2/utils/time.nim diff --git a/tests/v2/test_jsonrpc_waku.nim b/tests/v2/test_jsonrpc_waku.nim index a3cb320a7f..817ba5363a 100644 --- a/tests/v2/test_jsonrpc_waku.nim +++ b/tests/v2/test_jsonrpc_waku.nim @@ -25,6 +25,7 @@ import ../../waku/v2/protocol/waku_swap/waku_swap, ../../waku/v2/protocol/waku_filter/waku_filter, ../../waku/v2/utils/peers, + ../../waku/v2/utils/time, ../test_helpers template sourceDir*: string = currentSourcePath.rsplit(DirSep, 1)[0] @@ -102,7 +103,7 @@ procSuite "Waku v2 JSON-RPC API": response == true # Publish a message on the default topic - response = await client.post_waku_v2_relay_v1_message(defaultTopic, WakuRelayMessage(payload: @[byte 1], contentTopic: some(defaultContentTopic), timestamp: some(int64(epochTime())))) + response = await client.post_waku_v2_relay_v1_message(defaultTopic, WakuRelayMessage(payload: @[byte 1], contentTopic: some(defaultContentTopic), timestamp: some(getNanosecondTime(epochTime())))) check: # @TODO poll topic to verify message has been published @@ -573,7 +574,7 @@ procSuite "Waku v2 JSON-RPC API": pubSubTopic = "polling" contentTopic = defaultContentTopic payload = @[byte 9] - message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(int64(epochTime()))) + message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(getNanosecondTime(epochTime()))) topicCache = newTable[string, seq[WakuMessage]]() await node1.start() @@ -664,7 +665,7 @@ procSuite "Waku v2 JSON-RPC API": pubSubTopic = "polling" contentTopic = defaultContentTopic payload = @[byte 9] - message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(int64(epochTime()))) + message = WakuRelayMessage(payload: payload, contentTopic: some(contentTopic), timestamp: some(getNanosecondTime(epochTime()))) topicCache = newTable[string, seq[WakuMessage]]() await node1.start() diff --git a/tests/v2/test_message_store.nim b/tests/v2/test_message_store.nim index 8c500f9a46..6260fbdbb7 100644 --- a/tests/v2/test_message_store.nim +++ b/tests/v2/test_message_store.nim @@ -6,6 +6,7 @@ import ../../waku/v2/node/storage/message/waku_message_store, ../../waku/v2/node/storage/sqlite, ../../waku/v2/protocol/waku_store/waku_store, + ../../waku/v2/utils/time, ./utils suite "Message Store": @@ -16,9 +17,9 @@ suite "Message Store": topic = ContentTopic("/waku/2/default-content/proto") pubsubTopic = "/waku/2/default-waku/proto" - t1 = int64(epochTime()) - t2 = int64(epochTime()) - t3 = int64(high(float64)) + t1 = getNanosecondTime(epochTime()) + t2 = getNanosecondTime(epochTime()) + t3 = getNanosecondTime(high(float64)) var msgs = @[ WakuMessage(payload: @[byte 1, 2, 3], contentTopic: topic, version: uint32(0), timestamp: t1), WakuMessage(payload: @[byte 1, 2, 3, 4], contentTopic: topic, version: uint32(1), timestamp: t2), diff --git a/waku/v2/node/quicksim2.nim b/waku/v2/node/quicksim2.nim index b8ad02e2db..f3cac49edf 100644 --- a/waku/v2/node/quicksim2.nim +++ b/waku/v2/node/quicksim2.nim @@ -12,6 +12,7 @@ import ../protocol/waku_filter/waku_filter_types, ../protocol/waku_store/waku_store_types, ../protocol/waku_message, + ../utils/time, ./wakunode2, ./waku_payload, ./jsonrpc/[jsonrpc_types,jsonrpc_utils] @@ -63,11 +64,11 @@ os.sleep(2000) for i in 0.. Date: Sat, 5 Feb 2022 02:18:03 +0100 Subject: [PATCH 12/22] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27437ad3f7..d40ca99006 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,9 @@ The full list of changes is below. ### Changes +- Timestamps resolution changed to nanoseconds (type changed from float64 to int64). - ... + ### Fixes - ... From 3ec1fb0ff315b9503a1421c7e6bebe34ffe1fa6b Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Sat, 5 Feb 2022 02:22:48 +0100 Subject: [PATCH 13/22] Create 00003_convertTimestampsToInt64.up.sql Migration script --- .../00003_convertTimestampsToInt64.up.sql | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 waku/v2/node/00003_convertTimestampsToInt64.up.sql diff --git a/waku/v2/node/00003_convertTimestampsToInt64.up.sql b/waku/v2/node/00003_convertTimestampsToInt64.up.sql new file mode 100644 index 0000000000..55dd292f1e --- /dev/null +++ b/waku/v2/node/00003_convertTimestampsToInt64.up.sql @@ -0,0 +1,30 @@ +CREATE TABLE IF NOT EXISTS Message_backup ( + id BLOB PRIMARY KEY, + receiverTimestamp REAL NOT NULL, + contentTopic BLOB NOT NULL, + pubsubTopic BLOB NOT NULL, + payload BLOB, + version INTEGER NOT NULL, + senderTimestamp REAL NOT NULL + ) WITHOUT ROWID; + +INSERT INTO Message_backup SELECT id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp FROM Message; + +DROP TABLE Message; + +CREATE TABLE IF NOT EXISTS Message( + id BLOB PRIMARY KEY, + receiverTimestamp INTEGER NOT NULL, + contentTopic BLOB NOT NULL, + pubsubTopic BLOB NOT NULL, + payload BLOB, + version INTEGER NOT NULL, + senderTimestamp INTEGER NOT NULL + ) WITHOUT ROWID; + + +INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, version, senderTimestamp) + SELECT id, FLOOR(receiverTimestamp*1000000000), contentTopic, pubsubTopic, payload, version, FLOOR(senderTimestamp*1000000000) + FROM Message_backup; + +DROP TABLE Message_backup; \ No newline at end of file From 3e6eaec44a50661721308b0a855333b06145620e Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Sat, 5 Feb 2022 08:55:09 +0100 Subject: [PATCH 14/22] Moved migration script to right location --- .../message}/00003_convertTimestampsToInt64.up.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename waku/v2/node/{ => storage/migration/migrations_scripts/message}/00003_convertTimestampsToInt64.up.sql (100%) diff --git a/waku/v2/node/00003_convertTimestampsToInt64.up.sql b/waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInt64.up.sql similarity index 100% rename from waku/v2/node/00003_convertTimestampsToInt64.up.sql rename to waku/v2/node/storage/migration/migrations_scripts/message/00003_convertTimestampsToInt64.up.sql From dbddfb52a6778d232c81b4eeb194785a42e444ad Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Sun, 6 Feb 2022 20:42:00 +0100 Subject: [PATCH 15/22] Update waku_rln_relay_utils.nim --- waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index 901859307f..1f3a5f4335 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -453,7 +453,7 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Optio if abs(gap) >= MAX_EPOCH_GAP: # message's epoch is too old or too ahead # accept messages whose epoch is within +-MAX_EPOCH_GAP from the current epoch - debug "invalid message: epoch gap exceeds a threshold",gap=gap + debug "invalid message: epoch gap exceeds a threshold",gap=gap,epoch=epoch,msgEpoch=msgEpoch return MessageValidationResult.Invalid # verify the proof From 363916ff9eafbc6c3770c029f67fa538fe157f21 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Sun, 6 Feb 2022 21:52:50 +0100 Subject: [PATCH 16/22] Update waku_rln_relay_utils.nim --- waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index 1f3a5f4335..901859307f 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -453,7 +453,7 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Optio if abs(gap) >= MAX_EPOCH_GAP: # message's epoch is too old or too ahead # accept messages whose epoch is within +-MAX_EPOCH_GAP from the current epoch - debug "invalid message: epoch gap exceeds a threshold",gap=gap,epoch=epoch,msgEpoch=msgEpoch + debug "invalid message: epoch gap exceeds a threshold",gap=gap return MessageValidationResult.Invalid # verify the proof From c81602470ce556e2c2436a02683c7aa8d2a63ff0 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Tue, 8 Feb 2022 23:54:42 +0100 Subject: [PATCH 17/22] Addressed reviewers' comments --- tests/v2/test_jsonrpc_waku.nim | 2 +- tests/v2/test_message_store.nim | 14 ++-- tests/v2/test_waku_pagination.nim | 7 +- tests/v2/test_waku_store.nim | 77 ++++++++++--------- tests/v2/test_wakunode.nim | 3 +- waku/common/wakubridge.nim | 3 +- waku/v2/node/jsonrpc/jsonrpc_callsigs.nim | 2 +- waku/v2/node/jsonrpc/jsonrpc_types.nim | 5 +- waku/v2/node/jsonrpc/jsonrpc_utils.nim | 9 ++- waku/v2/node/jsonrpc/store_api.nim | 7 +- .../v2/node/storage/message/message_store.nim | 3 +- .../storage/message/waku_message_store.nim | 17 ++-- .../message/00002_addSenderTimeStamp.up.sql | 2 +- waku/v2/protocol/waku_message.nim | 9 ++- waku/v2/protocol/waku_store/waku_store.nim | 26 +++---- .../protocol/waku_store/waku_store_types.nim | 5 +- waku/v2/utils/pagination.nim | 8 +- waku/v2/utils/time.nim | 28 ++++--- 18 files changed, 125 insertions(+), 102 deletions(-) diff --git a/tests/v2/test_jsonrpc_waku.nim b/tests/v2/test_jsonrpc_waku.nim index 817ba5363a..19fe4d4b9a 100644 --- a/tests/v2/test_jsonrpc_waku.nim +++ b/tests/v2/test_jsonrpc_waku.nim @@ -261,7 +261,7 @@ procSuite "Waku v2 JSON-RPC API": let client = newRpcHttpClient() await client.connect("127.0.0.1", rpcPort, false) - let response = await client.get_waku_v2_store_v1_messages(some(defaultTopic), some(@[HistoryContentFilter(contentTopic: defaultContentTopic)]), some(0.int64), some(9.int64), some(StorePagingOptions())) + let response = await client.get_waku_v2_store_v1_messages(some(defaultTopic), some(@[HistoryContentFilter(contentTopic: defaultContentTopic)]), some(Timestamp(0)), some(Timestamp(9)), some(StorePagingOptions())) check: response.messages.len() == 8 response.pagingOptions.isSome() diff --git a/tests/v2/test_message_store.nim b/tests/v2/test_message_store.nim index 6260fbdbb7..fc70318047 100644 --- a/tests/v2/test_message_store.nim +++ b/tests/v2/test_message_store.nim @@ -46,7 +46,7 @@ suite "Message Store": var msgFlag, psTopicFlag = true var responseCount = 0 - proc data(receiverTimestamp: int64, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = + proc data(receiverTimestamp: Timestamp, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = responseCount += 1 # Note: cannot use `check` within `{.raises: [Defect].}` block: @@ -137,7 +137,7 @@ suite "Message Store": for i in 1..capacity: let - msg = WakuMessage(payload: @[byte i], contentTopic: contentTopic, version: uint32(0), timestamp: i.int64) + msg = WakuMessage(payload: @[byte i], contentTopic: contentTopic, version: uint32(0), timestamp: Timestamp(i)) index = computeIndex(msg) output = store.put(index, msg, pubsubTopic) @@ -146,9 +146,9 @@ suite "Message Store": var responseCount = 0 - lastMessageTimestamp = 0.int64 + lastMessageTimestamp = Timestamp(0) - proc data(receiverTimestamp: int64, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = + proc data(receiverTimestamp: Timestamp, msg: WakuMessage, psTopic: string) {.raises: [Defect].} = responseCount += 1 lastMessageTimestamp = msg.timestamp @@ -158,7 +158,7 @@ suite "Message Store": check: resMax.isOk responseCount == capacity # We retrieved all items - lastMessageTimestamp == capacity.int64 # Returned rows were ordered correctly + lastMessageTimestamp == Timestamp(capacity) # Returned rows were ordered correctly # Now test getAll with a limit smaller than total stored items responseCount = 0 # Reset response count @@ -168,7 +168,7 @@ suite "Message Store": check: resLimit.isOk responseCount == capacity - 2 # We retrieved limited number of items - lastMessageTimestamp == capacity.int64 # We retrieved the youngest items in the store, in order + lastMessageTimestamp == Timestamp(capacity) # We retrieved the youngest items in the store, in order # Test zero limit responseCount = 0 # Reset response count @@ -178,4 +178,4 @@ suite "Message Store": check: resZero.isOk responseCount == 0 # No items retrieved - lastMessageTimestamp == 0.int64 # No items retrieved + lastMessageTimestamp == Timestamp(0) # No items retrieved diff --git a/tests/v2/test_waku_pagination.nim b/tests/v2/test_waku_pagination.nim index a5e15f457e..69c3fc27bc 100644 --- a/tests/v2/test_waku_pagination.nim +++ b/tests/v2/test_waku_pagination.nim @@ -4,6 +4,7 @@ import testutils/unittests, nimcrypto/sha2, libp2p/protobuf/minprotobuf, ../../waku/v2/protocol/waku_store/waku_store, + ../../waku/v2/utils/time, ../test_helpers @@ -12,7 +13,7 @@ proc createSampleList(s: int): seq[IndexedWakuMessage] = var data {.noinit.}: array[32, byte] for x in data.mitems: x = 1 for i in 0.. end time - let rpc = HistoryQuery(contentFilters: @[HistoryContentFilter(contentTopic: ContentTopic("1"))], startTime: int64(5), endTime: int64(2)) + let rpc = HistoryQuery(contentFilters: @[HistoryContentFilter(contentTopic: ContentTopic("1"))], startTime: Timestamp(5), endTime: Timestamp(2)) await proto.query(rpc, handler) check: @@ -689,18 +690,18 @@ procSuite "Waku Store": test "find last seen message": var msgList = @[IndexedWakuMessage(msg: WakuMessage(payload: @[byte 0], contentTopic: ContentTopic("2"))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 1],contentTopic: ContentTopic("1"), timestamp: int64(1))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 2],contentTopic: ContentTopic("2"), timestamp: int64(2))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 3],contentTopic: ContentTopic("1"), timestamp: int64(3))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 4],contentTopic: ContentTopic("2"), timestamp: int64(4))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 5],contentTopic: ContentTopic("1"), timestamp: int64(9))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 6],contentTopic: ContentTopic("2"), timestamp: int64(6))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 7],contentTopic: ContentTopic("1"), timestamp: int64(7))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 8],contentTopic: ContentTopic("2"), timestamp: int64(8))), - IndexedWakuMessage(msg: WakuMessage(payload: @[byte 9],contentTopic: ContentTopic("1"),timestamp: int64(5)))] + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 1],contentTopic: ContentTopic("1"), timestamp: Timestamp(1))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 2],contentTopic: ContentTopic("2"), timestamp: Timestamp(2))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 3],contentTopic: ContentTopic("1"), timestamp: Timestamp(3))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 4],contentTopic: ContentTopic("2"), timestamp: Timestamp(4))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 5],contentTopic: ContentTopic("1"), timestamp: Timestamp(9))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 6],contentTopic: ContentTopic("2"), timestamp: Timestamp(6))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 7],contentTopic: ContentTopic("1"), timestamp: Timestamp(7))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 8],contentTopic: ContentTopic("2"), timestamp: Timestamp(8))), + IndexedWakuMessage(msg: WakuMessage(payload: @[byte 9],contentTopic: ContentTopic("1"),timestamp: Timestamp(5)))] check: - findLastSeen(msgList) == int64(9) + findLastSeen(msgList) == Timestamp(9) asyncTest "resume message history": # starts a new node @@ -727,7 +728,7 @@ procSuite "Waku Store": response.messages.len() == 4 completionFut.complete(true) - let rpc = HistoryQuery(startTime: int64(2), endTime: int64(5)) + let rpc = HistoryQuery(startTime: Timestamp(2), endTime: Timestamp(5)) let successResult = await proto.queryFrom(rpc, handler, listenSwitch.peerInfo.toRemotePeerInfo()) check: @@ -737,7 +738,7 @@ procSuite "Waku Store": asyncTest "queryFromWithPaging with empty pagingInfo": - let rpc = HistoryQuery(startTime: int64(2), endTime: int64(5)) + let rpc = HistoryQuery(startTime: Timestamp(2), endTime: Timestamp(5)) let messagesResult = await proto.queryFromWithPaging(rpc, listenSwitch.peerInfo.toRemotePeerInfo()) @@ -747,7 +748,7 @@ procSuite "Waku Store": asyncTest "queryFromWithPaging with pagination": var pinfo = PagingInfo(direction:PagingDirection.FORWARD, pageSize: 1) - let rpc = HistoryQuery(startTime: int64(2), endTime: int64(5), pagingInfo: pinfo) + let rpc = HistoryQuery(startTime: Timestamp(2), endTime: Timestamp(5), pagingInfo: pinfo) let messagesResult = await proto.queryFromWithPaging(rpc, listenSwitch.peerInfo.toRemotePeerInfo()) diff --git a/tests/v2/test_wakunode.nim b/tests/v2/test_wakunode.nim index 06637fbc1a..5cce24e6e8 100644 --- a/tests/v2/test_wakunode.nim +++ b/tests/v2/test_wakunode.nim @@ -21,6 +21,7 @@ import ../../waku/v2/protocol/waku_lightpush/waku_lightpush, ../../waku/v2/node/peer_manager/peer_manager, ../../waku/v2/utils/peers, + ../../waku/v2/utils/time, ../../waku/v2/node/wakunode2, ../test_helpers @@ -1104,7 +1105,7 @@ procSuite "WakuNode": # count the total number of retrieved messages from the database var responseCount = 0 - proc data(receiverTimestamp: int64, msg: WakuMessage, psTopic: string) = + proc data(receiverTimestamp: Timestamp, msg: WakuMessage, psTopic: string) = responseCount += 1 # retrieve all the messages in the db let res = store.getAll(data) diff --git a/waku/common/wakubridge.nim b/waku/common/wakubridge.nim index f97a3cb6d0..d0a54898cb 100644 --- a/waku/common/wakubridge.nim +++ b/waku/common/wakubridge.nim @@ -13,6 +13,7 @@ import # Waku v2 imports libp2p/crypto/crypto, ../v2/utils/namespacing, + ../v2/utils/time, ../v2/node/wakunode2, # Common cli config ./config_bridge @@ -91,7 +92,7 @@ func toWakuMessage(env: Envelope): WakuMessage = # Translate a Waku v1 envelope to a Waku v2 message WakuMessage(payload: env.data, contentTopic: toV2ContentTopic(env.topic), - timestamp: int64(env.expiry - env.ttl), + timestamp: (getNanosecondTime(env.expiry) - getNanosecondTime(env.ttl)), version: 1) proc toWakuV2(bridge: WakuBridge, env: Envelope) {.async.} = diff --git a/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim b/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim index 330317e072..24aba43227 100644 --- a/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim +++ b/waku/v2/node/jsonrpc/jsonrpc_callsigs.nim @@ -16,7 +16,7 @@ proc delete_waku_v2_relay_v1_subscriptions(topics: seq[string]): bool # Store API -proc get_waku_v2_store_v1_messages(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[int64], endTime: Option[int64], pagingOptions: Option[StorePagingOptions]): StoreResponse +proc get_waku_v2_store_v1_messages(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[Timestamp], endTime: Option[Timestamp], pagingOptions: Option[StorePagingOptions]): StoreResponse # Filter API diff --git a/waku/v2/node/jsonrpc/jsonrpc_types.nim b/waku/v2/node/jsonrpc/jsonrpc_types.nim index 611eb2e20f..077991021c 100644 --- a/waku/v2/node/jsonrpc/jsonrpc_types.nim +++ b/waku/v2/node/jsonrpc/jsonrpc_types.nim @@ -4,7 +4,8 @@ import std/[options,tables], eth/keys, ../../protocol/waku_message, - ../../utils/pagination + ../../utils/pagination, + ../../utils/time type StoreResponse* = object @@ -21,7 +22,7 @@ type payload*: seq[byte] contentTopic*: Option[ContentTopic] # sender generated timestamp - timestamp*: Option[int64] + timestamp*: Option[Timestamp] WakuPeer* = object multiaddr*: string diff --git a/waku/v2/node/jsonrpc/jsonrpc_utils.nim b/waku/v2/node/jsonrpc/jsonrpc_utils.nim index 1243f0c678..ddff71654b 100644 --- a/waku/v2/node/jsonrpc/jsonrpc_utils.nim +++ b/waku/v2/node/jsonrpc/jsonrpc_utils.nim @@ -6,6 +6,7 @@ import ../../../v1/node/rpc/hexstrings, ../../protocol/waku_store/waku_store_types, ../../protocol/waku_message, + ../../utils/time, ../waku_payload, ./jsonrpc_types @@ -41,12 +42,12 @@ proc toStoreResponse*(historyResponse: HistoryResponse): StoreResponse = proc toWakuMessage*(relayMessage: WakuRelayMessage, version: uint32): WakuMessage = const defaultCT = ContentTopic("/waku/2/default-content/proto") - var t: int64 + var t: Timestamp if relayMessage.timestamp.isSome: t = relayMessage.timestamp.get else: # incoming WakuRelayMessages with no timestamp will get 0 timestamp - t = int64(0) + t = Timestamp(0) WakuMessage(payload: relayMessage.payload, contentTopic: if relayMessage.contentTopic.isSome: relayMessage.contentTopic.get else: defaultCT, version: version, @@ -60,12 +61,12 @@ proc toWakuMessage*(relayMessage: WakuRelayMessage, version: uint32, rng: ref Br dst: pubKey, symkey: symkey) - var t: int64 + var t: Timestamp if relayMessage.timestamp.isSome: t = relayMessage.timestamp.get else: # incoming WakuRelayMessages with no timestamp will get 0 timestamp - t = int64(0) + t = Timestamp(0) WakuMessage(payload: payload.encode(version, rng[]).get(), contentTopic: if relayMessage.contentTopic.isSome: relayMessage.contentTopic.get else: defaultCT, diff --git a/waku/v2/node/jsonrpc/store_api.nim b/waku/v2/node/jsonrpc/store_api.nim index 474de64841..5b3e99abb3 100644 --- a/waku/v2/node/jsonrpc/store_api.nim +++ b/waku/v2/node/jsonrpc/store_api.nim @@ -5,6 +5,7 @@ import chronicles, json_rpc/rpcserver, ../wakunode2, + ../../utils/time, ./jsonrpc_types, ./jsonrpc_utils export jsonrpc_types @@ -17,7 +18,7 @@ proc installStoreApiHandlers*(node: WakuNode, rpcsrv: RpcServer) = ## Store API version 1 definitions - rpcsrv.rpc("get_waku_v2_store_v1_messages") do(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[int64], endTime: Option[int64], pagingOptions: Option[StorePagingOptions]) -> StoreResponse: + rpcsrv.rpc("get_waku_v2_store_v1_messages") do(pubsubTopicOption: Option[string], contentFiltersOption: Option[seq[HistoryContentFilter]], startTime: Option[Timestamp], endTime: Option[Timestamp], pagingOptions: Option[StorePagingOptions]) -> StoreResponse: ## Returns history for a list of content topics with optional paging debug "get_waku_v2_store_v1_messages" @@ -29,8 +30,8 @@ proc installStoreApiHandlers*(node: WakuNode, rpcsrv: RpcServer) = let historyQuery = HistoryQuery(pubsubTopic: if pubsubTopicOption.isSome: pubsubTopicOption.get() else: "", contentFilters: if contentFiltersOption.isSome: contentFiltersOption.get() else: @[], - startTime: if startTime.isSome: startTime.get() else: 0.int64, - endTime: if endTime.isSome: endTime.get() else: 0.int64, + startTime: if startTime.isSome: startTime.get() else: Timestamp(0), + endTime: if endTime.isSome: endTime.get() else: Timestamp(0), pagingInfo: if pagingOptions.isSome: pagingOptions.get.toPagingInfo() else: PagingInfo()) await node.query(historyQuery, queryFuncHandler) diff --git a/waku/v2/node/storage/message/message_store.nim b/waku/v2/node/storage/message/message_store.nim index 5cedebd06b..104f64a6a3 100644 --- a/waku/v2/node/storage/message/message_store.nim +++ b/waku/v2/node/storage/message/message_store.nim @@ -4,6 +4,7 @@ import std/options, stew/results, ../../../protocol/waku_message, + ../../../utils/time, ../../../utils/pagination ## This module defines a message store interface. Implementations of @@ -11,7 +12,7 @@ import ## retrieve historical messages type - DataProc* = proc(receiverTimestamp: int64, msg: WakuMessage, pubsubTopic: string) {.closure, raises: [Defect].} + DataProc* = proc(receiverTimestamp: Timestamp, msg: WakuMessage, pubsubTopic: string) {.closure, raises: [Defect].} MessageStoreResult*[T] = Result[T, string] diff --git a/waku/v2/node/storage/message/waku_message_store.nim b/waku/v2/node/storage/message/waku_message_store.nim index a4922bdb83..3c83e24f04 100644 --- a/waku/v2/node/storage/message/waku_message_store.nim +++ b/waku/v2/node/storage/message/waku_message_store.nim @@ -7,7 +7,8 @@ import ./message_store, ../sqlite, ../../../protocol/waku_message, - ../../../utils/pagination + ../../../utils/pagination, + ../../../utils/time export sqlite @@ -31,12 +32,12 @@ proc init*(T: type WakuMessageStore, db: SqliteDatabase): MessageStoreResult[T] let prepare = db.prepareStmt(""" CREATE TABLE IF NOT EXISTS """ & TABLE_TITLE & """ ( id BLOB PRIMARY KEY, - receiverTimestamp INTEGER NOT NULL, + receiverTimestamp """ & TIMESTAMP_TABLE_TYPE & """ NOT NULL, contentTopic BLOB NOT NULL, pubsubTopic BLOB NOT NULL, payload BLOB, version INTEGER NOT NULL, - senderTimestamp INTEGER NOT NULL + senderTimestamp """ & TIMESTAMP_TABLE_TYPE & """ NOT NULL ) WITHOUT ROWID; """, NoParams, void) @@ -61,7 +62,7 @@ method put*(db: WakuMessageStore, cursor: Index, message: WakuMessage, pubsubTop ## let prepare = db.database.prepareStmt( "INSERT INTO " & TABLE_TITLE & " (id, receiverTimestamp, contentTopic, payload, pubsubTopic, version, senderTimestamp) VALUES (?, ?, ?, ?, ?, ?, ?);", - (seq[byte], int64, seq[byte], seq[byte], seq[byte], int64, int64), + (seq[byte], Timestamp, seq[byte], seq[byte], seq[byte], int64, Timestamp), void ) @@ -91,7 +92,7 @@ method getAll*(db: WakuMessageStore, onData: message_store.DataProc, limit = non proc msg(s: ptr sqlite3_stmt) = gotMessages = true let - receiverTimestamp = sqlite3_column_double(s, 0) + receiverTimestamp = column_timestamp(s, 0) topic = cast[ptr UncheckedArray[byte]](sqlite3_column_blob(s, 1)) topicLength = sqlite3_column_bytes(s,1) @@ -107,12 +108,12 @@ method getAll*(db: WakuMessageStore, onData: message_store.DataProc, limit = non version = sqlite3_column_int64(s, 4) - senderTimestamp = sqlite3_column_double(s, 5) + senderTimestamp = column_timestamp(s, 5) # TODO retrieve the version number - onData(receiverTimestamp.int64, - WakuMessage(contentTopic: contentTopic, payload: payload , version: uint32(version), timestamp: senderTimestamp.int64), + onData(Timestamp(receiverTimestamp), + WakuMessage(contentTopic: contentTopic, payload: payload , version: uint32(version), timestamp: Timestamp(senderTimestamp)), pubsubTopic) var selectQuery = "SELECT receiverTimestamp, contentTopic, payload, pubsubTopic, version, senderTimestamp " & diff --git a/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql b/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql index 4a6852053b..ce263d1431 100644 --- a/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql +++ b/waku/v2/node/storage/migration/migrations_scripts/message/00002_addSenderTimeStamp.up.sql @@ -26,4 +26,4 @@ INSERT INTO Message (id, receiverTimestamp, contentTopic, pubsubTopic, payload, SELECT id, timestamp, contentTopic, pubsubTopic, payload, version, 0 FROM Message_backup; -DROP TABLE Message_backup; +DROP TABLE Message_backup; \ No newline at end of file diff --git a/waku/v2/protocol/waku_message.nim b/waku/v2/protocol/waku_message.nim index 666639d2b8..c8b6a3729d 100644 --- a/waku/v2/protocol/waku_message.nim +++ b/waku/v2/protocol/waku_message.nim @@ -9,8 +9,9 @@ {.push raises: [Defect].} import - libp2p/protobuf/minprotobuf -import libp2p/varint + libp2p/protobuf/minprotobuf, + libp2p/varint, + ../utils/time when defined(rln): import waku_rln_relay/waku_rln_relay_types @@ -25,7 +26,7 @@ type contentTopic*: ContentTopic version*: uint32 # sender generated timestamp - timestamp*: int64 + timestamp*: Timestamp # the proof field indicates that the message is not a spam # this field will be used in the rln-relay protocol # XXX Experimental, this is part of https://rfc.vac.dev/spec/17/ spec and not yet part of WakuMessage spec @@ -46,7 +47,7 @@ proc init*(T: type WakuMessage, buffer: seq[byte]): ProtoResult[T] = var timestamp: zint64 discard ? pb.getField(4, timestamp) - msg.timestamp = int64(timestamp) + msg.timestamp = Timestamp(timestamp) # XXX Experimental, this is part of https://rfc.vac.dev/spec/17/ spec and not yet part of WakuMessage spec when defined(rln): diff --git a/waku/v2/protocol/waku_store/waku_store.nim b/waku/v2/protocol/waku_store/waku_store.nim index af86a018b4..8bd2ee21d8 100644 --- a/waku/v2/protocol/waku_store/waku_store.nim +++ b/waku/v2/protocol/waku_store/waku_store.nim @@ -114,12 +114,12 @@ proc init*(T: type Index, buffer: seq[byte]): ProtoResult[T] = # read the timestamp var receiverTime: zint64 discard ? pb.getField(2, receiverTime) - index.receiverTime = int64(receiverTime) + index.receiverTime = Timestamp(receiverTime) # read the timestamp var senderTime: zint64 discard ? pb.getField(3, senderTime) - index.senderTime = int64(senderTime) + index.senderTime = Timestamp(senderTime) return ok(index) @@ -171,11 +171,11 @@ proc init*(T: type HistoryQuery, buffer: seq[byte]): ProtoResult[T] = var startTime: zint64 discard ? pb.getField(5, startTime) - msg.startTime = int64(startTime) + msg.startTime = Timestamp(startTime) var endTime: zint64 discard ? pb.getField(6, endTime) - msg.endTime = int64(endTime) + msg.endTime = Timestamp(endTime) return ok(msg) @@ -389,10 +389,10 @@ proc findMessages(w: WakuStore, query: HistoryQuery): HistoryResponse = else: none(seq[ContentTopic]) qPubSubTopic = if (query.pubsubTopic != ""): some(query.pubsubTopic) else: none(string) - qStartTime = if query.startTime != int64(0): some(query.startTime) - else: none(int64) - qEndTime = if query.endTime != int64(0): some(query.endTime) - else: none(int64) + qStartTime = if query.startTime != Timestamp(0): some(query.startTime) + else: none(Timestamp) + qEndTime = if query.endTime != Timestamp(0): some(query.endTime) + else: none(Timestamp) ## Compose filter predicate for message from query criteria proc matchesQuery(indMsg: IndexedWakuMessage): bool = @@ -473,7 +473,7 @@ proc init*(ws: WakuStore, capacity = DefaultStoreCapacity) = if ws.store.isNil: return - proc onData(receiverTime: int64, msg: WakuMessage, pubsubTopic: string) = + proc onData(receiverTime: Timestamp, msg: WakuMessage, pubsubTopic: string) = # TODO index should not be recalculated ws.messages.add(IndexedWakuMessage(msg: msg, index: msg.computeIndex(receiverTime), pubsubTopic: pubsubTopic)) @@ -644,8 +644,8 @@ proc queryLoop(w: WakuStore, query: HistoryQuery, candidateList: seq[RemotePeerI debug "failed to resolve the query" return err("failed to resolve the query") -proc findLastSeen*(list: seq[IndexedWakuMessage]): int64 = - var lastSeenTime = int64(0) +proc findLastSeen*(list: seq[IndexedWakuMessage]): Timestamp = + var lastSeenTime = Timestamp(0) for iwmsg in list.items : if iwmsg.msg.timestamp>lastSeenTime: lastSeenTime = iwmsg.msg.timestamp @@ -671,11 +671,11 @@ proc resume*(ws: WakuStore, peerList: Option[seq[RemotePeerInfo]] = none(seq[Rem ## the resume proc returns the number of retrieved messages if no error occurs, otherwise returns the error string var currentTime = getNanosecondTime(epochTime()) - var lastSeenTime: int64 = findLastSeen(ws.messages.allItems()) + var lastSeenTime: Timestamp = findLastSeen(ws.messages.allItems()) debug "resume", currentEpochTime=currentTime # adjust the time window with an offset of 20 seconds - let offset: int64 = 200000 + let offset: Timestamp = getNanosecondTime(20.0) currentTime = currentTime + offset lastSeenTime = max(lastSeenTime - offset, 0) debug "the offline time window is", lastSeenTime=lastSeenTime, currentTime=currentTime diff --git a/waku/v2/protocol/waku_store/waku_store_types.nim b/waku/v2/protocol/waku_store/waku_store_types.nim index 7174933da3..5ee845db73 100644 --- a/waku/v2/protocol/waku_store/waku_store_types.nim +++ b/waku/v2/protocol/waku_store/waku_store_types.nim @@ -12,6 +12,7 @@ import # internal imports ../../node/storage/message/message_store, ../../utils/pagination, + ../../utils/time, ../../node/peer_manager/peer_manager, ../waku_swap/waku_swap_types, ../waku_message @@ -65,8 +66,8 @@ type contentFilters*: seq[HistoryContentFilter] pubsubTopic*: string pagingInfo*: PagingInfo # used for pagination - startTime*: int64 # used for time-window query - endTime*: int64 # used for time-window query + startTime*: Timestamp # used for time-window query + endTime*: Timestamp # used for time-window query HistoryResponseError* {.pure.} = enum ## HistoryResponseError contains error message to inform the querying node about the state of its request diff --git a/waku/v2/utils/pagination.nim b/waku/v2/utils/pagination.nim index 7dbffcf9ec..3fd68ba5f1 100644 --- a/waku/v2/utils/pagination.nim +++ b/waku/v2/utils/pagination.nim @@ -4,11 +4,13 @@ {.push raises: [Defect].} -import nimcrypto/hash +import + ./time, + nimcrypto/hash type Index* = object ## This type contains the description of an Index used in the pagination of WakuMessages digest*: MDigest[256] - receiverTime*: int64 - senderTime*: int64 # the time at which the message is generated \ No newline at end of file + receiverTime*: Timestamp + senderTime*: Timestamp # the time at which the message is generated \ No newline at end of file diff --git a/waku/v2/utils/time.nim b/waku/v2/utils/time.nim index 76527c7339..4ae653ad71 100644 --- a/waku/v2/utils/time.nim +++ b/waku/v2/utils/time.nim @@ -2,14 +2,24 @@ {.push raises: [Defect].} -proc getNanosecondTime*(t: float64): int64 = - var tns = int64(t*100000000) - return tns +import sqlite3_abi -proc getMicrosecondTime*(t: float64): int64 = - var tmus = int64(t*1000000) - return tmus +type Timestamp* = int64 -proc getMillisecondTime*(t: float64): int64 = - var tms = int64(t*1000) - return tms \ No newline at end of file +const TIMESTAMP_TABLE_TYPE* = "INTEGER" + +proc getNanosecondTime*[T](timeInSeconds: T): Timestamp = + var ns = Timestamp(timeInSeconds*100000000) + return ns + +proc getMicrosecondTime*[T](timeInSeconds: T): Timestamp = + var us = Timestamp(timeInSeconds*1000000) + return us + +proc getMillisecondTime*[T](timeInSeconds: T): Timestamp = + var ms = Timestamp(timeInSeconds*1000) + return ms + + +proc column_timestamp*(a1: ptr sqlite3_stmt, iCol: cint): int64 = + return sqlite3_column_int64(a1, iCol) \ No newline at end of file From a463f3542fd84b154def3d2fdafc293f629ceb14 Mon Sep 17 00:00:00 2001 From: Hanno Cornelius <68783915+jm-clius@users.noreply.github.com> Date: Tue, 8 Feb 2022 12:22:06 +0100 Subject: [PATCH 18/22] Update default fleet metrics dashboard (#844) --- metrics/waku_fleet_dashboard.json | 1298 ++++++++++++++++++----------- 1 file changed, 829 insertions(+), 469 deletions(-) diff --git a/metrics/waku_fleet_dashboard.json b/metrics/waku_fleet_dashboard.json index a209c58075..621bfd9d28 100644 --- a/metrics/waku_fleet_dashboard.json +++ b/metrics/waku_fleet_dashboard.json @@ -8,21 +8,27 @@ "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, "type": "dashboard" } ] }, "description": "Metrics for Waku nodes written in Nim", "editable": true, - "gnetId": null, + "fiscalYearStartMonth": 0, "graphTooltip": 0, "id": 36, - "iteration": 1629304165221, + "iteration": 1644253194447, "links": [], + "liveNow": false, "panels": [ { "collapsed": false, - "datasource": null, "gridPos": { "h": 1, "w": 24, @@ -35,13 +41,14 @@ "type": "row" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, "mappings": [], + "max": 150, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ @@ -60,6 +67,14 @@ { "color": "green", "value": 2 + }, + { + "color": "#EAB839", + "value": 120 + }, + { + "color": "red", + "value": 149 } ] } @@ -74,6 +89,7 @@ }, "id": 52, "options": { + "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" @@ -85,7 +101,7 @@ "showThresholdMarkers": true, "text": {} }, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "targets": [ { "exemplar": true, @@ -99,7 +115,6 @@ "type": "gauge" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -144,7 +159,7 @@ }, "textMode": "auto" }, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "targets": [ { "exemplar": true, @@ -158,7 +173,6 @@ "type": "stat" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -204,7 +218,7 @@ "showUnfilled": true, "text": {} }, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "targets": [ { "exemplar": true, @@ -218,107 +232,399 @@ "type": "bargauge" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, + "description": "", "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 11 }, - "hiddenSeries": false, "id": 11, - "legend": { - "alignAsTable": false, - "avg": true, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } }, - "percentage": false, - "pluginVersion": "8.0.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "pluginVersion": "8.3.1", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, "exemplar": true, - "expr": "waku_node_messages_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "expr": "rate(waku_node_messages_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}[1m])", "interval": "", "legendFormat": "{{type}}: {{instance}}", "refId": "A" } ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Total Messages", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" + "title": "Messages (rate per minute)", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "store store_failure: node-01.do-ams3.wakuv2.prod" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 11 }, - "yaxes": [ + "id": 54, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ { - "$$hashKey": "object:115", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true + "exemplar": true, + "expr": "waku_peers_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", + "interval": "", + "legendFormat": "peer {{type}}: {{instance}}", + "refId": "A" }, { - "$$hashKey": "object:116", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true + "exemplar": true, + "expr": "waku_store_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", + "hide": false, + "interval": "", + "legendFormat": "store {{type}}: {{instance}}", + "refId": "B" + }, + { + "exemplar": true, + "expr": "waku_node_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", + "hide": false, + "interval": "", + "legendFormat": "node {{type}}: {{instance}}", + "refId": "C" } ], - "yaxis": { - "align": false, - "alignLevel": null - } + "title": "Waku Errors", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 66, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, + "exemplar": true, + "expr": "count(count by (contentTopic)(waku_node_messages_total))", + "interval": "", + "legendFormat": "content topics", + "refId": "A" + } + ], + "title": "Total Content Topics", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 68, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, + "exemplar": true, + "expr": "topk(10, (sum by (contentTopic)(rate(waku_node_messages_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}[1m]))))", + "interval": "", + "legendFormat": "{{contentTopic}}", + "refId": "A" + } + ], + "title": "Top content topics (message rate per minute)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 17, + "panels": [], + "title": "General", + "type": "row" }, { - "datasource": null, + "description": "", "fieldConfig": { "defaults": { "color": { @@ -370,12 +676,12 @@ "overrides": [] }, "gridPos": { - "h": 9, + "h": 6, "w": 12, - "x": 12, - "y": 11 + "x": 0, + "y": 29 }, - "id": 54, + "id": 48, "options": { "legend": { "calcs": [], @@ -389,48 +695,16 @@ "targets": [ { "exemplar": true, - "expr": "waku_peers_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", + "expr": "waku_node_filters{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", "interval": "", - "legendFormat": "peer {{type}}: {{instance}}", + "legendFormat": "{{instance}}", "refId": "A" - }, - { - "exemplar": true, - "expr": "waku_store_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", - "hide": false, - "interval": "", - "legendFormat": "store {{type}}: {{instance}}", - "refId": "B" - }, - { - "exemplar": true, - "expr": "waku_node_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", - "hide": false, - "interval": "", - "legendFormat": "node {{type}}: {{instance}}", - "refId": "C" } ], - "title": "Waku Errors", + "title": "Waku Node Filters", "type": "timeseries" }, { - "collapsed": false, - "datasource": null, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 20 - }, - "id": 17, - "panels": [], - "title": "General", - "type": "row" - }, - { - "datasource": null, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -484,10 +758,10 @@ "gridPos": { "h": 6, "w": 12, - "x": 0, - "y": 21 + "x": 12, + "y": 29 }, - "id": 48, + "id": 50, "options": { "legend": { "calcs": [], @@ -501,17 +775,16 @@ "targets": [ { "exemplar": true, - "expr": "waku_node_filters{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", + "expr": "waku_node_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", "interval": "", - "legendFormat": "{{instance}}", + "legendFormat": "{{type}}: {{instance}}", "refId": "A" } ], - "title": "Waku Node Filters", + "title": "Waku Node Errors", "type": "timeseries" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -565,10 +838,10 @@ "gridPos": { "h": 6, "w": 12, - "x": 12, - "y": 21 + "x": 0, + "y": 35 }, - "id": 50, + "id": 60, "options": { "legend": { "calcs": [], @@ -581,14 +854,42 @@ }, "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, "exemplar": true, - "expr": "waku_node_errors{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", + "expr": "libp2p_pubsub_topics {instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", "interval": "", - "legendFormat": "{{type}}: {{instance}}", + "legendFormat": "Topics: {{instance}}", "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, + "exemplar": true, + "expr": "libp2p_pubsub_subscriptions_total {instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "hide": false, + "interval": "", + "legendFormat": "Subscriptions: {{instance}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, + "exemplar": true, + "expr": "libp2p_pubsub_unsubscriptions_total {instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "hide": false, + "interval": "", + "legendFormat": "Unsubscriptions: {{instance}}", + "refId": "C" } ], - "title": "Waku Node Errors", + "title": "Pubsub Topics", "type": "timeseries" }, { @@ -596,7 +897,93 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 5, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 35 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (instance)(libp2p_pubsub_peers{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"})", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "LibP2P PubSub Peers", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1232", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1233", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, "fieldConfig": { "defaults": { "links": [] @@ -609,7 +996,7 @@ "h": 6, "w": 12, "x": 0, - "y": 27 + "y": 41 }, "hiddenSeries": false, "id": 2, @@ -631,7 +1018,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -648,9 +1035,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "LibP2P Peers", "tooltip": { "shared": true, @@ -659,9 +1044,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -669,25 +1052,18 @@ { "$$hashKey": "object:1306", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:1307", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -695,30 +1071,29 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 5, + "fill": 1, "fillGradient": 0, "gridPos": { "h": 6, "w": 12, "x": 12, - "y": 27 + "y": 41 }, "hiddenSeries": false, - "id": 8, + "id": 9, "legend": { - "alignAsTable": false, + "alignAsTable": true, "avg": true, "current": false, "max": false, "min": false, - "rightSide": false, + "rightSide": true, "show": true, "total": false, "values": true @@ -730,27 +1105,40 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, - "stack": true, + "stack": false, "steppedLine": false, "targets": [ { - "expr": "sum by (instance)(libp2p_pubsub_peers{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"})", + "expr": "libp2p_pubsub_validation_success_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "hide": false, "interval": "", - "legendFormat": "{{instance}}", + "legendFormat": "success", "refId": "A" + }, + { + "expr": "libp2p_pubsub_validation_failure_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "hide": false, + "interval": "", + "legendFormat": "failure", + "refId": "B" + }, + { + "expr": "libp2p_pubsub_validation_ignore_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "hide": false, + "interval": "", + "legendFormat": "ignore", + "refId": "C" } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, - "title": "LibP2P PubSub Peers", + "title": "LibP2P Validations", "tooltip": { "shared": true, "sort": 2, @@ -758,35 +1146,26 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, "yaxes": [ { - "$$hashKey": "object:1232", + "$$hashKey": "object:189", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { - "$$hashKey": "object:1233", + "$$hashKey": "object:190", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -794,7 +1173,6 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { "links": [] @@ -807,7 +1185,7 @@ "h": 6, "w": 12, "x": 0, - "y": 33 + "y": 47 }, "hiddenSeries": false, "id": 3, @@ -829,7 +1207,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -846,9 +1224,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "LibP2P Open Streams", "tooltip": { "shared": true, @@ -857,9 +1233,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -867,25 +1241,18 @@ { "$$hashKey": "object:115", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:116", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -893,7 +1260,6 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { "links": [] @@ -906,17 +1272,17 @@ "h": 6, "w": 12, "x": 12, - "y": 33 + "y": 47 }, "hiddenSeries": false, - "id": 9, + "id": 7, "legend": { - "alignAsTable": true, + "alignAsTable": false, "avg": true, "current": false, "max": false, "min": false, - "rightSide": true, + "rightSide": false, "show": true, "total": false, "values": true @@ -928,7 +1294,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -938,32 +1304,34 @@ "steppedLine": false, "targets": [ { - "expr": "libp2p_pubsub_validation_success_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "exemplar": true, + "expr": "libp2p_total_dial_attempts_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "format": "time_series", "hide": false, "interval": "", - "legendFormat": "success", + "legendFormat": "Attempts: {{instance}}", "refId": "A" }, { - "expr": "libp2p_pubsub_validation_failure_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "exemplar": true, + "expr": "libp2p_failed_dials_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", "hide": false, "interval": "", - "legendFormat": "failure", + "legendFormat": "Failed: {{instance}}", "refId": "B" }, { - "expr": "libp2p_pubsub_validation_ignore_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "exemplar": true, + "expr": "libp2p_successful_dials_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", "hide": false, "interval": "", - "legendFormat": "ignore", + "legendFormat": "Successful: {{instance}}", "refId": "C" } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, - "title": "LibP2P Validations", + "title": "LibP2P Dials", "tooltip": { "shared": true, "sort": 2, @@ -971,9 +1339,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -981,25 +1347,18 @@ { "$$hashKey": "object:189", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:190", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -1007,7 +1366,6 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { "links": [] @@ -1020,7 +1378,7 @@ "h": 6, "w": 12, "x": 0, - "y": 39 + "y": 53 }, "hiddenSeries": false, "id": 6, @@ -1042,7 +1400,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -1059,9 +1417,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "Open File Descriptors", "tooltip": { "shared": true, @@ -1070,9 +1426,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -1080,25 +1434,18 @@ { "$$hashKey": "object:511", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:512", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -1106,10 +1453,10 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unit": "percent" }, "overrides": [] }, @@ -1119,15 +1466,15 @@ "h": 6, "w": 12, "x": 12, - "y": 39 + "y": 53 }, "hiddenSeries": false, - "id": 7, + "id": 10, "legend": { "alignAsTable": false, - "avg": true, + "avg": false, "current": false, - "max": false, + "max": true, "min": false, "rightSide": false, "show": true, @@ -1141,46 +1488,27 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "libp2p_total_dial_attempts_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", - "format": "time_series", - "hide": false, - "interval": "", - "legendFormat": "Attempts: {{instance}}", - "refId": "A" - }, - { - "exemplar": true, - "expr": "libp2p_failed_dials_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", - "hide": false, - "interval": "", - "legendFormat": "Failed: {{instance}}", - "refId": "B" - }, + "stack": false, + "steppedLine": false, + "targets": [ { "exemplar": true, - "expr": "libp2p_successful_dials_total{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "expr": "avg by (instance)(netdata_cpu_cpu_percentage_average{dimension=\"user\", instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"})", "hide": false, "interval": "", - "legendFormat": "Successful: {{instance}}", - "refId": "C" + "legendFormat": "{{instance}}", + "refId": "A" } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, - "title": "LibP2P Dials", + "title": "CPU Usage", "tooltip": { "shared": true, "sort": 2, @@ -1188,39 +1516,29 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, "yaxes": [ { "$$hashKey": "object:189", - "format": "short", - "label": null, + "format": "percent", "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:190", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { - "datasource": null, "description": "", "fieldConfig": { "defaults": { @@ -1274,10 +1592,10 @@ "overrides": [] }, "gridPos": { - "h": 6, + "h": 8, "w": 12, "x": 0, - "y": 45 + "y": 59 }, "id": 44, "options": { @@ -1292,6 +1610,10 @@ }, "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, "exemplar": true, "expr": "nim_gc_mem_bytes{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", "interval": "", @@ -1299,125 +1621,123 @@ "refId": "A" }, { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, "exemplar": true, "expr": "nim_gc_mem_occupied_bytes{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", "hide": false, "interval": "", "legendFormat": "Nim occupied memory: {{instance}}", "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, + "exemplar": true, + "expr": "nim_gc_heap_instance_occupied_summed_bytes", + "hide": false, + "interval": "", + "legendFormat": "Nim total heap: {{instance}}", + "refId": "C" } ], "title": "Nim Memory Usage", "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { - "links": [], - "unit": "percent" + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { - "h": 6, + "h": 8, "w": 12, "x": 12, - "y": 45 + "y": 59 }, - "hiddenSeries": false, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": true, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", + "id": 64, "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } }, - "percentage": false, - "pluginVersion": "8.0.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, "exemplar": true, - "expr": "avg by (instance)(netdata_cpu_cpu_percentage_average{dimension=\"user\", instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"})", - "hide": false, + "expr": "nim_gc_heap_instance_occupied_bytes{instance=~\"[[host]].([[dc:pipe]]).*.([[fleet:pipe]])\"}", "interval": "", - "legendFormat": "{{instance}}", + "legendFormat": "{{instance}} {{type_name}}", "refId": "A" } ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:189", - "format": "percent", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "$$hashKey": "object:190", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } + "title": "Heap allocation", + "type": "timeseries" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { "links": [] @@ -1430,7 +1750,7 @@ "h": 6, "w": 12, "x": 0, - "y": 51 + "y": 67 }, "hiddenSeries": false, "id": 4, @@ -1452,7 +1772,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -1469,9 +1789,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "Virtual Memory", "tooltip": { "shared": true, @@ -1480,9 +1798,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -1490,25 +1806,18 @@ { "$$hashKey": "object:263", "format": "decbytes", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:264", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -1516,7 +1825,6 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "fieldConfig": { "defaults": { "links": [] @@ -1529,7 +1837,7 @@ "h": 6, "w": 12, "x": 12, - "y": 51 + "y": 67 }, "hiddenSeries": false, "id": 5, @@ -1551,7 +1859,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -1568,9 +1876,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "Resident Memory", "tooltip": { "shared": true, @@ -1579,9 +1885,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -1589,35 +1893,27 @@ { "$$hashKey": "object:437", "format": "decbytes", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:438", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { "collapsed": false, - "datasource": null, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 57 + "y": 73 }, "id": 34, "panels": [], @@ -1625,7 +1921,6 @@ "type": "row" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -1677,10 +1972,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 8, + "h": 9, + "w": 12, "x": 0, - "y": 58 + "y": 74 }, "id": 36, "options": { @@ -1706,7 +2001,6 @@ "type": "timeseries" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -1758,10 +2052,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 8, - "x": 8, - "y": 58 + "h": 9, + "w": 12, + "x": 12, + "y": 74 }, "id": 38, "options": { @@ -1787,7 +2081,115 @@ "type": "timeseries" }, { - "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "node-01.do-ams3.wakuv2.prod" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 83 + }, + "id": 62, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P6693426190CB2316" + }, + "exemplar": true, + "expr": "waku_store_queries{instance=~\"[[host]].([[dc:pipe]]).([[fleet:pipe]])\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Waku Store Queries", + "type": "timeseries" + }, + { "fieldConfig": { "defaults": { "color": { @@ -1839,10 +2241,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 8, - "x": 16, - "y": 58 + "h": 9, + "w": 12, + "x": 12, + "y": 83 }, "id": 40, "options": { @@ -1869,12 +2271,11 @@ }, { "collapsed": false, - "datasource": null, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 66 + "y": 92 }, "id": 20, "panels": [], @@ -1882,7 +2283,6 @@ "type": "row" }, { - "datasource": null, "description": "Waku Filter Peers", "fieldConfig": { "defaults": { @@ -1938,7 +2338,7 @@ "h": 8, "w": 8, "x": 0, - "y": 67 + "y": 93 }, "id": 22, "options": { @@ -1965,7 +2365,6 @@ "type": "timeseries" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -2020,7 +2419,7 @@ "h": 8, "w": 8, "x": 8, - "y": 67 + "y": 93 }, "id": 24, "options": { @@ -2046,7 +2445,6 @@ "type": "timeseries" }, { - "datasource": null, "description": "", "fieldConfig": { "defaults": { @@ -2102,7 +2500,7 @@ "h": 8, "w": 8, "x": 16, - "y": 67 + "y": 93 }, "id": 26, "options": { @@ -2129,12 +2527,11 @@ }, { "collapsed": false, - "datasource": null, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 75 + "y": 101 }, "id": 28, "panels": [], @@ -2142,7 +2539,6 @@ "type": "row" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -2197,7 +2593,7 @@ "h": 8, "w": 12, "x": 0, - "y": 76 + "y": 102 }, "id": 30, "options": { @@ -2223,7 +2619,6 @@ "type": "timeseries" }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -2278,7 +2673,7 @@ "h": 8, "w": 12, "x": 12, - "y": 76 + "y": 102 }, "id": 32, "options": { @@ -2305,12 +2700,11 @@ }, { "collapsed": false, - "datasource": null, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 84 + "y": 110 }, "id": 15, "panels": [], @@ -2322,7 +2716,6 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "description": "number of swap peers", "fill": 1, "fillGradient": 0, @@ -2330,7 +2723,7 @@ "h": 7, "w": 8, "x": 0, - "y": 85 + "y": 111 }, "hiddenSeries": false, "id": 13, @@ -2350,7 +2743,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2368,9 +2761,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "Waku Swap Peers", "tooltip": { "shared": true, @@ -2379,9 +2770,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -2389,25 +2778,18 @@ { "$$hashKey": "object:139", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:140", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { @@ -2415,7 +2797,6 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": null, "description": "swap account state for each peer", "fill": 1, "fillGradient": 0, @@ -2423,7 +2804,7 @@ "h": 7, "w": 8, "x": 8, - "y": 85 + "y": 111 }, "hiddenSeries": false, "id": 18, @@ -2446,7 +2827,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "8.0.4", + "pluginVersion": "8.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2511,9 +2892,7 @@ } ], "thresholds": [], - "timeFrom": null, "timeRegions": [], - "timeShift": null, "title": "Waku Swap Account State", "tooltip": { "shared": true, @@ -2522,9 +2901,7 @@ }, "type": "graph", "xaxis": { - "buckets": null, "mode": "time", - "name": null, "show": true, "values": [] }, @@ -2532,29 +2909,21 @@ { "$$hashKey": "object:139", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true }, { "$$hashKey": "object:140", "format": "short", - "label": null, "logBase": 1, - "max": null, - "min": null, "show": true } ], "yaxis": { - "align": false, - "alignLevel": null + "align": false } }, { - "datasource": null, "fieldConfig": { "defaults": { "color": { @@ -2609,7 +2978,7 @@ "h": 7, "w": 8, "x": 16, - "y": 85 + "y": 111 }, "id": 42, "options": { @@ -2635,21 +3004,18 @@ "type": "timeseries" } ], - "refresh": "5m", - "schemaVersion": 30, + "refresh": "30s", + "schemaVersion": 33, "style": "dark", "tags": [], "templating": { "list": [ { - "allValue": null, "current": { "selected": true, "text": ".*", "value": ".*" }, - "description": null, - "error": null, "hide": 0, "includeAll": false, "label": "Hostname regex", @@ -2668,22 +3034,16 @@ "type": "custom" }, { - "allValue": null, "current": { "selected": true, "text": [ - "wakuv2.prod", - "wakuv2.test" + "wakuv2.prod" ], "value": [ - "wakuv2.prod", - "wakuv2.test" + "wakuv2.prod" ] }, - "datasource": null, "definition": "label_values(libp2p_peers, fleet)", - "description": null, - "error": null, "hide": 0, "includeAll": false, "label": "Fleet name", @@ -2704,7 +3064,6 @@ "useTags": false }, { - "allValue": null, "current": { "selected": true, "text": [ @@ -2714,17 +3073,17 @@ "$__all" ] }, - "datasource": "-- Grafana --", "definition": "label_values(libp2p_peers, datacenter)", - "description": null, - "error": null, "hide": 0, "includeAll": true, "label": "Data Center", "multi": true, "name": "dc", "options": [], - "query": "label_values(libp2p_peers, datacenter)", + "query": { + "query": "label_values(libp2p_peers, datacenter)", + "refId": "StandardVariableQuery" + }, "refresh": 1, "regex": "", "skipUrlSync": false, @@ -2737,7 +3096,7 @@ ] }, "time": { - "from": "now-6h", + "from": "now-12h", "to": "now" }, "timepicker": { @@ -2756,5 +3115,6 @@ "timezone": "", "title": "Nim-Waku V2", "uid": "qrp_ZCTGz", - "version": 26 + "version": 37, + "weekStart": "" } \ No newline at end of file From c4363230204265ae86c0698abf474f357a3ed9f8 Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Wed, 9 Feb 2022 00:25:37 +0100 Subject: [PATCH 19/22] Fix --- waku/v2/utils/time.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/waku/v2/utils/time.nim b/waku/v2/utils/time.nim index 4ae653ad71..ac37668b69 100644 --- a/waku/v2/utils/time.nim +++ b/waku/v2/utils/time.nim @@ -20,6 +20,5 @@ proc getMillisecondTime*[T](timeInSeconds: T): Timestamp = var ms = Timestamp(timeInSeconds*1000) return ms - proc column_timestamp*(a1: ptr sqlite3_stmt, iCol: cint): int64 = return sqlite3_column_int64(a1, iCol) \ No newline at end of file From 7072c457f876bb25d833d40dd6848dc487a3af2b Mon Sep 17 00:00:00 2001 From: G <28568419+s1fr0@users.noreply.github.com> Date: Wed, 9 Feb 2022 19:15:47 +0100 Subject: [PATCH 20/22] No need for float --- waku/v2/protocol/waku_store/waku_store.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waku/v2/protocol/waku_store/waku_store.nim b/waku/v2/protocol/waku_store/waku_store.nim index 8bd2ee21d8..30a2459ca5 100644 --- a/waku/v2/protocol/waku_store/waku_store.nim +++ b/waku/v2/protocol/waku_store/waku_store.nim @@ -675,7 +675,7 @@ proc resume*(ws: WakuStore, peerList: Option[seq[RemotePeerInfo]] = none(seq[Rem debug "resume", currentEpochTime=currentTime # adjust the time window with an offset of 20 seconds - let offset: Timestamp = getNanosecondTime(20.0) + let offset: Timestamp = getNanosecondTime(20) currentTime = currentTime + offset lastSeenTime = max(lastSeenTime - offset, 0) debug "the offline time window is", lastSeenTime=lastSeenTime, currentTime=currentTime From 3ac4f653776de28f05fcd4ffb0f8723d97d22d02 Mon Sep 17 00:00:00 2001 From: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:13:19 +0100 Subject: [PATCH 21/22] Aligning master to changes in PR --- tests/v2/test_pagination_utils.nim | 29 +++++++-------- tests/v2/test_waku_store.nim | 4 +-- tests/v2/test_waku_store_queue.nim | 57 +++++++++++++++--------------- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/tests/v2/test_pagination_utils.nim b/tests/v2/test_pagination_utils.nim index 62033efff2..0eb72915fa 100644 --- a/tests/v2/test_pagination_utils.nim +++ b/tests/v2/test_pagination_utils.nim @@ -6,6 +6,7 @@ import stew/byteutils, libp2p/crypto/crypto, ../../waku/v2/utils/pagination + ../../waku/v2/utils/time procSuite "Pagination utils": @@ -24,26 +25,26 @@ procSuite "Pagination utils": ## Test vars let smallIndex1 = Index(digest: hashFromStr("1234"), - receiverTime: 0.00, - senderTime: 1000.00) + receiverTime: getNanosecondTime(0), + senderTime: getNanosecondTime(1000)) smallIndex2 = Index(digest: hashFromStr("1234567"), # digest is less significant than senderTime - receiverTime: 0.00, - senderTime: 1000.00) + receiverTime: getNanosecondTime(0), + senderTime: getNanosecondTime(1000)) largeIndex1 = Index(digest: hashFromStr("1234"), - receiverTime: 0.00, - senderTime: 9000.00) # only senderTime differ from smallIndex1 + receiverTime: getNanosecondTime(0), + senderTime: getNanosecondTime(9000)) # only senderTime differ from smallIndex1 largeIndex2 = Index(digest: hashFromStr("12345"), # only digest differs from smallIndex1 - receiverTime: 0.00, - senderTime: 1000.00) + receiverTime: getNanosecondTime(0), + senderTime: getNanosecondTime(1000)) eqIndex1 = Index(digest: hashFromStr("0003"), - receiverTime: 0.00, - senderTime: 54321.00) + receiverTime: getNanosecondTime(0), + senderTime: getNanosecondTime(54321)) eqIndex2 = Index(digest: hashFromStr("0003"), - receiverTime: 0.00, - senderTime: 54321.00) + receiverTime: getNanosecondTime(0), + senderTime: getNanosecondTime(54321)) eqIndex3 = Index(digest: hashFromStr("0003"), - receiverTime: 9999.00, # receiverTime difference should have no effect on comparisons - senderTime: 54321.00) + receiverTime: getNanosecondTime(9999), # receiverTime difference should have no effect on comparisons + senderTime: getNanosecondTime(54321)) ## Test suite diff --git a/tests/v2/test_waku_store.nim b/tests/v2/test_waku_store.nim index 105a49e3eb..12c515690b 100644 --- a/tests/v2/test_waku_store.nim +++ b/tests/v2/test_waku_store.nim @@ -791,14 +791,14 @@ procSuite "Waku Store": let store = WakuStore.init(PeerManager.new(newStandardSwitch()), crypto.newRng(), capacity = capacity) for i in 1..capacity: - await store.handleMessage(pubsubTopic, WakuMessage(payload: @[byte i], contentTopic: contentTopic, timestamp: i.float64)) + await store.handleMessage(pubsubTopic, WakuMessage(payload: @[byte i], contentTopic: contentTopic, timestamp: Timestamp(i))) await sleepAsync(1.millis) # Sleep a millisecond to ensure messages are stored chronologically check: store.messages.len == capacity # Store is at capacity # Test that capacity holds - await store.handleMessage(pubsubTopic, WakuMessage(payload: @[byte (capacity + 1)], contentTopic: contentTopic, timestamp: (capacity + 1).float64)) + await store.handleMessage(pubsubTopic, WakuMessage(payload: @[byte (capacity + 1)], contentTopic: contentTopic, timestamp: Timestamp(capacity + 1))) check: store.messages.len == capacity # Store is still at capacity diff --git a/tests/v2/test_waku_store_queue.nim b/tests/v2/test_waku_store_queue.nim index 3a88768162..20181322c1 100644 --- a/tests/v2/test_waku_store_queue.nim +++ b/tests/v2/test_waku_store_queue.nim @@ -3,7 +3,8 @@ import std/sequtils, testutils/unittests, - ../../waku/v2/protocol/waku_store/waku_store_types + ../../waku/v2/protocol/waku_store/waku_store_types, + ../../waku/v2/utils/time procSuite "Sorted store queue": @@ -12,8 +13,8 @@ procSuite "Sorted store queue": ## Use i to generate an IndexedWakuMessage var data {.noinit.}: array[32, byte] for x in data.mitems: x = i.byte - return IndexedWakuMessage(msg: WakuMessage(payload: @[byte i], timestamp: float64(i)), - index: Index(receiverTime: float64(i), senderTime: float64(i), digest: MDigest[256](data: data))) + return IndexedWakuMessage(msg: WakuMessage(payload: @[byte i], timestamp: Timestamp(i)), + index: Index(receiverTime: Timestamp(i), senderTime: Timestamp(i), digest: MDigest[256](data: data))) # Test variables let @@ -62,8 +63,8 @@ procSuite "Sorted store queue": let first = testStoreQueue.first() check: first.isOk() - first.get().msg.timestamp == 1.0 - + first.get().msg.timestamp == Timestamp(1) + # Error condition let emptyQ = StoreQueueRef.new(capacity) check: @@ -73,7 +74,7 @@ procSuite "Sorted store queue": let last = testStoreQueue.last() check: last.isOk() - last.get().msg.timestamp == 5.0 + last.get().msg.timestamp == Timestamp(5) # Error condition let emptyQ = StoreQueueRef.new(capacity) @@ -103,9 +104,9 @@ procSuite "Sorted store queue": # Second page pInfo.pageSize == 2 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 5.0 + pInfo.cursor.senderTime == Timestamp(5) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int) == @[4,5] + res.mapIt(it.timestamp.int64) == @[4,5] (res, pInfo, err) = testStoreQueue.getPage(predicate, pInfo) @@ -114,7 +115,7 @@ procSuite "Sorted store queue": # Empty last page pInfo.pageSize == 0 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 5.0 + pInfo.cursor.senderTime == Timestamp(5) err == HistoryResponseError.NONE res.len == 0 @@ -129,9 +130,9 @@ procSuite "Sorted store queue": # First page pInfo.pageSize == 3 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 3.0 + pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int) == @[3,4,5] + res.mapIt(it.timestamp.int64) == @[3,4,5] (res, pInfo, err) = testStoreQueue.getPage(predicate, @@ -141,9 +142,9 @@ procSuite "Sorted store queue": # Second page pInfo.pageSize == 2 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 1.0 + pInfo.cursor.senderTime == Timestamp(1) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int) == @[1,2] + res.mapIt(it.timestamp.int64) == @[1,2] (res, pInfo, err) = testStoreQueue.getPage(predicate, pInfo) @@ -152,7 +153,7 @@ procSuite "Sorted store queue": # Empty last page pInfo.pageSize == 0 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 1.0 + pInfo.cursor.senderTime == Timestamp(1) err == HistoryResponseError.NONE res.len == 0 @@ -170,9 +171,9 @@ procSuite "Sorted store queue": # First page pInfo.pageSize == 2 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 4.0 + pInfo.cursor.senderTime == Timestamp(4) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int) == @[2,4] + res.mapIt(it.timestamp.int64) == @[2,4] (res, pInfo, err) = testStoreQueue.getPage(onlyEvenTimes, pInfo) @@ -181,7 +182,7 @@ procSuite "Sorted store queue": # Empty next page pInfo.pageSize == 0 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 4.0 + pInfo.cursor.senderTime == Timestamp(4) err == HistoryResponseError.NONE res.len == 0 @@ -195,9 +196,9 @@ procSuite "Sorted store queue": # First page pInfo.pageSize == 2 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 3.0 + pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int) == @[3,5] + res.mapIt(it.timestamp.int64) == @[3,5] (res, pInfo, err) = testStoreQueue.getPage(onlyOddTimes, pInfo) @@ -206,9 +207,9 @@ procSuite "Sorted store queue": # Next page pInfo.pageSize == 1 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 1.0 + pInfo.cursor.senderTime == Timestamp(1) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int) == @[1] + res.mapIt(it.timestamp.int64) == @[1] (res, pInfo, err) = testStoreQueue.getPage(onlyOddTimes, pInfo) @@ -217,7 +218,7 @@ procSuite "Sorted store queue": # Empty last page pInfo.pageSize == 0 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 1.0 + pInfo.cursor.senderTime == Timestamp(1) err == HistoryResponseError.NONE res.len == 0 @@ -228,14 +229,14 @@ procSuite "Sorted store queue": var (res, pInfo, err) = testStoreQueue.getPage(predicate, PagingInfo(pageSize: 3, - cursor: Index(receiverTime: float64(3), senderTime: float64(3), digest: MDigest[256]()), + cursor: Index(receiverTime: Timestamp(3), senderTime: Timestamp(3), digest: MDigest[256]()), direction: PagingDirection.BACKWARD)) check: # Empty response with error pInfo.pageSize == 0 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 3.0 + pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.INVALID_CURSOR res.len == 0 @@ -243,14 +244,14 @@ procSuite "Sorted store queue": (res, pInfo, err) = testStoreQueue.getPage(predicate, PagingInfo(pageSize: 3, - cursor: Index(receiverTime: float64(3), senderTime: float64(3), digest: MDigest[256]()), + cursor: Index(receiverTime: Timestamp(3), senderTime: Timestamp(3), digest: MDigest[256]()), direction: PagingDirection.FORWARD)) check: # Empty response with error pInfo.pageSize == 0 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 3.0 + pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.INVALID_CURSOR res.len == 0 @@ -271,7 +272,7 @@ procSuite "Sorted store queue": # Empty response pInfo.pageSize == 0 pInfo.direction == PagingDirection.BACKWARD - pInfo.cursor.senderTime == 0.0 + pInfo.cursor.senderTime == Timestamp(0) err == HistoryResponseError.NONE res.len == 0 @@ -285,7 +286,7 @@ procSuite "Sorted store queue": # Empty response pInfo.pageSize == 0 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 0.0 + pInfo.cursor.senderTime == Timestamp(0) err == HistoryResponseError.NONE res.len == 0 From fe09c2ac30de92d059a4adb33b203b7c8650faa7 Mon Sep 17 00:00:00 2001 From: s1fr0 <28568419+s1fr0@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:23:20 +0100 Subject: [PATCH 22/22] Further fixes --- tests/v2/test_pagination_utils.nim | 2 +- tests/v2/test_waku_store_queue.nim | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/v2/test_pagination_utils.nim b/tests/v2/test_pagination_utils.nim index 0eb72915fa..b4360805c6 100644 --- a/tests/v2/test_pagination_utils.nim +++ b/tests/v2/test_pagination_utils.nim @@ -5,7 +5,7 @@ import chronos, stew/byteutils, libp2p/crypto/crypto, - ../../waku/v2/utils/pagination + ../../waku/v2/utils/pagination, ../../waku/v2/utils/time procSuite "Pagination utils": diff --git a/tests/v2/test_waku_store_queue.nim b/tests/v2/test_waku_store_queue.nim index 20181322c1..224d7fc7b4 100644 --- a/tests/v2/test_waku_store_queue.nim +++ b/tests/v2/test_waku_store_queue.nim @@ -92,7 +92,7 @@ procSuite "Sorted store queue": # First page pInfo.pageSize == 3 pInfo.direction == PagingDirection.FORWARD - pInfo.cursor.senderTime == 3.0 + pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.NONE res.mapIt(it.timestamp.int) == @[1,2,3] @@ -106,7 +106,7 @@ procSuite "Sorted store queue": pInfo.direction == PagingDirection.FORWARD pInfo.cursor.senderTime == Timestamp(5) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int64) == @[4,5] + res.mapIt(it.timestamp.int) == @[4,5] (res, pInfo, err) = testStoreQueue.getPage(predicate, pInfo) @@ -132,7 +132,7 @@ procSuite "Sorted store queue": pInfo.direction == PagingDirection.BACKWARD pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int64) == @[3,4,5] + res.mapIt(it.timestamp.int) == @[3,4,5] (res, pInfo, err) = testStoreQueue.getPage(predicate, @@ -144,7 +144,7 @@ procSuite "Sorted store queue": pInfo.direction == PagingDirection.BACKWARD pInfo.cursor.senderTime == Timestamp(1) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int64) == @[1,2] + res.mapIt(it.timestamp.int) == @[1,2] (res, pInfo, err) = testStoreQueue.getPage(predicate, pInfo) @@ -173,7 +173,7 @@ procSuite "Sorted store queue": pInfo.direction == PagingDirection.FORWARD pInfo.cursor.senderTime == Timestamp(4) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int64) == @[2,4] + res.mapIt(it.timestamp.int) == @[2,4] (res, pInfo, err) = testStoreQueue.getPage(onlyEvenTimes, pInfo) @@ -198,7 +198,7 @@ procSuite "Sorted store queue": pInfo.direction == PagingDirection.BACKWARD pInfo.cursor.senderTime == Timestamp(3) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int64) == @[3,5] + res.mapIt(it.timestamp.int) == @[3,5] (res, pInfo, err) = testStoreQueue.getPage(onlyOddTimes, pInfo) @@ -209,7 +209,7 @@ procSuite "Sorted store queue": pInfo.direction == PagingDirection.BACKWARD pInfo.cursor.senderTime == Timestamp(1) err == HistoryResponseError.NONE - res.mapIt(it.timestamp.int64) == @[1] + res.mapIt(it.timestamp.int) == @[1] (res, pInfo, err) = testStoreQueue.getPage(onlyOddTimes, pInfo)