From 04e5765a65b1b051242fdecfdbf94722bfaf32cc Mon Sep 17 00:00:00 2001 From: coffeepots Date: Thu, 12 Apr 2018 18:48:46 +0100 Subject: [PATCH] Migrate registration macros and ethprocs to servertypes --- eth-rpc/rpcserver.nim | 4 +- eth-rpc/server/ethprocs.nim | 117 ++++++++++++++--------------- eth-rpc/server/rpcregistration.nim | 45 ----------- eth-rpc/server/serverdispatch.nim | 3 +- eth-rpc/server/servertypes.nim | 70 +++++++++++++++-- 5 files changed, 123 insertions(+), 116 deletions(-) delete mode 100644 eth-rpc/server/rpcregistration.nim diff --git a/eth-rpc/rpcserver.nim b/eth-rpc/rpcserver.nim index 8724e94..ba40b91 100644 --- a/eth-rpc/rpcserver.nim +++ b/eth-rpc/rpcserver.nim @@ -1,2 +1,2 @@ -import server / [servertypes, rpcconsts, serverdispatch, rpcregistration] -export servertypes, rpcconsts, serverdispatch, rpcregistration +import server / [servertypes, rpcconsts, serverdispatch] +export servertypes, rpcconsts, serverdispatch diff --git a/eth-rpc/server/ethprocs.nim b/eth-rpc/server/ethprocs.nim index 629a42e..19a8e5e 100644 --- a/eth-rpc/server/ethprocs.nim +++ b/eth-rpc/server/ethprocs.nim @@ -1,185 +1,184 @@ -import servertypes, json, asyncdispatch, rpcregistration import cryptoutils -proc web3_clientVersion {.rpc.} = +proc web3_clientVersion* {.rpc.} = return %("Nimbus-RPC-Test") -proc web3_sha3 {.rpc.} = +proc web3_sha3* {.rpc.} = var data = params.getStr let kres = k256(data) return %kres -proc net_version {.rpc.} = +proc net_version* {.rpc.} = #[ See: https://github.com/ethereum/interfaces/issues/6 https://github.com/ethereum/EIPs/issues/611 ]# discard -proc net_listening {.rpc.} = +proc net_listening* {.rpc.} = return %"true" -proc net_peerCount {.rpc.} = +proc net_peerCount* {.rpc.} = # TODO: Discovery integration discard -proc eth_protocolVersion {.rpc.} = +proc eth_protocolVersion* {.rpc.} = discard -proc eth_syncing {.rpc.} = +proc eth_syncing* {.rpc.} = discard -proc eth_coinbase {.rpc.} = +proc eth_coinbase* {.rpc.} = discard -proc eth_mining {.rpc.} = +proc eth_mining* {.rpc.} = discard -proc eth_hashrate {.rpc.} = +proc eth_hashrate* {.rpc.} = discard -proc eth_gasPrice {.rpc.} = +proc eth_gasPrice* {.rpc.} = discard -proc eth_accounts {.rpc.} = +proc eth_accounts* {.rpc.} = discard -proc eth_blockNumber {.rpc.} = +proc eth_blockNumber* {.rpc.} = discard -proc eth_getBalance {.rpc.} = +proc eth_getBalance* {.rpc.} = discard -proc eth_getStorageAt {.rpc.} = +proc eth_getStorageAt* {.rpc.} = discard -proc eth_getTransactionCount {.rpc.} = +proc eth_getTransactionCount* {.rpc.} = discard -proc eth_getBlockTransactionCountByHash {.rpc.} = +proc eth_getBlockTransactionCountByHash* {.rpc.} = discard -proc eth_getBlockTransactionCountByNumber {.rpc.} = +proc eth_getBlockTransactionCountByNumber* {.rpc.} = discard -proc eth_getUncleCountByBlockHash {.rpc.} = +proc eth_getUncleCountByBlockHash* {.rpc.} = discard -proc eth_getUncleCountByBlockNumber {.rpc.} = +proc eth_getUncleCountByBlockNumber* {.rpc.} = discard -proc eth_getCode {.rpc.} = +proc eth_getCode* {.rpc.} = discard -proc eth_sign {.rpc.} = +proc eth_sign* {.rpc.} = discard -proc eth_sendTransaction {.rpc.} = +proc eth_sendTransaction* {.rpc.} = discard -proc eth_sendRawTransaction {.rpc.} = +proc eth_sendRawTransaction* {.rpc.} = discard -proc eth_call {.rpc.} = +proc eth_call* {.rpc.} = discard -proc eth_estimateGas {.rpc.} = +proc eth_estimateGas* {.rpc.} = discard -proc eth_getBlockByHash {.rpc.} = +proc eth_getBlockByHash* {.rpc.} = discard -proc eth_getBlockByNumber {.rpc.} = +proc eth_getBlockByNumber* {.rpc.} = discard -proc eth_getTransactionByHash {.rpc.} = +proc eth_getTransactionByHash* {.rpc.} = discard -proc eth_getTransactionByBlockHashAndIndex {.rpc.} = +proc eth_getTransactionByBlockHashAndIndex* {.rpc.} = discard -proc eth_getTransactionByBlockNumberAndIndex {.rpc.} = +proc eth_getTransactionByBlockNumberAndIndex* {.rpc.} = discard -proc eth_getTransactionReceipt {.rpc.} = +proc eth_getTransactionReceipt* {.rpc.} = discard -proc eth_getUncleByBlockHashAndIndex {.rpc.} = +proc eth_getUncleByBlockHashAndIndex* {.rpc.} = discard -proc eth_getUncleByBlockNumberAndIndex {.rpc.} = +proc eth_getUncleByBlockNumberAndIndex* {.rpc.} = discard -proc eth_getCompilers {.rpc.} = +proc eth_getCompilers* {.rpc.} = discard -proc eth_compileLLL {.rpc.} = +proc eth_compileLLL* {.rpc.} = discard -proc eth_compileSolidity {.rpc.} = +proc eth_compileSolidity* {.rpc.} = discard -proc eth_compileSerpent {.rpc.} = +proc eth_compileSerpent* {.rpc.} = discard -proc eth_newFilter {.rpc.} = +proc eth_newFilter* {.rpc.} = discard -proc eth_newBlockFilter {.rpc.} = +proc eth_newBlockFilter* {.rpc.} = discard -proc eth_newPendingTransactionFilter {.rpc.} = +proc eth_newPendingTransactionFilter* {.rpc.} = discard -proc eth_uninstallFilter {.rpc.} = +proc eth_uninstallFilter* {.rpc.} = discard -proc eth_getFilterChanges {.rpc.} = +proc eth_getFilterChanges* {.rpc.} = discard -proc eth_getFilterLogs {.rpc.} = +proc eth_getFilterLogs* {.rpc.} = discard -proc eth_getLogs {.rpc.} = +proc eth_getLogs* {.rpc.} = discard -proc eth_getWork {.rpc.} = +proc eth_getWork* {.rpc.} = discard -proc eth_submitWork {.rpc.} = +proc eth_submitWork* {.rpc.} = discard -proc eth_submitHashrate {.rpc.} = +proc eth_submitHashrate* {.rpc.} = discard -proc shh_post {.rpc.} = +proc shh_post* {.rpc.} = discard -proc shh_version {.rpc.} = +proc shh_version* {.rpc.} = discard -proc shh_newIdentity {.rpc.} = +proc shh_newIdentity* {.rpc.} = discard -proc shh_hasIdentity {.rpc.} = +proc shh_hasIdentity* {.rpc.} = discard -proc shh_newGroup {.rpc.} = +proc shh_newGroup* {.rpc.} = discard -proc shh_addToGroup {.rpc.} = +proc shh_addToGroup* {.rpc.} = discard -proc shh_newFilter {.rpc.} = +proc shh_newFilter* {.rpc.} = discard -proc shh_uninstallFilter {.rpc.} = +proc shh_uninstallFilter* {.rpc.} = discard -proc shh_getFilterChanges {.rpc.} = +proc shh_getFilterChanges* {.rpc.} = discard -proc shh_getMessages {.rpc.} = +proc shh_getMessages* {.rpc.} = discard proc registerEthereumRpcs*(server: RpcServer) = diff --git a/eth-rpc/server/rpcregistration.nim b/eth-rpc/server/rpcregistration.nim deleted file mode 100644 index 1f9fb6e..0000000 --- a/eth-rpc/server/rpcregistration.nim +++ /dev/null @@ -1,45 +0,0 @@ -import macros, servertypes, strutils - -var rpcCallRefs {.compiletime.} = newSeq[(string)]() - -macro rpc*(prc: untyped): untyped = - ## Converts a procedure into the following format: - ## *(params: JsonNode): Future[JsonNode] {.async.} - ## This procedure is then added into a compile-time list - ## so that it is automatically registered for every server that - ## calls registerRpcs(server) - prc.expectKind nnkProcDef - result = prc - let - params = prc.findChild(it.kind == nnkFormalParams) - procName = prc.findChild(it.kind == nnkIdent) - - assert params != nil - procName.expectKind(nnkIdent) - for param in params.children: - if param.kind == nnkIdentDefs: - if param[1] == ident("JsonNode"): - return - var identDefs = newNimNode(nnkIdentDefs) - identDefs.add ident("params"), ident("JsonNode"), newEmptyNode() - # check there isn't already a result type - assert params.len == 1 and params[0].kind == nnkEmpty - params[0] = newNimNode(nnkBracketExpr) - params[0].add ident("Future"), ident("JsonNode") - params.add identDefs - # add async pragma, we can assume there isn't an existing .async. - # as this would fail the result check above. - prc.addPragma(newIdentNode("async")) - - # Adds to compiletime list of rpc calls so we can register them in bulk - # for multiple servers using `registerRpcs`. - rpcCallRefs.add $procName - -macro registerRpcs*(server: RpcServer): untyped = - ## Step through procs currently registered with {.rpc.} and add a register call for server - result = newNimNode(nnkStmtList) - result.add newCall(newDotExpr(ident($server), ident("unRegisterAll"))) - for procName in rpcCallRefs: - let de = newDotExpr(ident($server), ident("register")) - result.add(newCall(de, newStrLitNode(procName), ident(procName))) - echo result.repr diff --git a/eth-rpc/server/serverdispatch.nim b/eth-rpc/server/serverdispatch.nim index 54ce450..692f1f3 100644 --- a/eth-rpc/server/serverdispatch.nim +++ b/eth-rpc/server/serverdispatch.nim @@ -1,5 +1,5 @@ import asyncdispatch, asyncnet, json, tables, strutils, - servertypes, rpcconsts, private / [transportutils, debugutils], jsonutils, asyncutils, ethprocs, + servertypes, rpcconsts, private / [transportutils, debugutils], jsonutils, asyncutils, options proc processMessage(server: RpcServer, client: AsyncSocket, line: string) {.async.} = @@ -43,7 +43,6 @@ proc processClient(server: RpcServer, client: AsyncSocket) {.async.} = await client.sendError(-32000, "Error", %getCurrentExceptionMsg()) proc serve*(server: RpcServer) {.async.} = - server.registerEthereumRpcs server.socket.bindAddr(server.port, server.address) server.socket.listen() diff --git a/eth-rpc/server/servertypes.nim b/eth-rpc/server/servertypes.nim index 61ee711..75c25b9 100644 --- a/eth-rpc/server/servertypes.nim +++ b/eth-rpc/server/servertypes.nim @@ -1,4 +1,4 @@ -import asyncdispatch, asyncnet, json, tables +import asyncdispatch, asyncnet, json, tables, macros, strutils type RpcProc* = proc (params: JsonNode): Future[JsonNode] @@ -13,15 +13,69 @@ type code*: int data*: JsonNode -proc newRpcServer*(address: string, port: Port = Port(8545)): RpcServer = - RpcServer( - socket: newAsyncSocket(), - port: port, - address: address, - procs: newTable[string, RpcProc]() - ) +var rpcCallRefs {.compiletime.} = newSeq[(string)]() proc register*(server: RpcServer, name: string, rpc: RpcProc) = server.procs[name] = rpc proc unRegisterAll*(server: RpcServer) = server.procs.clear + +macro rpc*(prc: untyped): untyped = + ## Converts a procedure into the following format: + ## *(params: JsonNode): Future[JsonNode] {.async.} + ## This procedure is then added into a compile-time list + ## so that it is automatically registered for every server that + ## calls registerRpcs(server) + prc.expectKind nnkProcDef + result = prc + let + params = prc.params + procName = prc.name + + procName.expectKind(nnkIdent) + + # check there isn't already a result type + assert params[0].kind == nnkEmpty + + # add parameter + params.add nnkIdentDefs.newTree( + newIdentNode("params"), + newIdentNode("JsonNode"), + newEmptyNode() + ) + # set result type + params[0] = nnkBracketExpr.newTree( + newIdentNode("Future"), + newIdentNode("JsonNode") + ) + # add async pragma; we can assume there isn't an existing .async. + # as this would mean there's a return type and fail the result check above. + prc.addPragma(newIdentNode("async")) + + # Adds to compiletime list of rpc calls so we can register them in bulk + # for multiple servers using `registerRpcs`. + rpcCallRefs.add $procName + +macro registerRpcs*(server: RpcServer): untyped = + ## Step through procs currently registered with {.rpc.} and add a register call for this server + result = newStmtList() + result.add(quote do: + `server`.unRegisterAll + ) + for procName in rpcCallRefs: + let i = ident(procName) + result.add(quote do: + `server`.register(`procName`, `i`) + ) + +include ethprocs # TODO: This isn't ideal as it means editing code in ethprocs shows errors + +proc newRpcServer*(address: string, port: Port = Port(8545)): RpcServer = + result = RpcServer( + socket: newAsyncSocket(), + port: port, + address: address, + procs: newTable[string, RpcProc]() + ) + result.registerRpcs +