mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-05-14 18:59:39 +00:00
Added content topic polling on FilterAPI (#314)
This commit is contained in:
parent
8a1ca1ff8f
commit
57f69201d6
@ -1,5 +1,5 @@
|
|||||||
import
|
import
|
||||||
std/[unittest, options, sets, tables, os, strutils],
|
std/[unittest, options, sets, tables, os, strutils, sequtils],
|
||||||
stew/shims/net as stewNet,
|
stew/shims/net as stewNet,
|
||||||
json_rpc/[rpcserver, rpcclient],
|
json_rpc/[rpcserver, rpcclient],
|
||||||
libp2p/standard_setup,
|
libp2p/standard_setup,
|
||||||
@ -13,6 +13,7 @@ import
|
|||||||
../../waku/v2/node/wakunode2,
|
../../waku/v2/node/wakunode2,
|
||||||
../../waku/v2/node/jsonrpc/[jsonrpc_types,store_api,relay_api,debug_api,filter_api],
|
../../waku/v2/node/jsonrpc/[jsonrpc_types,store_api,relay_api,debug_api,filter_api],
|
||||||
../../waku/v2/protocol/message_notifier,
|
../../waku/v2/protocol/message_notifier,
|
||||||
|
../../waku/v2/protocol/waku_filter,
|
||||||
../../waku/v2/protocol/waku_store/waku_store,
|
../../waku/v2/protocol/waku_store/waku_store,
|
||||||
../test_helpers
|
../test_helpers
|
||||||
|
|
||||||
@ -281,3 +282,64 @@ procSuite "Waku v2 JSON-RPC API":
|
|||||||
server.stop()
|
server.stop()
|
||||||
server.close()
|
server.close()
|
||||||
waitfor node.stop()
|
waitfor node.stop()
|
||||||
|
|
||||||
|
asyncTest "Filter API: get latest messages":
|
||||||
|
const cTopic = ContentTopic(1)
|
||||||
|
|
||||||
|
waitFor node.start()
|
||||||
|
|
||||||
|
# RPC server setup
|
||||||
|
let
|
||||||
|
rpcPort = Port(8545)
|
||||||
|
ta = initTAddress(bindIp, rpcPort)
|
||||||
|
server = newRpcHttpServer([ta])
|
||||||
|
|
||||||
|
installFilterApiHandlers(node, server)
|
||||||
|
server.start()
|
||||||
|
|
||||||
|
node.mountFilter()
|
||||||
|
|
||||||
|
let client = newRpcHttpClient()
|
||||||
|
await client.connect("127.0.0.1", rpcPort)
|
||||||
|
|
||||||
|
# First ensure subscription exists
|
||||||
|
|
||||||
|
let sub = await client.post_waku_v2_filter_v1_subscription(contentFilters = @[ContentFilter(topics: @[cTopic])], topic = some(defaultTopic))
|
||||||
|
check:
|
||||||
|
sub
|
||||||
|
|
||||||
|
# Now prime the node with some messages before tests
|
||||||
|
var
|
||||||
|
msgList = @[WakuMessage(payload: @[byte 0], contentTopic: ContentTopic(2)),
|
||||||
|
WakuMessage(payload: @[byte 1], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 2], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 3], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 4], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 5], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 6], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 7], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 8], contentTopic: cTopic),
|
||||||
|
WakuMessage(payload: @[byte 9], contentTopic: ContentTopic(2))]
|
||||||
|
|
||||||
|
let
|
||||||
|
filters = node.filters
|
||||||
|
requestId = toSeq(Table(filters).keys)[0]
|
||||||
|
|
||||||
|
for wakuMsg in msgList:
|
||||||
|
filters.notify(wakuMsg, requestId)
|
||||||
|
|
||||||
|
var response = await client.get_waku_v2_filter_v1_messages(cTopic)
|
||||||
|
check:
|
||||||
|
response.len() == 8
|
||||||
|
response.allIt(it.contentTopic == cTopic)
|
||||||
|
|
||||||
|
# No new messages
|
||||||
|
|
||||||
|
response = await client.get_waku_v2_filter_v1_messages(cTopic)
|
||||||
|
|
||||||
|
check:
|
||||||
|
response.len() == 0
|
||||||
|
|
||||||
|
server.stop()
|
||||||
|
server.close()
|
||||||
|
waitfor node.stop()
|
||||||
@ -1,30 +1,58 @@
|
|||||||
{.push raises: [Exception, Defect].}
|
{.push raises: [Exception, Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
|
std/[tables,sequtils],
|
||||||
json_rpc/rpcserver,
|
json_rpc/rpcserver,
|
||||||
eth/[common, rlp, keys, p2p],
|
eth/[common, rlp, keys, p2p],
|
||||||
../../waku_types,
|
../../waku_types,
|
||||||
../wakunode2
|
../wakunode2
|
||||||
|
|
||||||
|
const futTimeout = 5.seconds
|
||||||
|
|
||||||
proc installFilterApiHandlers*(node: WakuNode, rpcsrv: RpcServer) =
|
proc installFilterApiHandlers*(node: WakuNode, rpcsrv: RpcServer) =
|
||||||
const futTimeout = 5.seconds
|
## Create a message cache indexed on content topic
|
||||||
|
## @TODO consider moving message cache elsewhere. Perhaps to node?
|
||||||
|
var
|
||||||
|
messageCache = initTable[ContentTopic, seq[WakuMessage]]()
|
||||||
|
|
||||||
|
proc filterHandler(msg: WakuMessage) {.gcsafe, closure.} =
|
||||||
|
debug "WakuMessage received", msg=msg
|
||||||
|
# Add message to current cache
|
||||||
|
# @TODO limit max content topics and messages
|
||||||
|
messageCache.mgetOrPut(msg.contentTopic, @[]).add(msg)
|
||||||
|
|
||||||
## Filter API version 1 definitions
|
## Filter API version 1 definitions
|
||||||
|
|
||||||
|
rpcsrv.rpc("get_waku_v2_filter_v1_messages") do(contentTopic: ContentTopic) -> seq[WakuMessage]:
|
||||||
|
## Returns all WakuMessages received on a content topic since the
|
||||||
|
## last time this method was called
|
||||||
|
## @TODO ability to specify a return message limit
|
||||||
|
debug "get_waku_v2_filter_v1_messages", contentTopic=contentTopic
|
||||||
|
|
||||||
|
if messageCache.hasKey(contentTopic):
|
||||||
|
let msgs = messageCache[contentTopic]
|
||||||
|
# Clear cache before next call
|
||||||
|
messageCache[contentTopic] = @[]
|
||||||
|
return msgs
|
||||||
|
else:
|
||||||
|
# Not subscribed to this content topic
|
||||||
|
raise newException(ValueError, "Not subscribed to content topic: " & $contentTopic)
|
||||||
|
|
||||||
rpcsrv.rpc("post_waku_v2_filter_v1_subscription") do(contentFilters: seq[ContentFilter], topic: Option[string]) -> bool:
|
rpcsrv.rpc("post_waku_v2_filter_v1_subscription") do(contentFilters: seq[ContentFilter], topic: Option[string]) -> bool:
|
||||||
## Subscribes a node to a list of content filters
|
## Subscribes a node to a list of content filters
|
||||||
debug "post_waku_v2_filter_v1_subscription"
|
debug "post_waku_v2_filter_v1_subscription"
|
||||||
|
|
||||||
proc filterHandler(msg: WakuMessage) {.gcsafe, closure.} =
|
|
||||||
debug "WakuMessage received", msg=msg, topic=topic
|
|
||||||
# @TODO handle message
|
|
||||||
|
|
||||||
# Construct a filter request
|
# Construct a filter request
|
||||||
# @TODO use default PubSub topic if undefined
|
# @TODO use default PubSub topic if undefined
|
||||||
let fReq = if topic.isSome: FilterRequest(topic: topic.get, contentFilters: contentFilters, subscribe: true) else: FilterRequest(contentFilters: contentFilters, subscribe: true)
|
let fReq = if topic.isSome: FilterRequest(topic: topic.get, contentFilters: contentFilters, subscribe: true) else: FilterRequest(contentFilters: contentFilters, subscribe: true)
|
||||||
|
|
||||||
if (await node.subscribe(fReq, filterHandler).withTimeout(futTimeout)):
|
if (await node.subscribe(fReq, filterHandler).withTimeout(futTimeout)):
|
||||||
# Successfully subscribed to all content filters
|
# Successfully subscribed to all content filters
|
||||||
|
|
||||||
|
for cTopic in concat(contentFilters.mapIt(it.topics)):
|
||||||
|
# Create message cache for each subscribed content topic
|
||||||
|
messageCache[cTopic] = @[]
|
||||||
|
|
||||||
return true
|
return true
|
||||||
else:
|
else:
|
||||||
# Failed to subscribe to one or more content filters
|
# Failed to subscribe to one or more content filters
|
||||||
@ -40,6 +68,11 @@ proc installFilterApiHandlers*(node: WakuNode, rpcsrv: RpcServer) =
|
|||||||
|
|
||||||
if (await node.unsubscribe(fReq).withTimeout(futTimeout)):
|
if (await node.unsubscribe(fReq).withTimeout(futTimeout)):
|
||||||
# Successfully unsubscribed from all content filters
|
# Successfully unsubscribed from all content filters
|
||||||
|
|
||||||
|
for cTopic in concat(contentFilters.mapIt(it.topics)):
|
||||||
|
# Remove message cache for each unsubscribed content topic
|
||||||
|
messageCache.del(cTopic)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
else:
|
else:
|
||||||
# Failed to unsubscribe from one or more content filters
|
# Failed to unsubscribe from one or more content filters
|
||||||
|
|||||||
@ -15,5 +15,6 @@ proc get_waku_v2_store_v1_messages(topics: seq[ContentTopic], pagingOptions: Opt
|
|||||||
|
|
||||||
# Filter API
|
# Filter API
|
||||||
|
|
||||||
|
proc get_waku_v2_filter_v1_messages(contentTopic: ContentTopic): seq[WakuMessage]
|
||||||
proc post_waku_v2_filter_v1_subscription(contentFilters: seq[ContentFilter], topic: Option[string]): bool
|
proc post_waku_v2_filter_v1_subscription(contentFilters: seq[ContentFilter], topic: Option[string]): bool
|
||||||
proc delete_waku_v2_filter_v1_subscription(contentFilters: seq[ContentFilter], topic: Option[string]): bool
|
proc delete_waku_v2_filter_v1_subscription(contentFilters: seq[ContentFilter], topic: Option[string]): bool
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user