From 3e7d1cbba6da2004de9f3269c3f78fbeb5e0fcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Thor=C3=A9n?= Date: Mon, 27 Jul 2020 17:01:06 +0800 Subject: [PATCH] Simplify Node API (#77) * Waku v2 Node API: Split into implemented and NYI - Init is now separated into Create and Start node * Simplify Node API * Node API: proc->method and add WakuNode as first argument * Fix indent to make compile * Stub out all API methods --- docs/api/v2/node.md | 141 +++++++++++++++---------------------- waku/node/v2/wakunode2.nim | 86 ++++++++++++++++++++++ 2 files changed, 144 insertions(+), 83 deletions(-) diff --git a/docs/api/v2/node.md b/docs/api/v2/node.md index b4589675d..a3bc686b0 100644 --- a/docs/api/v2/node.md +++ b/docs/api/v2/node.md @@ -2,101 +2,76 @@ ## Nim API -### WakuSub API +The Nim Waku API consist of five methods. Some of them have different arity +depending on what privacy/bandwidth trade-off the consumer wants to make. These +five method are: -This is an internal API to be used by the Waku API. It is practically a small -layer above GossipSub. And possibly a request/response libp2p protocol. +1. **Init** - create and start a node. +2. **Subscribe** - to a topic or a specific content filter. +3. **Unsubscribe** - to a topic or a specific content filter. +4. **Publish** - to a topic, or a topic and a specific content filter. +5. **Query** - for historical messages. ```Nim -# TODO: Some init call to set things up? -method publish*(w: WakuSub, topic: string, data: seq[byte]) {.async.} -method subscribe*(w: WakuSub, topic: string, handler: TopicHandler) {.async.} -method unsubscribe*(w: WakuSub, topics: seq[TopicPair]) {.async.} +proc init*(conf: WakuNodeConf): Future[WakuNode] + ## Creates and starts a Waku node. + ## + ## Status: Partially implemented. + ## TODO Take conf as a parameter and return a started WakuNode -# TODO: Calls for non GossipSub communication. -``` +method subscribe*(w: WakuNode, topic: Topic, handler: TopicHandler) + ## Subscribes to a PubSub topic. Triggers handler when receiving messages on + ## this topic. TopicHandler is a method that takes a topic and a `Message`. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol`, and ensure Message is + ## passed, not `data` field. -### Waku API +method subscribe*(w: WakuNode, contentFilter: ContentFilter, handler: ContentFilterHandler) + ## Subscribes to a ContentFilter. Triggers handler when receiving messages on + ## this content filter. ContentFilter is a method that takes some content + ## filter, specifically with `ContentTopic`, and a `Message`. The `Message` + ## has to match the `ContentTopic`. -This API is very dependend on how the protocol should work for functionality -such as light nodes (no relaying) and nodes that do not want to get messages -from all `WakuTopic`s. + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol` and `subscribe` above, and + ## ensure Message is passed, not `data` field. -See also issue: -https://github.com/vacp2p/specs/issues/156 +method unsubscribe*(w: WakuNode, topic: Topic) + ## Unsubscribe from a topic. + ## + ## Status: Not yet implemented. + ## TODO Implement. -For now it is assumed that we will require a seperate request-response protocol -for this, next to the GossipSub domain. +method unsubscribe*(w: WakuNode, contentFilter: ContentFilter) + ## Unsubscribe from a content filter. + ## + ## Status: Not yet implemented. + ## TODO Implement. -```Nim -type - WakuOptions = object - # If there are more capabilities than just light node, we can create a - # capabilities field. - lightNode: bool - topics: seq[WakuTopic] - bloomfilter: Bloom # TODO: No longer needed with Gossip? - limits: Limits +method publish*(w: WakuNode, topic: Topic, message: Message) + ## Publish a `Message` to a PubSub topic. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol`, and ensure Message is + ## passed, not `data` field. -proc init(w: WakuNode, conf: WakuConfig) -## Initialize the WakuNode. -## -## When not a light node, this will set up the node to be part of the gossipsub -## network with a subscription to the general Waku Topic. -## When a light node, this will connect to full node peer(s) with provided -## `topics` or `bloomfilter` for the full node to filter messages on. +method publish*(w: WakuNode, topic: Topic, contentFilter: ContentFilter, message: Message) + ## Publish a `Message` to a PubSub topic with a specific content filter. + ## Currently this means a `contentTopic`. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol` and `publish`, and ensure + ## Message is passed, not `data` field. Also ensure content filter is in + ## Message. -proc publish(w: WakuNode, topic: WakuTopic, data: seq[byte]): bool -## Publish a message with specified `WakuTopic`. -## -## Both full node and light node can use the GossipSub network to publish. - -proc subscribe(w: WakuNode, topics: seq[WakuTopic], handler: WakuHandler): Identifier -## Subscribe to the provided `topics`, handler will be called on receival of -## messages on those topics. -## -## In case of a full node, this will be through the GossipSub network (see, -## subscription in `init`) -## In case of the light node, this will likely be through a separate request -## response network where the full node filters out the messages. - -proc unsubscribe(id: Identifier): bool -## Unsubscribe handler for topics. - -# Can get rid of the identifiers in subscribe and unsubscribe and track topics + -# handler like in WakuSub, if that is more convenient. - -proc setLightNode(isLightNode: bool) -## Change light node setting. This might trigger change in subscriptions from -## the gossip domain to the request response domain and vice versa. - -proc setTopicInterest(topics: seq[string]) -## Change the topic interests. -# TODO: Only valid if light node? - -proc setBloomFilter(topics: seq[string]) -## Change the topic interests. -# TODO: Still required if we have gossip? +method query*(w: WakuNode, query: HistoryQuery): HistoryResponse + ## Queries for historical messages. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol` and send `RPCMsg`. ``` ## JSON RPC -**TODO: Data should be RPC Messages / bytes** -**TODO: Enable topic handler** - -Call signatures: - -```Nim -proc waku_version(): string -proc waku_info(): WakuInfo -proc waku_publish(topic: string, message: string): bool -proc waku_subscribe(topics: seq[string]): Identifier -proc waku_unsubscribe(id: Identifier): bool - -# TODO: Do we still want to be able to pull for data also? -# E.g. a getTopicsMessages(topics: seq[string])? - -proc waku_setLightNode(isLightNode: bool) -proc waku_setTopicInterest(topics: seq[string]) -proc waku_setBloomFilter(topics: seq[string]) -``` +### TODO To specify diff --git a/waku/node/v2/wakunode2.nim b/waku/node/v2/wakunode2.nim index bc76b421c..8cd1fcddc 100644 --- a/waku/node/v2/wakunode2.nim +++ b/waku/node/v2/wakunode2.nim @@ -223,11 +223,97 @@ proc start*(node: WakuNode, conf: WakuNodeConf) {.async.} = #proc run(conf: WakuNodeConf) {.async, gcsafe.} = +## Public API +## + +# TODO Take conf as a parameter and return a started WakuNode proc init*() {.async.} = let conf = WakuNodeConf.load() let network = await createWakuNode(conf) waitFor network.start(conf) runForever() +# TODO Replace init above +method init2*(conf: WakuNodeConf): Future[WakuNode] {.async.} = + ## Creates and starts a Waku node. + ## + ## Status: Partially implemented. + ## TODO Take conf as a parameter and return a started WakuNode + let node = await createWakuNode(conf) + await node.start(conf) + return node + +type Topic* = string +type Message* = seq[byte] +type ContentFilter* = object + contentTopic*: string +type TopicHandler* = proc(topic: Topic, message: Message) +type ContentFilterHandler* = proc(contentFilter: ContentFilter, message: Message) + +type HistoryQuery = object + xxx*: seq[byte] + +type HistoryResponse = object + xxx*: seq[byte] + +method subscribe*(w: WakuNode, topic: Topic, handler: TopicHandler) = + echo "NYI" + ## Subscribes to a PubSub topic. Triggers handler when receiving messages on + ## this topic. TopicHandler is a method that takes a topic and a `Message`. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol`, and ensure Message is + ## passed, not `data` field. + +method subscribe*(w: WakuNode, contentFilter: ContentFilter, handler: ContentFilterHandler) = + echo "NYI" + ## Subscribes to a ContentFilter. Triggers handler when receiving messages on + ## this content filter. ContentFilter is a method that takes some content + ## filter, specifically with `ContentTopic`, and a `Message`. The `Message` + ## has to match the `ContentTopic`. + + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol` and `subscribe` above, and + ## ensure Message is passed, not `data` field. + +method unsubscribe*(w: WakuNode, topic: Topic) = + echo "NYI" + ## Unsubscribe from a topic. + ## + ## Status: Not yet implemented. + ## TODO Implement. + +method unsubscribe*(w: WakuNode, contentFilter: ContentFilter) = + echo "NYI" + ## Unsubscribe from a content filter. + ## + ## Status: Not yet implemented. + ## TODO Implement. + +method publish*(w: WakuNode, topic: Topic, message: Message) = + echo "NYI" + ## Publish a `Message` to a PubSub topic. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol`, and ensure Message is + ## passed, not `data` field. + +method publish*(w: WakuNode, topic: Topic, contentFilter: ContentFilter, message: Message) = + echo "NYI" + ## Publish a `Message` to a PubSub topic with a specific content filter. + ## Currently this means a `contentTopic`. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol` and `publish`, and ensure + ## Message is passed, not `data` field. Also ensure content filter is in + ## Message. + +method query*(w: WakuNode, query: HistoryQuery): HistoryResponse = + echo "NYI" + ## Queries for historical messages. + ## + ## Status: Not yet implemented. + ## TODO Implement as wrapper around `waku_protocol` and send `RPCMsg`. + when isMainModule: discard init()