2022-10-05 15:58:24 +00:00
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
2022-10-21 13:01:39 +00:00
|
|
|
std/[options, tables, sets],
|
2022-11-23 09:08:00 +00:00
|
|
|
testutils/unittests,
|
|
|
|
chronos,
|
2022-10-05 15:58:24 +00:00
|
|
|
chronicles,
|
|
|
|
libp2p/crypto/crypto
|
|
|
|
import
|
2023-06-22 09:27:40 +00:00
|
|
|
../../waku/common/databases/db_sqlite,
|
2023-11-22 16:32:56 +00:00
|
|
|
../../waku/waku_archive/driver,
|
|
|
|
../../waku/waku_archive/driver/sqlite_driver/sqlite_driver,
|
2023-08-09 17:11:50 +00:00
|
|
|
../../waku/node/peer_manager,
|
|
|
|
../../waku/waku_core,
|
2023-11-22 16:32:56 +00:00
|
|
|
../../waku/waku_core/message/digest,
|
2024-04-25 13:09:52 +00:00
|
|
|
../../waku/waku_store_legacy,
|
|
|
|
../waku_store_legacy/store_utils,
|
2023-11-27 17:33:27 +00:00
|
|
|
../waku_archive/archive_utils,
|
2022-10-21 13:01:39 +00:00
|
|
|
./testlib/common,
|
|
|
|
./testlib/switch
|
2022-10-05 15:58:24 +00:00
|
|
|
|
|
|
|
procSuite "Waku Store - resume store":
|
|
|
|
## Fixtures
|
|
|
|
let storeA = block:
|
2024-03-15 23:08:47 +00:00
|
|
|
let store = newTestMessageStore()
|
|
|
|
let msgList =
|
|
|
|
@[
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 0], contentTopic = ContentTopic("2"), ts = ts(0)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 1], contentTopic = ContentTopic("1"), ts = ts(1)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 2], contentTopic = ContentTopic("2"), ts = ts(2)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 3], contentTopic = ContentTopic("1"), ts = ts(3)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 4], contentTopic = ContentTopic("2"), ts = ts(4)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 5], contentTopic = ContentTopic("1"), ts = ts(5)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 6], contentTopic = ContentTopic("2"), ts = ts(6)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 7], contentTopic = ContentTopic("1"), ts = ts(7)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 8], contentTopic = ContentTopic("2"), ts = ts(8)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 9], contentTopic = ContentTopic("1"), ts = ts(9)
|
|
|
|
),
|
2022-10-05 15:58:24 +00:00
|
|
|
]
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
for msg in msgList:
|
|
|
|
require store
|
|
|
|
.put(
|
|
|
|
DefaultPubsubTopic,
|
|
|
|
msg,
|
|
|
|
computeDigest(msg),
|
|
|
|
computeMessageHash(DefaultPubsubTopic, msg),
|
|
|
|
msg.timestamp,
|
|
|
|
)
|
|
|
|
.isOk()
|
2022-10-05 15:58:24 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
store
|
2022-10-05 15:58:24 +00:00
|
|
|
|
2022-11-23 09:08:00 +00:00
|
|
|
let storeB = block:
|
2024-03-15 23:08:47 +00:00
|
|
|
let store = newTestMessageStore()
|
|
|
|
let msgList2 =
|
|
|
|
@[
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 0], contentTopic = ContentTopic("2"), ts = ts(0)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 11], contentTopic = ContentTopic("1"), ts = ts(1)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 12], contentTopic = ContentTopic("2"), ts = ts(2)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 3], contentTopic = ContentTopic("1"), ts = ts(3)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 4], contentTopic = ContentTopic("2"), ts = ts(4)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 5], contentTopic = ContentTopic("1"), ts = ts(5)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 13], contentTopic = ContentTopic("2"), ts = ts(6)
|
|
|
|
),
|
|
|
|
fakeWakuMessage(
|
|
|
|
payload = @[byte 14], contentTopic = ContentTopic("1"), ts = ts(7)
|
|
|
|
),
|
2022-10-05 15:58:24 +00:00
|
|
|
]
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
for msg in msgList2:
|
|
|
|
require store
|
|
|
|
.put(
|
|
|
|
DefaultPubsubTopic,
|
|
|
|
msg,
|
|
|
|
computeDigest(msg),
|
|
|
|
computeMessageHash(DefaultPubsubTopic, msg),
|
|
|
|
msg.timestamp,
|
|
|
|
)
|
|
|
|
.isOk()
|
2022-10-05 15:58:24 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
store
|
2022-10-05 15:58:24 +00:00
|
|
|
|
2022-11-23 09:08:00 +00:00
|
|
|
asyncTest "multiple query to multiple peers with pagination":
|
|
|
|
## Setup
|
|
|
|
let
|
|
|
|
serverSwitchA = newTestSwitch()
|
|
|
|
serverSwitchB = newTestSwitch()
|
|
|
|
clientSwitch = newTestSwitch()
|
|
|
|
|
|
|
|
await allFutures(serverSwitchA.start(), serverSwitchB.start(), clientSwitch.start())
|
|
|
|
|
|
|
|
let
|
2024-03-15 23:08:47 +00:00
|
|
|
serverA = await newTestWakuStoreNode(serverSwitchA, store = testStore)
|
|
|
|
serverB = await newTestWakuStoreNode(serverSwitchB, store = testStore)
|
2022-11-23 09:08:00 +00:00
|
|
|
client = newTestWakuStoreClient(clientSwitch)
|
|
|
|
|
|
|
|
## Given
|
2024-03-15 23:08:47 +00:00
|
|
|
let peers =
|
|
|
|
@[
|
|
|
|
serverSwitchA.peerInfo.toRemotePeerInfo(),
|
|
|
|
serverSwitchB.peerInfo.toRemotePeerInfo(),
|
|
|
|
]
|
2022-11-23 09:08:00 +00:00
|
|
|
let req = HistoryQuery(contentTopics: @[DefaultContentTopic], pageSize: 5)
|
|
|
|
|
|
|
|
## When
|
|
|
|
let res = await client.queryLoop(req, peers)
|
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
|
|
|
|
let response = res.tryGet()
|
|
|
|
check:
|
|
|
|
response.len == 10
|
|
|
|
|
|
|
|
## Cleanup
|
|
|
|
await allFutures(clientSwitch.stop(), serverSwitchA.stop(), serverSwitchB.stop())
|
2022-10-05 15:58:24 +00:00
|
|
|
|
|
|
|
asyncTest "resume message history":
|
|
|
|
## Setup
|
2022-11-23 09:08:00 +00:00
|
|
|
let
|
2022-10-05 15:58:24 +00:00
|
|
|
serverSwitch = newTestSwitch()
|
|
|
|
clientSwitch = newTestSwitch()
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
await allFutures(serverSwitch.start(), clientSwitch.start())
|
|
|
|
|
2022-11-23 09:08:00 +00:00
|
|
|
let
|
2024-03-15 23:08:47 +00:00
|
|
|
server = await newTestWakuStore(serverSwitch, store = storeA)
|
2022-10-21 13:01:39 +00:00
|
|
|
client = await newTestWakuStore(clientSwitch)
|
2022-10-05 15:58:24 +00:00
|
|
|
|
|
|
|
client.setPeer(serverSwitch.peerInfo.toRemotePeerInfo())
|
|
|
|
|
|
|
|
## When
|
|
|
|
let res = await client.resume()
|
|
|
|
|
|
|
|
## Then
|
|
|
|
check res.isOk()
|
|
|
|
|
|
|
|
let resumedMessagesCount = res.tryGet()
|
|
|
|
let storedMessagesCount = client.store.getMessagesCount().tryGet()
|
|
|
|
check:
|
|
|
|
resumedMessagesCount == 10
|
|
|
|
storedMessagesCount == 10
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
## Cleanup
|
|
|
|
await allFutures(clientSwitch.stop(), serverSwitch.stop())
|
|
|
|
|
|
|
|
asyncTest "resume history from a list of candidates - offline peer":
|
|
|
|
## Setup
|
2022-11-23 09:08:00 +00:00
|
|
|
let
|
2022-10-05 15:58:24 +00:00
|
|
|
clientSwitch = newTestSwitch()
|
|
|
|
offlineSwitch = newTestSwitch()
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
await clientSwitch.start()
|
|
|
|
|
2022-10-21 13:01:39 +00:00
|
|
|
let client = await newTestWakuStore(clientSwitch)
|
2022-10-05 15:58:24 +00:00
|
|
|
|
|
|
|
## Given
|
|
|
|
let peers = @[offlineSwitch.peerInfo.toRemotePeerInfo()]
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
## When
|
|
|
|
let res = await client.resume(some(peers))
|
|
|
|
|
|
|
|
## Then
|
|
|
|
check res.isErr()
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
## Cleanup
|
|
|
|
await clientSwitch.stop()
|
|
|
|
|
|
|
|
asyncTest "resume history from a list of candidates - online and offline peers":
|
|
|
|
## Setup
|
2022-11-23 09:08:00 +00:00
|
|
|
let
|
2022-10-05 15:58:24 +00:00
|
|
|
offlineSwitch = newTestSwitch()
|
|
|
|
serverASwitch = newTestSwitch()
|
|
|
|
serverBSwitch = newTestSwitch()
|
|
|
|
clientSwitch = newTestSwitch()
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
await allFutures(serverASwitch.start(), serverBSwitch.start(), clientSwitch.start())
|
|
|
|
|
2022-11-23 09:08:00 +00:00
|
|
|
let
|
2024-03-15 23:08:47 +00:00
|
|
|
serverA = await newTestWakuStore(serverASwitch, store = storeA)
|
|
|
|
serverB = await newTestWakuStore(serverBSwitch, store = storeB)
|
2022-10-21 13:01:39 +00:00
|
|
|
client = await newTestWakuStore(clientSwitch)
|
2022-10-05 15:58:24 +00:00
|
|
|
|
|
|
|
## Given
|
2024-03-15 23:08:47 +00:00
|
|
|
let peers =
|
|
|
|
@[
|
|
|
|
offlineSwitch.peerInfo.toRemotePeerInfo(),
|
|
|
|
serverASwitch.peerInfo.toRemotePeerInfo(),
|
|
|
|
serverBSwitch.peerInfo.toRemotePeerInfo(),
|
|
|
|
]
|
2022-10-05 15:58:24 +00:00
|
|
|
|
|
|
|
## When
|
|
|
|
let res = await client.resume(some(peers))
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
## Then
|
|
|
|
# `client` is expected to retrieve 14 messages:
|
|
|
|
# - The store mounted on `serverB` holds 10 messages (see `storeA` fixture)
|
|
|
|
# - The store mounted on `serverB` holds 7 messages (see `storeB` fixture)
|
|
|
|
# Both stores share 3 messages, resulting in 14 unique messages in total
|
|
|
|
check res.isOk()
|
|
|
|
|
|
|
|
let restoredMessagesCount = res.tryGet()
|
|
|
|
let storedMessagesCount = client.store.getMessagesCount().tryGet()
|
|
|
|
check:
|
|
|
|
restoredMessagesCount == 14
|
|
|
|
storedMessagesCount == 14
|
2022-11-23 09:08:00 +00:00
|
|
|
|
2022-10-05 15:58:24 +00:00
|
|
|
## Cleanup
|
|
|
|
await allFutures(serverASwitch.stop(), serverBSwitch.stop(), clientSwitch.stop())
|
|
|
|
|
2022-11-23 09:08:00 +00:00
|
|
|
suite "WakuNode - waku store":
|
|
|
|
asyncTest "Resume proc fetches the history":
|
|
|
|
## Setup
|
|
|
|
let
|
2023-02-13 10:43:49 +00:00
|
|
|
serverKey = generateSecp256k1Key()
|
2023-12-14 06:16:39 +00:00
|
|
|
server = newTestWakuNode(serverKey, parseIpAddress("0.0.0.0"), Port(0))
|
2023-02-13 10:43:49 +00:00
|
|
|
clientKey = generateSecp256k1Key()
|
2023-12-14 06:16:39 +00:00
|
|
|
client = newTestWakuNode(clientKey, parseIpAddress("0.0.0.0"), Port(0))
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
await allFutures(client.start(), server.start())
|
|
|
|
|
2023-11-27 17:33:27 +00:00
|
|
|
let driver = newSqliteArchiveDriver()
|
2022-11-23 09:08:00 +00:00
|
|
|
server.mountArchive(some(driver), none(MessageValidator), none(RetentionPolicy))
|
|
|
|
await server.mountStore()
|
|
|
|
|
|
|
|
let clientStore = StoreQueueRef.new()
|
2024-03-15 23:08:47 +00:00
|
|
|
await client.mountStore(store = clientStore)
|
|
|
|
client.mountStoreClient(store = clientStore)
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
## Given
|
|
|
|
let message = fakeWakuMessage()
|
|
|
|
require server.wakuStore.store.put(DefaultPubsubTopic, message).isOk()
|
|
|
|
|
|
|
|
let serverPeer = server.peerInfo.toRemotePeerInfo()
|
|
|
|
|
|
|
|
## When
|
|
|
|
await client.resume(some(@[serverPeer]))
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
client.wakuStore.store.getMessagesCount().tryGet() == 1
|
|
|
|
|
|
|
|
## Cleanup
|
|
|
|
await allFutures(client.stop(), server.stop())
|
|
|
|
|
|
|
|
asyncTest "Resume proc discards duplicate messages":
|
|
|
|
## Setup
|
|
|
|
let
|
2023-02-13 10:43:49 +00:00
|
|
|
serverKey = generateSecp256k1Key()
|
2023-12-14 06:16:39 +00:00
|
|
|
server = newTestWakuNode(serverKey, parseIpAddress("0.0.0.0"), Port(0))
|
2023-02-13 10:43:49 +00:00
|
|
|
clientKey = generateSecp256k1Key()
|
2023-12-14 06:16:39 +00:00
|
|
|
client = newTestWakuNode(clientKey, parseIpAddress("0.0.0.0"), Port(0))
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
await allFutures(server.start(), client.start())
|
2024-03-15 23:08:47 +00:00
|
|
|
await server.mountStore(store = StoreQueueRef.new())
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
let clientStore = StoreQueueRef.new()
|
2024-03-15 23:08:47 +00:00
|
|
|
await client.mountStore(store = clientStore)
|
|
|
|
client.mountStoreClient(store = clientStore)
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
## Given
|
|
|
|
let timeOrigin = now()
|
|
|
|
let
|
2024-03-15 23:08:47 +00:00
|
|
|
msg1 = fakeWakuMessage(
|
|
|
|
payload = "hello world1", ts = (timeOrigin + getNanoSecondTime(1))
|
|
|
|
)
|
|
|
|
msg2 = fakeWakuMessage(
|
|
|
|
payload = "hello world2", ts = (timeOrigin + getNanoSecondTime(2))
|
|
|
|
)
|
|
|
|
msg3 = fakeWakuMessage(
|
|
|
|
payload = "hello world3", ts = (timeOrigin + getNanoSecondTime(3))
|
|
|
|
)
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
require server.wakuStore.store.put(DefaultPubsubTopic, msg1).isOk()
|
|
|
|
require server.wakuStore.store.put(DefaultPubsubTopic, msg2).isOk()
|
|
|
|
|
|
|
|
# Insert the same message in both node's store
|
|
|
|
let
|
|
|
|
receivedTime3 = now() + getNanosecondTime(10)
|
|
|
|
digest3 = computeDigest(msg3)
|
2024-03-15 23:08:47 +00:00
|
|
|
require server.wakuStore.store
|
|
|
|
.put(DefaultPubsubTopic, msg3, digest3, receivedTime3)
|
|
|
|
.isOk()
|
|
|
|
require client.wakuStore.store
|
|
|
|
.put(DefaultPubsubTopic, msg3, digest3, receivedTime3)
|
|
|
|
.isOk()
|
2022-11-23 09:08:00 +00:00
|
|
|
|
|
|
|
let serverPeer = server.peerInfo.toRemotePeerInfo()
|
|
|
|
|
|
|
|
## When
|
|
|
|
await client.resume(some(@[serverPeer]))
|
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
|
|
|
# If the duplicates are discarded properly, then the total number of messages after resume should be 3
|
|
|
|
client.wakuStore.store.getMessagesCount().tryGet() == 3
|
|
|
|
|
|
|
|
await allFutures(client.stop(), server.stop())
|