RPC macro now builds compiletime list for automatic server registration

This commit is contained in:
coffeepots 2018-03-22 17:28:34 +00:00
parent e6ee2a7db7
commit 6dc45a9f9d
2 changed files with 42 additions and 86 deletions

View File

@ -1,43 +1,24 @@
import servertypes, json, asyncdispatch, macros import servertypes, json, asyncdispatch, rpcregistration
import keccak_tiny
macro rpc*(prc: untyped): untyped =
result = prc
let params = prc.findChild(it.kind == nnkFormalParams)
assert params != nil
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()
# proc result
# check there isn't already a result type
assert params.len == 1 and params[0].kind == nnkEmpty
params[0] = ident("JsonNode")
params.add identDefs
# finally, register with server's table.
# this requires a server variable to be passed somehow
#var body = prc.findChild(it.kind == nnkStmtList)
#body.add(quote do:
# server.register "web3_clientVersion", web3_clientVersion
#)
proc web3_clientVersion {.rpc.} = proc web3_clientVersion {.rpc.} =
return %("Nimbus-RPC-Test") return %("Nimbus-RPC-Test")
proc web3_sha3 {.rpc.} = proc web3_sha3 {.rpc.} =
discard let
data = params.getStr
res = $sha3_256(data)
return %res
proc net_version {.rpc.} = proc net_version {.rpc.} =
discard discard
proc net_peerCount {.rpc.} = proc net_peerCount {.rpc.} =
# TODO: Discovery integration
discard discard
proc net_listening {.rpc.} = proc net_listening {.rpc.} =
discard return %"true"
proc eth_protocolVersion {.rpc.} = proc eth_protocolVersion {.rpc.} =
discard discard
@ -201,62 +182,4 @@ proc shh_getMessages {.rpc.} =
proc registerEthereumRpcs*(server: RpcServer) = proc registerEthereumRpcs*(server: RpcServer) =
## Register all ethereum rpc calls to the server ## Register all ethereum rpc calls to the server
# TODO: Automate this # TODO: Automate this
server.register "web3_clientVersion", web3_clientVersion registerRpcs(server)
server.register "web3_sha3", web3_sha3
server.register "net_version", net_version
server.register "net_peerCount", net_peerCount
server.register "net_listening", net_listening
server.register "eth_protocolVersion", eth_protocolVersion
server.register "eth_syncing", eth_syncing
server.register "eth_coinbase", eth_coinbase
server.register "eth_mining", eth_mining
server.register "eth_hashrate", eth_hashrate
server.register "eth_gasPrice", eth_gasPrice
server.register "eth_accounts", eth_accounts
server.register "eth_blockNumber", eth_blockNumber
server.register "eth_getBalance", eth_getBalance
server.register "eth_getStorageAt", eth_getStorageAt
server.register "eth_getTransactionCount", eth_getTransactionCount
server.register "eth_getBlockTransactionCountByHash", eth_getBlockTransactionCountByHash
server.register "eth_getBlockTransactionCountByNumber", eth_getBlockTransactionCountByNumber
server.register "eth_getUncleCountByBlockHash", eth_getUncleCountByBlockHash
server.register "eth_getUncleCountByBlockNumber", eth_getUncleCountByBlockNumber
server.register "eth_getCode", eth_getCode
server.register "eth_sign", eth_sign
server.register "eth_sendTransaction", eth_sendTransaction
server.register "eth_sendRawTransaction", eth_sendRawTransaction
server.register "eth_call", eth_call
server.register "eth_estimateGas", eth_estimateGas
server.register "eth_getBlockByHash", eth_getBlockByHash
server.register "eth_getBlockByNumber", eth_getBlockByNumber
server.register "eth_getTransactionByHash", eth_getTransactionByHash
server.register "eth_getTransactionByBlockHashAndIndex", eth_getTransactionByBlockHashAndIndex
server.register "eth_getTransactionByBlockNumberAndIndex", eth_getTransactionByBlockNumberAndIndex
server.register "eth_getTransactionReceipt", eth_getTransactionReceipt
server.register "eth_getUncleByBlockHashAndIndex", eth_getUncleByBlockHashAndIndex
server.register "eth_getUncleByBlockNumberAndIndex", eth_getUncleByBlockNumberAndIndex
server.register "eth_getCompilers", eth_getCompilers
server.register "eth_compileLLL", eth_compileLLL
server.register "eth_compileSolidity", eth_compileSolidity
server.register "eth_compileSerpent", eth_compileSerpent
server.register "eth_newFilter", eth_newFilter
server.register "eth_newBlockFilter", eth_newBlockFilter
server.register "eth_newPendingTransactionFilter", eth_newPendingTransactionFilter
server.register "eth_uninstallFilter", eth_uninstallFilter
server.register "eth_getFilterChanges", eth_getFilterChanges
server.register "eth_getFilterLogs", eth_getFilterLogs
server.register "eth_getLogs", eth_getLogs
server.register "eth_getWork", eth_getWork
server.register "eth_submitWork", eth_submitWork
server.register "eth_submitHashrate", eth_submitHashrate
server.register "shh_post", shh_post
server.register "shh_version", shh_version
server.register "shh_newIdentity", shh_newIdentity
server.register "shh_hasIdentity", shh_hasIdentity
server.register "shh_newGroup", shh_newGroup
server.register "shh_addToGroup", shh_addToGroup
server.register "shh_newFilter", shh_newFilter
server.register "shh_uninstallFilter", shh_uninstallFilter
server.register "shh_getFilterChanges", shh_getFilterChanges
server.register "shh_getMessages", shh_getMessages

View File

@ -0,0 +1,33 @@
import macros, servertypes
var rpcCallRefs {.compiletime.} = newSeq[(string)]()
macro rpc*(prc: untyped): untyped =
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] = ident("JsonNode")
params.add identDefs
# 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)))