Some version of the findContent JSON-RPC proc (#918)

Also includes fixing instantiation of the history network json-rpc
API handles.
This commit is contained in:
Kim De Mey 2021-12-20 11:57:55 +01:00 committed by GitHub
parent 796787e0e5
commit f4ca598c03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 3 deletions

View File

@ -48,6 +48,10 @@ curl -s -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"1
# Extra parameter is an array of requested logarithmic distances
curl -s -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"1","method":"portal_state_findNodes","params":["enr:<base64 encoding of ENR>", [254, 255, 256]]}' http://localhost:8545 | jq
# FindContent / Content
# A request with an invalid content key will not receive a response
curl -s -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"1","method":"portal_state_findContent","params":["enr:<base64 encoding of ENR>", "02829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"]}' http://localhost:8545 | jq
# Read out the Portal state network routing table contents
curl -s -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"1","method":"portal_state_routingTableInfo","params":[]}' http://localhost:8545 | jq
```

View File

@ -99,7 +99,7 @@ proc run(config: PortalConf) {.raises: [CatchableError, Defect].} =
rpcHttpServerWithProxy.installEthApiHandlers()
rpcHttpServerWithProxy.installDiscoveryApiHandlers(d)
rpcHttpServerWithProxy.installPortalApiHandlers(stateNetwork.portalProtocol, "state")
rpcHttpServerWithProxy.installPortalApiHandlers(stateNetwork.portalProtocol, "history")
rpcHttpServerWithProxy.installPortalApiHandlers(historyNetwork.portalProtocol, "history")
# TODO for now we can only proxy to local node (or remote one without ssl) to make it possible
# to call infura https://github.com/status-im/nim-json-rpc/pull/101 needs to get merged for http client to support https/
waitFor rpcHttpServerWithProxy.start()

View File

@ -24,7 +24,7 @@ logScope:
const
alpha = 3 ## Kademlia concurrency factor
enrsResultLimit = 32 ## Maximum amount of ENRs in the total Nodes messages
enrsResultLimit* = 32 ## Maximum amount of ENRs in the total Nodes messages
## that will be processed
refreshInterval = 5.minutes ## Interval of launching a random query to
## refresh the routing table.
@ -308,7 +308,7 @@ proc offer*(p: PortalProtocol, dst: Node, contentKeys: ContentKeysList):
# id, and initiate an uTP stream with given uTP connection id to get the data
# out.
proc recordsFromBytes(rawRecords: List[ByteList, 32]): PortalResult[seq[Record]] =
proc recordsFromBytes*(rawRecords: List[ByteList, 32]): PortalResult[seq[Record]] =
var records: seq[Record]
for r in rawRecords.asSeq():
var record: Record

View File

@ -10,6 +10,7 @@
import
std/sequtils,
json_rpc/[rpcproxy, rpcserver], stew/byteutils,
eth/p2p/discoveryv5/nodes_verification,
../network/wire/portal_protocol,
./rpc_types
@ -63,6 +64,49 @@ proc installPortalApiHandlers*(
else:
return nodes.get().map(proc(n: Node): Record = n.record)
# TODO: This returns null values for the `none`s. Not sure what it should be
# according to spec, no k:v pair at all?
# Note: Would it not be nice to have a call that resturns either content or
# ENRs, and that the connection id is used in the background instead of this
# "raw" `findContent` call.
rpcServer.rpc("portal_" & network & "_findContent") do(
enr: Record, contentKey: string) -> tuple[
connectionId: Option[string],
content: Option[string],
enrs: Option[seq[Record]]]:
let
node = toNodeWithAddress(enr)
content = await p.findContent(
node, ByteList.init(hexToSeqByte(contentKey)))
if content.isErr():
raise newException(ValueError, $content.error)
else:
let contentMessage = content.get()
case contentMessage.contentMessageType:
of connectionIdType:
return (
some("0x" & contentMessage.connectionId.toHex()),
none(string),
none(seq[Record]))
of contentType:
return (
none(string),
some("0x" & contentMessage.content.asSeq().toHex()),
none(seq[Record]))
of enrsType:
let records = recordsFromBytes(contentMessage.enrs)
if records.isErr():
raise newException(ValueError, $records.error)
else:
return (
none(string),
none(string),
# Note: Could also pass not verified nodes
some(verifyNodesRecords(
records.get(), node, enrsResultLimit).map(
proc(n: Node): Record = n.record)))
rpcServer.rpc("portal_" & network & "_recursiveFindNodes") do() -> seq[Record]:
let discovered = await p.queryRandom()
return discovered.map(proc(n: Node): Record = n.record)