diff --git a/docs/tutorial/filter.md b/docs/tutorial/filter.md index 2e339bce9..98f0e6e5c 100644 --- a/docs/tutorial/filter.md +++ b/docs/tutorial/filter.md @@ -26,7 +26,7 @@ Do basic RPC calls: ``` ./build/rpc_subscribe 8545 -./build/rpc_subscribe_filter 8546 # enter your topic default is "foobar" +./build/rpc_subscribe_filter 8546 # enter your content topic; default is "1" ./build/rpc_publish 8545 # enter your message in STDIN ``` diff --git a/docs/tutorial/store.md b/docs/tutorial/store.md index 5951103b2..cf3762814 100644 --- a/docs/tutorial/store.md +++ b/docs/tutorial/store.md @@ -31,7 +31,7 @@ Do basic RPC calls: ./build/rpc_subscribe 8545 ./build/rpc_subscribe 8546 ./build/rpc_publish 8545 # enter your message in STDIN -./build/rpc_query 8546 # enter your topic default is "foobar" +./build/rpc_query 8546 # enter your content topic; default is "1" ``` You should see other node receive something. diff --git a/tests/all_tests_v2.nim b/tests/all_tests_v2.nim index 9af0ea633..083fc7b0c 100644 --- a/tests/all_tests_v2.nim +++ b/tests/all_tests_v2.nim @@ -7,7 +7,6 @@ import ./v2/test_waku_filter, ./v2/test_waku_pagination, ./v2/test_waku_payload, - ./v2/test_rpc_waku, ./v2/test_waku_swap, ./v2/test_message_store, ./v2/test_jsonrpc_waku, diff --git a/tests/v2/test_rpc_waku.nim b/tests/v2/test_rpc_waku.nim deleted file mode 100644 index 9183c8667..000000000 --- a/tests/v2/test_rpc_waku.nim +++ /dev/null @@ -1,50 +0,0 @@ -{.used.} - -import - std/[unittest, options, os, strutils], - stew/shims/net as stewNet, - json_rpc/[rpcserver, rpcclient], - libp2p/crypto/crypto, - ../../waku/v2/node/wakunode2, - ../../waku/v2/node/rpc/wakurpc, - ../../waku/v2/protocol/waku_relay, - ../test_helpers - - -template sourceDir*: string = currentSourcePath.rsplit(DirSep, 1)[0] -const sigPath = sourceDir / ParDir / ParDir / "waku" / "v2" / "node" / "rpc" / "wakucallsigs.nim" -createRpcSigs(RpcHttpClient, sigPath) - -suite "Waku v2 Remote Procedure Calls": - # WakuNode setup - let - rng = crypto.newRng() - privkey = crypto.PrivateKey.random(Secp256k1, rng[]).tryGet() - bindIp = ValidIpAddress.init("0.0.0.0") - extIp = ValidIpAddress.init("127.0.0.1") - port = Port(9000) - node = WakuNode.init(privkey, bindIp, port, some(extIp), some(port)) - - waitFor node.start() - - node.mountRelay(@["waku"]) - - # RPC server setup - let - rpcPort = Port(8545) - ta = initTAddress(bindIp, rpcPort) - server = newRpcHttpServer([ta]) - - setupWakuRPC(node, server) - server.start() - - asyncTest "waku_info": - # RPC client setup - let client = newRpcHttpClient() - await client.connect("127.0.0.1", rpcPort) - - check await(client.waku_version()) == WakuRelayCodec - - server.stop() - server.close() - waitfor node.stop() diff --git a/waku.nimble b/waku.nimble index af06561a6..bbe51fd89 100644 --- a/waku.nimble +++ b/waku.nimble @@ -71,11 +71,11 @@ task test2, "Build & run Waku v2 tests": test "all_tests_v2" task scripts2, "Build Waku v2 scripts": - buildBinary "rpc_publish", "waku/v2/node/rpc/", "-d:chronicles_log_level=DEBUG" - buildBinary "rpc_subscribe", "waku/v2/node/rpc/", "-d:chronicles_log_level=DEBUG" - buildBinary "rpc_subscribe_filter", "waku/v2/node/rpc/", "-d:chronicles_log_level=DEBUG" - buildBinary "rpc_query", "waku/v2/node/rpc/", "-d:chronicles_log_level=DEBUG" - buildBinary "rpc_info", "waku/v2/node/rpc/", "-d:chronicles_log_level=DEBUG" + buildBinary "rpc_publish", "waku/v2/node/scripts/", "-d:chronicles_log_level=DEBUG" + buildBinary "rpc_subscribe", "waku/v2/node/scripts/", "-d:chronicles_log_level=DEBUG" + buildBinary "rpc_subscribe_filter", "waku/v2/node/scripts/", "-d:chronicles_log_level=DEBUG" + buildBinary "rpc_query", "waku/v2/node/scripts/", "-d:chronicles_log_level=DEBUG" + buildBinary "rpc_info", "waku/v2/node/scripts/", "-d:chronicles_log_level=DEBUG" task chat2, "Build example Waku v2 chat usage": let name = "chat2" diff --git a/waku/common/wakubridge.nim b/waku/common/wakubridge.nim index c0af3eb2f..1dc8e9f2a 100644 --- a/waku/common/wakubridge.nim +++ b/waku/common/wakubridge.nim @@ -1,5 +1,5 @@ import - std/strutils, + std/[strutils, tables], chronos, confutils, chronicles, chronicles/topics_registry, metrics, stew/shims/net as stewNet, json_rpc/rpcserver, # Waku v1 imports @@ -8,11 +8,17 @@ import ../v1/protocol/waku_protocol, ./utils/nat, ../v1/node/rpc/wakusim, + ../v1/node/rpc/waku, + ../v1/node/rpc/key_storage, ../v1/node/waku_helpers, # Waku v2 imports libp2p/crypto/crypto, + ../v2/protocol/waku_filter/waku_filter_types, ../v2/node/wakunode2, - ../v2/node/rpc/wakurpc, + ../v2/node/jsonrpc/[debug_api, + filter_api, + relay_api, + store_api], # Common cli config ./config_bridge @@ -98,6 +104,23 @@ proc startWakuV2(config: WakuNodeConf): Future[WakuNode] {.async.} = return node when isMainModule: + proc startV2Rpc(node: WakuNode, rpcServer: RpcHttpServer, conf: WakuNodeConf) = + installDebugApiHandlers(node, rpcServer) + + # Install enabled API handlers: + if conf.relay: + let topicCache = newTable[string, seq[WakuMessage]]() + installRelayApiHandlers(node, rpcServer, topicCache) + + if conf.filter: + let messageCache = newTable[ContentTopic, seq[WakuMessage]]() + installFilterApiHandlers(node, rpcServer, messageCache) + + if conf.store: + installStoreApiHandlers(node, rpcServer) + + rpcServer.start() + let rng = keys.newRng() let conf = WakuNodeConf.load() @@ -114,13 +137,11 @@ when isMainModule: Port(conf.rpcPort + conf.portsShift)) var rpcServer = newRpcHttpServer([ta]) # Waku v1 RPC - # TODO: Commented out the Waku v1 RPC calls as there is a conflict because - # of exact same named rpc calls between v1 and v2 - # let keys = newKeyStorage() - # setupWakuRPC(nodev1, keys, rpcServer, rng) + let keys = newKeyStorage() + setupWakuRPC(nodev1, keys, rpcServer, rng) setupWakuSimRPC(nodev1, rpcServer) # Waku v2 rpc - setupWakuRPC(nodev2, rpcServer) + startV2Rpc(nodev2, rpcServer, conf) rpcServer.start() diff --git a/waku/v2/node/rpc/rpc_info.nim b/waku/v2/node/rpc/rpc_info.nim deleted file mode 100644 index 2e50440ad..000000000 --- a/waku/v2/node/rpc/rpc_info.nim +++ /dev/null @@ -1,19 +0,0 @@ -import - os, strutils, strformat, chronicles, json_rpc/[rpcclient, rpcserver], nimcrypto/sysrand, - libp2p/protobuf/minprotobuf, - libp2p/[peerinfo, multiaddress], - eth/common as eth_common, eth/keys, - system, - options - -from strutils import rsplit -template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] - -const sigWakuPath = sourceDir / "wakucallsigs.nim" -createRpcSigs(RpcHttpClient, sigWakuPath) - -var node = newRpcHttpClient() -waitfor node.connect("localhost", Port(8545)) - -var res = waitfor node.wakuInfo() -echo "Waku info res: ", res diff --git a/waku/v2/node/rpc/wakucallsigs.nim b/waku/v2/node/rpc/wakucallsigs.nim deleted file mode 100644 index 34b75286a..000000000 --- a/waku/v2/node/rpc/wakucallsigs.nim +++ /dev/null @@ -1,41 +0,0 @@ -# Alpha - Currently implemented in v2 -proc waku_version(): string -# TODO Deprecate old waku_publish, requires adjust simulation code etc -proc waku_publish(topic: string, message: seq[byte]): bool -# TODO This should be properly done with rpc types, etc. -proc waku_publish2(topic: string, message: seq[byte]): bool -proc waku_subscribe(topic: string): bool -proc waku_query(topics: seq[string]): bool -proc waku_subscribe_filter(topic: string, contentFilters: seq[seq[string]]): bool -#proc waku_subscribe(topic: string, handler: Topichandler): bool -# -# TODO turn into WakuInfo object -proc waku_info(): string - -# NYI -#proc waku_info(): WakuInfo -#proc waku_setMaxMessageSize(size: uint64): bool -#proc waku_setMinPoW(pow: float): bool -#proc waku_markTrustedPeer(enode: string): bool -# -#proc waku_newKeyPair(): Identifier -#proc waku_addPrivateKey(key: string): Identifier -#proc waku_deleteKeyPair(id: Identifier): bool -#proc waku_hasKeyPair(id: Identifier): bool -#proc waku_getPublicKey(id: Identifier): PublicKey -#proc waku_getPrivateKey(id: Identifier): PrivateKey -# -#proc waku_newSymKey(): Identifier -#proc waku_addSymKey(key: string): Identifier -#proc waku_generateSymKeyFromPassword(password: string): Identifier -#proc waku_hasSymKey(id: Identifier): bool -#proc waku_getSymKey(id: Identifier): SymKey -#proc waku_deleteSymKey(id: Identifier): bool -# -#proc waku_newMessageFilter(options: WakuFilterOptions): Identifier -#proc waku_deleteMessageFilter(id: Identifier): bool -#proc waku_getFilterMessages(id: Identifier): seq[WakuFilterMessage] -##proc waku_post(message: WakuPostMessage): bool -# -#proc wakusim_generateTraffic(amount: int): bool -#proc wakusim_generateRandomTraffic(amount: int): bool diff --git a/waku/v2/node/rpc/wakurpc.nim b/waku/v2/node/rpc/wakurpc.nim deleted file mode 100644 index cb16fb583..000000000 --- a/waku/v2/node/rpc/wakurpc.nim +++ /dev/null @@ -1,99 +0,0 @@ -import - std/options, - json_rpc/rpcserver, - nimcrypto/[sysrand, hmac, sha2], - eth/[common, rlp, keys, p2p], - ../../protocol/waku_relay, - ../../protocol/waku_store/waku_store, - ../../protocol/waku_filter/waku_filter, - ../wakunode2 - -proc setupWakuRPC*(node: WakuNode, rpcsrv: RpcServer) = - - rpcsrv.rpc("waku_version") do() -> string: - ## Returns string of the current Waku protocol version. - result = WakuRelayCodec - - # TODO: Implement symkey etc logic - rpcsrv.rpc("waku_publish") do(topic: string, payload: seq[byte]) -> bool: - let wakuRelay = node.wakuRelay - # XXX also future return type - # TODO: Shouldn't we really be doing WakuNode publish here? - debug "waku_publish", topic=topic, payload=payload - discard wakuRelay.publish(topic, payload) - return true - #if not result: - # raise newException(ValueError, "Message could not be posted") - - rpcsrv.rpc("waku_publish2") do(topic: string, payload: seq[byte]) -> bool: - let msg = WakuMessage.init(payload) - if msg.isOk(): - debug "waku_publish", msg=msg - else: - warn "waku_publish decode error", msg=msg - - debug "waku_publish", topic=topic, payload=payload, msg=msg[] - await node.publish(topic, msg[]) - return true - #if not result: - # raise newException(ValueError, "Message could not be posted") - - # TODO: Handler / Identifier logic - rpcsrv.rpc("waku_subscribe") do(topic: string) -> bool: - debug "waku_subscribe", topic=topic - - # XXX: Hacky in-line handler - proc handler(topic: string, data: seq[byte]) {.async, gcsafe.} = - let msg = WakuMessage.init(data) - if msg.isOk(): - debug "waku_subscribe handler", msg=msg - var readable_str = cast[string](msg[].payload) - info "Hit subscribe handler", topic=topic, msg=msg[], payload=readable_str - else: - warn "waku_subscribe decode error", msg=msg - info "waku_subscribe raw data string", str=cast[string](data) - - node.subscribe(topic, handler) - return true - #if not result: - # raise newException(ValueError, "Message could not be posted") - - rpcsrv.rpc("waku_query") do(topics: seq[int]) -> bool: - debug "waku_query" - - # XXX: Hacky in-line handler - proc handler(response: HistoryResponse) {.gcsafe.} = - info "Hit response handler", messages=response.messages - - var contentTopics = newSeq[ContentTopic]() - for topic in topics: - contentTopics.add(ContentTopic(topic)) - - await node.query(HistoryQuery(topics: contentTopics), handler) - return true - - rpcsrv.rpc("waku_subscribe_filter") do(topic: string, contentFilters: seq[seq[int]]) -> bool: - debug "waku_subscribe_filter" - - # XXX: Hacky in-line handler - proc handler(msg: WakuMessage) {.gcsafe, closure.} = - info "Hit subscribe response", message=msg - - var filters = newSeq[ContentFilter]() - for topics in contentFilters: - var contentTopics = newSeq[ContentTopic]() - for topic in topics: - contentTopics.add(ContentTopic(topic)) - filters.add(ContentFilter(topics: contentTopics)) - - await node.subscribe(FilterRequest(topic: topic, contentFilters: filters, subscribe: true), handler) - return true - - rpcsrv.rpc("waku_info") do() -> string: - debug "waku_node_info" - - let wakuInfo = node.info() - let listenStr = wakuInfo.listenStr - info "Listening on", full = listenStr - - return listenStr diff --git a/waku/v2/node/scripts/rpc_info.nim b/waku/v2/node/scripts/rpc_info.nim new file mode 100644 index 000000000..0f1fdd62c --- /dev/null +++ b/waku/v2/node/scripts/rpc_info.nim @@ -0,0 +1,25 @@ +import + os, strutils, chronicles, json_rpc/[rpcclient, rpcserver], nimcrypto/sysrand, + libp2p/protobuf/minprotobuf, + libp2p/[peerinfo, multiaddress], + eth/common as eth_common, eth/keys, + system, + options, + ../wakunode2, + ../waku_payload, + ../jsonrpc/jsonrpc_types, + ../../protocol/waku_filter/waku_filter_types, + ../../protocol/waku_store/waku_store_types, + ../../../v1/node/rpc/hexstrings + +from strutils import rsplit +template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] + +const sigWakuPath = sourceDir / "../jsonrpc/jsonrpc_callsigs.nim" +createRpcSigs(RpcHttpClient, sigWakuPath) + +var node = newRpcHttpClient() +waitfor node.connect("localhost", Port(8545)) + +var res = waitfor node.get_waku_v2_debug_v1_info() +echo "Waku info res: ", res diff --git a/waku/v2/node/rpc/rpc_publish.nim b/waku/v2/node/scripts/rpc_publish.nim similarity index 63% rename from waku/v2/node/rpc/rpc_publish.nim rename to waku/v2/node/scripts/rpc_publish.nim index bfea46b2c..7edef3055 100644 --- a/waku/v2/node/rpc/rpc_publish.nim +++ b/waku/v2/node/scripts/rpc_publish.nim @@ -4,12 +4,18 @@ import libp2p/protobuf/minprotobuf, eth/common as eth_common, eth/keys, system, - options + options, + ../wakunode2, + ../waku_payload, + ../jsonrpc/jsonrpc_types, + ../../protocol/waku_filter/waku_filter_types, + ../../protocol/waku_store/waku_store_types, + ../../../v1/node/rpc/hexstrings from strutils import rsplit template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] -const sigWakuPath = sourceDir / "wakucallsigs.nim" +const sigWakuPath = sourceDir / "../jsonrpc/jsonrpc_callsigs.nim" createRpcSigs(RpcHttpClient, sigWakuPath) if paramCount() < 1: @@ -28,8 +34,6 @@ waitfor node.connect("localhost", rpcPort) let pubSubTopic = "/waku/2/default-waku/proto" let contentTopic = ContentTopic(1) -var wakuMessage = WakuMessage(payload: input.toBytes(), contentTopic: contentTopic) -# XXX This should be WakuMessage type, but need to setup JSON-RPC mapping for that to work -var raw_bytes = wakuMessage.encode().buffer -var res = waitfor node.wakuPublish2(pubSubTopic, raw_bytes) +let relayMessage = WakuRelayMessage(payload: input.toBytes(), contentTopic: some(contentTopic)) +var res = waitfor node.post_waku_v2_relay_v1_message(pubSubTopic, relayMessage) echo "Waku publish response: ", res diff --git a/waku/v2/node/rpc/rpc_query.nim b/waku/v2/node/scripts/rpc_query.nim similarity index 64% rename from waku/v2/node/rpc/rpc_query.nim rename to waku/v2/node/scripts/rpc_query.nim index eb6c91e83..97fd9e318 100644 --- a/waku/v2/node/rpc/rpc_query.nim +++ b/waku/v2/node/scripts/rpc_query.nim @@ -4,12 +4,18 @@ import libp2p/[peerinfo, multiaddress], eth/common as eth_common, eth/keys, system, - options + options, + ../wakunode2, + ../waku_payload, + ../jsonrpc/jsonrpc_types, + ../../protocol/waku_filter/waku_filter_types, + ../../protocol/waku_store/waku_store_types, + ../../../v1/node/rpc/hexstrings from strutils import rsplit template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] -const sigWakuPath = sourceDir / "wakucallsigs.nim" +const sigWakuPath = sourceDir / "../jsonrpc/jsonrpc_callsigs.nim" createRpcSigs(RpcHttpClient, sigWakuPath) if paramCount() < 1: @@ -26,5 +32,5 @@ echo "Input is:", input var node = newRpcHttpClient() waitfor node.connect("localhost", rpcPort) -var res = waitfor node.wakuQuery(@[input]) +var res = waitfor node.get_waku_v2_store_v1_messages(@[ContentTopic(parseUInt(input))], none(StorePagingOptions)) echo "Waku query response: ", res diff --git a/waku/v2/node/rpc/rpc_subscribe.nim b/waku/v2/node/scripts/rpc_subscribe.nim similarity index 52% rename from waku/v2/node/rpc/rpc_subscribe.nim rename to waku/v2/node/scripts/rpc_subscribe.nim index 45eb0fbda..a5e426fc9 100644 --- a/waku/v2/node/rpc/rpc_subscribe.nim +++ b/waku/v2/node/scripts/rpc_subscribe.nim @@ -1,14 +1,20 @@ import - os, strutils, strformat, chronicles, json_rpc/[rpcclient, rpcserver], nimcrypto/sysrand, + os, strutils, chronicles, json_rpc/[rpcclient, rpcserver], nimcrypto/sysrand, libp2p/protobuf/minprotobuf, eth/common as eth_common, eth/keys, system, - options + options, + ../wakunode2, + ../waku_payload, + ../jsonrpc/jsonrpc_types, + ../../protocol/waku_filter/waku_filter_types, + ../../protocol/waku_store/waku_store_types, + ../../../v1/node/rpc/hexstrings from strutils import rsplit template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] -const sigWakuPath = sourceDir / "wakucallsigs.nim" +const sigWakuPath = sourceDir / "../jsonrpc/jsonrpc_callsigs.nim" createRpcSigs(RpcHttpClient, sigWakuPath) if paramCount() < 1: @@ -23,5 +29,5 @@ waitfor client.connect("localhost", rpcPort) echo "Subscribing" # Subscribe to waku topic -var res = waitFor client.wakuSubscribe("/waku/2/default-waku/proto") +var res = waitFor client.post_waku_v2_relay_v1_subscriptions(@["/waku/2/default-waku/proto"]) echo res diff --git a/waku/v2/node/rpc/rpc_subscribe_filter.nim b/waku/v2/node/scripts/rpc_subscribe_filter.nim similarity index 63% rename from waku/v2/node/rpc/rpc_subscribe_filter.nim rename to waku/v2/node/scripts/rpc_subscribe_filter.nim index 18d8b0ed4..be8e86167 100644 --- a/waku/v2/node/rpc/rpc_subscribe_filter.nim +++ b/waku/v2/node/scripts/rpc_subscribe_filter.nim @@ -4,12 +4,18 @@ import libp2p/[peerinfo, multiaddress], eth/common as eth_common, eth/keys, system, - options + options, + ../wakunode2, + ../waku_payload, + ../jsonrpc/jsonrpc_types, + ../../protocol/waku_filter/waku_filter_types, + ../../protocol/waku_store/waku_store_types, + ../../../v1/node/rpc/hexstrings from strutils import rsplit template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] -const sigWakuPath = sourceDir / "wakucallsigs.nim" +const sigWakuPath = sourceDir / "../jsonrpc/jsonrpc_callsigs.nim" createRpcSigs(RpcHttpClient, sigWakuPath) if paramCount() < 1: @@ -27,6 +33,6 @@ var node = newRpcHttpClient() waitfor node.connect("localhost", rpcPort) let pubSubTopic = "/waku/2/default-waku/proto" -let contentTopic = "foobar" -var res = waitfor node.wakuSubscribeFilter(pubSubTopic, @[@[contentTopic]]) +let contentTopic = ContentTopic(1) +var res = waitfor node.post_waku_v2_filter_v1_subscription(@[ContentFilter(topics: @[contentTopic])], some(pubSubTopic)) echo "Waku query response: ", res