From a492e3c21858a1eff66fc2bb7a130542646eb1d6 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 3 Jun 2019 20:05:45 +0300 Subject: [PATCH] More flexible definitions of Responders --- eth/p2p/p2p_backends_helpers.nim | 5 +++++ eth/p2p/p2p_protocol_dsl.nim | 33 +++++++++++++++++++------------- eth/p2p/rlpx.nim | 10 +++++++++- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/eth/p2p/p2p_backends_helpers.nim b/eth/p2p/p2p_backends_helpers.nim index c731d47..2ffb862 100644 --- a/eth/p2p/p2p_backends_helpers.nim +++ b/eth/p2p/p2p_backends_helpers.nim @@ -23,6 +23,11 @@ template networkState*(connection: Peer, Protocol: type): untyped = proc initProtocolState*[T](state: T, x: Peer|EthereumNode) {.gcsafe.} = discard +proc resolveFuture[MsgType](msg: pointer, future: FutureBase) {.gcsafe.} = + var f = Future[MsgType](future) + doAssert(not f.finished()) + f.complete(cast[ptr MsgType](msg)[]) + proc requestResolver[MsgType](msg: pointer, future: FutureBase) {.gcsafe.} = var f = Future[Option[MsgType]](future) if not f.finished: diff --git a/eth/p2p/p2p_protocol_dsl.nim b/eth/p2p/p2p_protocol_dsl.nim index cca7d09..3c3d2f6 100644 --- a/eth/p2p/p2p_protocol_dsl.nim +++ b/eth/p2p/p2p_protocol_dsl.nim @@ -17,9 +17,10 @@ type timeoutParam*: NimNode recIdent*: NimNode recBody*: NimNode - userHandler*: NimNode protocol*: P2PProtocol response*: Message + userHandler*: NimNode + initResponderCall*: NimNode Request* = ref object queries*: seq[Message] @@ -93,6 +94,7 @@ type # Code generators implementMsg*: proc (msg: Message) implementProtocolInit*: proc (protocol: P2PProtocol): NimNode + afterProtocolInit*: proc (protocol: P2PProtocol) # Bound symbols to the back-end run-time types and procs @@ -213,6 +215,9 @@ proc init*(T: type P2PProtocol, backendFactory: BackendFactory, outProcRegistrations: newStmtList()) result.backend = backendFactory(result) + assert(not result.backend.implementProtocolInit.isNil) + assert(not result.backend.ResponderType.isNil) + result.processProtocolBody body if not result.backend.afterProtocolInit.isNil: @@ -312,6 +317,11 @@ proc ensureTimeoutParam(procDef: NimNode, timeouts: int64): NimNode = proc hasReqId*(msg: Message): bool = msg.protocol.useRequestIds and msg.kind in {msgRequest, msgResponse} +proc ResponderType(msg: Message): NimNode = + var resp = if msg.kind == msgRequest: msg.response else: msg + newTree(nnkBracketExpr, + msg.protocol.backend.ResponderType, resp.recIdent) + proc newMsg(protocol: P2PProtocol, kind: MessageKind, id: int, procDef: NimNode, timeoutParam: NimNode = nil, response: Message = nil): Message = @@ -354,16 +364,16 @@ proc newMsg(protocol: P2PProtocol, kind: MessageKind, id: int, assert response != nil let peerParam = userHandler.params[1][0] - ResponderType = protocol.backend.ResponderType - ResponseRecord = response.recIdent + ResponderType = result.ResponderType + initResponderCall = newCall(ident"init", ResponderType, peerParam) if protocol.useRequestIds: - userHandler.addPreludeDefs quote do: - let `responseVar` = `ResponderType`[`ResponseRecord`](peer: `peerParam`, - reqId: `reqIdVar`) - else: - userHandler.addPreludeDefs quote do: - let `responseVar` = `ResponderType`[`ResponseRecord`](peer: `peerParam`) + initResponderCall.add reqIdVar + + userHandler.addPreludeDefs quote do: + let `responseVar` = `initResponderCall` + + result.initResponderCall = initResponderCall protocol.outRecvProcs.add userHandler result.userHandler = userHandler @@ -418,12 +428,9 @@ proc createSendProc*(msg: Message, # 1 to the correct strongly-typed ResponderType. The incoming procs still # gets the normal Peer paramter. let - ResponderTypeHead = msg.protocol.backend.ResponderType - ResponderType = newTree(nnkBracketExpr, ResponderTypeHead, msg.recIdent) + ResponderType = msg.ResponderType sendProcName = msg.ident - assert ResponderTypeHead != nil - def[3][1][1] = ResponderType # We create a helper that enables the `response.send()` syntax diff --git a/eth/p2p/rlpx.nim b/eth/p2p/rlpx.nim index 742d2e5..e786900 100644 --- a/eth/p2p/rlpx.nim +++ b/eth/p2p/rlpx.nim @@ -45,9 +45,17 @@ var template allProtocols*: auto = {.gcsafe.}: gProtocols template devp2pInfo: auto = {.gcsafe.}: gDevp2pInfo +proc init*[MsgName](T: type ResponderWithId[MsgName], + peer: Peer, reqId: int): T = + T(peer: peer, reqId: reqId) + +proc init*[MsgName](T: type ResponderWithoutId[MsgName], peer: Peer): T = + T(peer) + chronicles.formatIt(Peer): $(it.remote) -proc disconnect*(peer: Peer, reason: DisconnectionReason, notifyOtherPeer = false) {.gcsafe, async.} +proc disconnect*(peer: Peer, reason: DisconnectionReason, + notifyOtherPeer = false) {.gcsafe, async.} template raisePeerDisconnected(msg: string, r: DisconnectionReason) = var e = newException(PeerDisconnected, msg)