Migrate registration macros and ethprocs to servertypes

This commit is contained in:
coffeepots 2018-04-12 18:48:46 +01:00 committed by zah
parent 67eb771b4b
commit 2038c4c15b
5 changed files with 123 additions and 116 deletions

View File

@ -1,2 +1,2 @@
import server / [servertypes, rpcconsts, serverdispatch, rpcregistration]
export servertypes, rpcconsts, serverdispatch, rpcregistration
import server / [servertypes, rpcconsts, serverdispatch]
export servertypes, rpcconsts, serverdispatch

View File

@ -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) =

View File

@ -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:
## <proc name>*(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

View File

@ -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()

View File

@ -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:
## <proc name>*(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