mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-04 06:53:12 +00:00
* Refactor timestamps type from float64 to int64 (milliseconds resolution) * Revert epochs to float64 * Update 00002_addSenderTimeStamp.up.sql * Update quicksim2.nim * Add files via upload * Delete 00003_convertTimestampsToInts.up.sql * Add files via upload * Rename 00003_convertTimestampsToInts.up.sql to 00003_addTimestampsToInts.up.sql * Delete 00003_addTimestampsToInts.up.sql * 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 * Squashed commit of the following: commit bc36c99ab202d07baa0a5f0100bd10d1d76fdfa1 Merge: dc2b2946 0cd7003d 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. * Update CHANGELOG.md * Create 00003_convertTimestampsToInt64.up.sql Migration script * Moved migration script to right location * Update waku_rln_relay_utils.nim * Update waku_rln_relay_utils.nim * Addressed reviewers' comments * Update default fleet metrics dashboard (#844) * Fix * No need for float * Aligning master to changes in PR * Further fixes Co-authored-by: Sanaz Taheri Boshrooyeh <35961250+staheri14@users.noreply.github.com> Co-authored-by: Hanno Cornelius <68783915+jm-clius@users.noreply.github.com>
312 lines
12 KiB
Nim
312 lines
12 KiB
Nim
{.used.}
|
|
import
|
|
std/[algorithm, options, sequtils],
|
|
testutils/unittests, nimcrypto/sha2,
|
|
libp2p/protobuf/minprotobuf,
|
|
../../waku/v2/protocol/waku_store/waku_store,
|
|
../../waku/v2/utils/time,
|
|
../test_helpers
|
|
|
|
|
|
proc createSampleStoreQueue(s: int): StoreQueueRef =
|
|
## takes s as input and outputs a StoreQueue with s amount of IndexedWakuMessage
|
|
|
|
let testStoreQueue = StoreQueueRef.new(s)
|
|
|
|
var data {.noinit.}: array[32, byte]
|
|
for x in data.mitems: x = 1
|
|
|
|
for i in 0..<s:
|
|
discard testStoreQueue.add(IndexedWakuMessage(msg: WakuMessage(payload: @[byte i]),
|
|
index: Index(receiverTime: Timestamp(i),
|
|
senderTime: Timestamp(i),
|
|
digest: MDigest[256](data: data)) ))
|
|
|
|
return testStoreQueue
|
|
|
|
procSuite "pagination":
|
|
test "Index computation test":
|
|
let
|
|
wm = WakuMessage(payload: @[byte 1, 2, 3], timestamp: 2)
|
|
index = wm.computeIndex()
|
|
check:
|
|
# the fields of the index should be non-empty
|
|
len(index.digest.data) != 0
|
|
len(index.digest.data) == 32 # sha2 output length in bytes
|
|
index.receiverTime != 0 # the receiver timestamp should be a non-zero value
|
|
index.senderTime == 2
|
|
|
|
let
|
|
wm1 = WakuMessage(payload: @[byte 1, 2, 3], contentTopic: ContentTopic("/waku/2/default-content/proto"))
|
|
index1 = wm1.computeIndex()
|
|
wm2 = WakuMessage(payload: @[byte 1, 2, 3], contentTopic: ContentTopic("/waku/2/default-content/proto"))
|
|
index2 = wm2.computeIndex()
|
|
|
|
check:
|
|
# the digests of two identical WakuMessages must be the same
|
|
index1.digest == index2.digest
|
|
|
|
test "Forward pagination test":
|
|
var
|
|
stQ = createSampleStoreQueue(10)
|
|
indexList = toSeq(stQ.fwdIterator()).mapIt(it[0]) # Seq copy of the store queue indices for verification
|
|
msgList = toSeq(stQ.fwdIterator()).mapIt(it[1].msg) # Seq copy of the store queue messages for verification
|
|
pagingInfo = PagingInfo(pageSize: 2, cursor: indexList[3], direction: PagingDirection.FORWARD)
|
|
|
|
# test for a normal pagination
|
|
var (data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 2
|
|
data == msgList[4..5]
|
|
newPagingInfo.cursor == indexList[5]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == pagingInfo.pageSize
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an initial pagination request with an empty cursor
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 2
|
|
data == msgList[0..1]
|
|
newPagingInfo.cursor == indexList[1]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 2
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an initial pagination request with an empty cursor to fetch the entire history
|
|
pagingInfo = PagingInfo(pageSize: 13, direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 10
|
|
data == msgList[0..9]
|
|
newPagingInfo.cursor == indexList[9]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 10
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an empty msgList
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(createSampleStoreQueue(0), pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.pageSize == 0
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for a page size larger than the remaining messages
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[3], direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 6
|
|
data == msgList[4..9]
|
|
newPagingInfo.cursor == indexList[9]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 6
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for a page size larger than the maximum allowed page size
|
|
pagingInfo = PagingInfo(pageSize: MaxPageSize+1, cursor: indexList[3], direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
uint64(data.len) <= MaxPageSize
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize <= MaxPageSize
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for a cursor pointing to the end of the message list
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[9], direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.cursor == indexList[9]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 0
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an invalid cursor
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: computeIndex(WakuMessage(payload: @[byte 10])), direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 0
|
|
error == HistoryResponseError.INVALID_CURSOR
|
|
|
|
# test initial paging query over a message list with one message
|
|
var singleItemMsgList = createSampleStoreQueue(1)
|
|
pagingInfo = PagingInfo(pageSize: 10, direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
|
check:
|
|
data.len == 1
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 1
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test pagination over a message list with one message
|
|
singleItemMsgList = createSampleStoreQueue(1)
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[0], direction: PagingDirection.FORWARD)
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 0
|
|
error == HistoryResponseError.NONE
|
|
|
|
test "Backward pagination test":
|
|
var
|
|
stQ = createSampleStoreQueue(10)
|
|
indexList = toSeq(stQ.fwdIterator()).mapIt(it[0]) # Seq copy of the store queue indices for verification
|
|
msgList = toSeq(stQ.fwdIterator()).mapIt(it[1].msg) # Seq copy of the store queue messages for verification
|
|
pagingInfo = PagingInfo(pageSize: 2, cursor: indexList[3], direction: PagingDirection.BACKWARD)
|
|
|
|
# test for a normal pagination
|
|
var (data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data == msgList[1..2]
|
|
newPagingInfo.cursor == indexList[1]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == pagingInfo.pageSize
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an empty msgList
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(createSampleStoreQueue(0), pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.pageSize == 0
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an initial pagination request with an empty cursor
|
|
pagingInfo = PagingInfo(pageSize: 2, direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 2
|
|
data == msgList[8..9]
|
|
newPagingInfo.cursor == indexList[8]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 2
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an initial pagination request with an empty cursor to fetch the entire history
|
|
pagingInfo = PagingInfo(pageSize: 13, direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 10
|
|
data == msgList[0..9]
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 10
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for a page size larger than the remaining messages
|
|
pagingInfo = PagingInfo(pageSize: 5, cursor: indexList[3], direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data == msgList[0..2]
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 3
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for a page size larger than the Maximum allowed page size
|
|
pagingInfo = PagingInfo(pageSize: MaxPageSize+1, cursor: indexList[3], direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
uint64(data.len) <= MaxPageSize
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize <= MaxPageSize
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for a cursor pointing to the begining of the message list
|
|
pagingInfo = PagingInfo(pageSize: 5, cursor: indexList[0], direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 0
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test for an invalid cursor
|
|
pagingInfo = PagingInfo(pageSize: 5, cursor: computeIndex(WakuMessage(payload: @[byte 10])), direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(stQ, pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.cursor == pagingInfo.cursor
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 0
|
|
error == HistoryResponseError.INVALID_CURSOR
|
|
|
|
# test initial paging query over a message list with one message
|
|
var singleItemMsgList = createSampleStoreQueue(1)
|
|
pagingInfo = PagingInfo(pageSize: 10, direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
|
check:
|
|
data.len == 1
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 1
|
|
error == HistoryResponseError.NONE
|
|
|
|
# test paging query over a message list with one message
|
|
singleItemMsgList = createSampleStoreQueue(1)
|
|
pagingInfo = PagingInfo(pageSize: 10, cursor: indexList[0], direction: PagingDirection.BACKWARD)
|
|
(data, newPagingInfo, error) = getPage(singleItemMsgList, pagingInfo)
|
|
check:
|
|
data.len == 0
|
|
newPagingInfo.cursor == indexList[0]
|
|
newPagingInfo.direction == pagingInfo.direction
|
|
newPagingInfo.pageSize == 0
|
|
error == HistoryResponseError.NONE
|
|
|
|
suite "time-window history query":
|
|
test "Encode/Decode waku message with timestamp":
|
|
# test encoding and decoding of the timestamp field of a WakuMessage
|
|
# Encoding
|
|
let
|
|
version = 0'u32
|
|
payload = @[byte 0, 1, 2]
|
|
timestamp = Timestamp(10)
|
|
msg = WakuMessage(payload: payload, version: version, timestamp: timestamp)
|
|
pb = msg.encode()
|
|
|
|
# Decoding
|
|
let
|
|
msgDecoded = WakuMessage.init(pb.buffer)
|
|
check:
|
|
msgDecoded.isOk()
|
|
|
|
let
|
|
timestampDecoded = msgDecoded.value.timestamp
|
|
check:
|
|
timestampDecoded == timestamp
|
|
|
|
test "Encode/Decode waku message without timestamp":
|
|
# test the encoding and decoding of a WakuMessage with an empty timestamp field
|
|
|
|
# Encoding
|
|
let
|
|
version = 0'u32
|
|
payload = @[byte 0, 1, 2]
|
|
msg = WakuMessage(payload: payload, version: version)
|
|
pb = msg.encode()
|
|
|
|
# Decoding
|
|
let
|
|
msgDecoded = WakuMessage.init(pb.buffer)
|
|
doAssert:
|
|
msgDecoded.isOk()
|
|
|
|
let
|
|
timestampDecoded = msgDecoded.value.timestamp
|
|
check:
|
|
timestampDecoded == Timestamp(0)
|