From e177d177621a3512b5ce6c74911dd4a0a352aaa2 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Thu, 30 May 2019 21:57:12 +0300 Subject: [PATCH] Further simplifications --- beacon_chain/libp2p_backend.nim | 39 +++++----- beacon_chain/libp2p_spec_backend.nim | 102 +++++++-------------------- 2 files changed, 44 insertions(+), 97 deletions(-) diff --git a/beacon_chain/libp2p_backend.nim b/beacon_chain/libp2p_backend.nim index 96bd3552a..0ce4a4895 100644 --- a/beacon_chain/libp2p_backend.nim +++ b/beacon_chain/libp2p_backend.nim @@ -68,7 +68,7 @@ type peer*: Peer stream*: P2PStream - Response*[MsgType] = distinct UntypedResponse + Responder*[MsgType] = distinct UntypedResponse Bytes = seq[byte] @@ -82,6 +82,7 @@ type const defaultIncomingReqTimeout = 5000 defaultOutgoingReqTimeout = 10000 + HandshakeTimeout = BreachOfProtocol var gProtocols: seq[ProtocolInfo] @@ -272,7 +273,7 @@ template getRecipient(peer: Peer): Peer = template getRecipient(stream: P2PStream): P2PStream = stream -template getRecipient(response: Response): Peer = +template getRecipient(response: Responder): Peer = UntypedResponse(response).peer proc initProtocol(name: string, @@ -329,7 +330,7 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = Format = ident"SSZ" Option = bindSym "Option" UntypedResponse = bindSym "UntypedResponse" - Response = bindSym "Response" + Responder = bindSym "Responder" DaemonAPI = bindSym "DaemonAPI" P2PStream = ident "P2PStream" # XXX: Binding the int type causes instantiation failure for some reason @@ -368,20 +369,21 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = result.registerProtocol = bindSym "registerProtocol" result.setEventHandlers = bindSym "setEventHandlers" result.SerializationFormat = Format - result.ResponseType = Response + result.ResponderType = Responder result.afterProtocolInit = proc (p: P2PProtocol) = p.onPeerConnected.params.add newIdentDefs(ident"handshakeStream", P2PStream) - result.implementMsg = proc (p: P2PProtocol, msg: Message, resp: Message = nil) = + result.implementMsg = proc (msg: Message) = let n = msg.procDef + protocol = msg.protocol msgId = newLit(msg.id) msgIdent = n.name msgName = $msgIdent msgKind = msg.kind msgRecName = msg.recIdent - responseRecord = if resp != nil: resp.recIdent else: nil + ResponseRecord = if msg.response != nil: msg.response.recIdent else: nil userPragmas = n.pragma var @@ -415,14 +417,14 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = extraDefs = quote do: # Jump through some hoops to work aroung # https://github.com/nim-lang/Nim/issues/6248 - let `response` = `Response`[`responseRecord`]( + let `response` = `Responder`[`ResponseRecord`]( `UntypedResponse`(peer: `peer`, stream: `stream`)) # Resolve the Eth2Peer from the LibP2P data received in the thunk userHandlerCall.add peerIdent msg.userHandler.addPreludeDefs extraDefs - p.outRecvProcs.add msg.userHandler + protocol.outRecvProcs.add msg.userHandler elif msgName == "status": #awaitUserHandler = quote do: @@ -455,14 +457,11 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = `awaitUserHandler` `resolveNextMsgFutures`(`peerIdent`, get(`receivedMsg`)) - for p in userPragmas: - thunkProc.addPragma p - - p.outRecvProcs.add thunkProc + protocol.outRecvProcs.add thunkProc var msgSendProc = n let msgSendProcName = n.name - p.outSendProcs.add msgSendProc + protocol.outSendProcs.add msgSendProc # TODO: check that the first param has the correct type msgSendProc.params[1][0] = sendTo @@ -478,9 +477,9 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = # from a certain request. Here we change the Peer parameter at position # 1 to the correct strongly-typed ResponseType. The incoming procs still # gets the normal Peer paramter. - let ResponseType = newTree(nnkBracketExpr, Response, msgRecName) + let ResponseType = newTree(nnkBracketExpr, Responder, msgRecName) msgSendProc.params[1][1] = ResponseType - p.outSendProcs.add quote do: + protocol.outSendProcs.add quote do: template send*(r: `ResponseType`, args: varargs[untyped]): auto = `msgSendProcName`(r, args) else: discard @@ -488,7 +487,7 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = # We change the return type of the sending proc to a Future. # If this is a request proc, the future will return the response record. let rt = if msgKind != msgRequest: Void - else: newTree(nnkBracketExpr, Option, responseRecord) + else: newTree(nnkBracketExpr, Option, ResponseRecord) msgSendProc.params[0] = newTree(nnkBracketExpr, ident("Future"), rt) if msgKind == msgHandshake: @@ -516,7 +515,7 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = return `getAst`(`handshakeImpl`(`msgRecName`, peer, stream, lazySendCall, timeout)) - p.outSendProcs.add handshakeExchanger.def + protocol.outSendProcs.add handshakeExchanger.def msgSendProc.params[1][1] = P2PStream msgSendProc.name = ident rawSendProc @@ -553,7 +552,7 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = if msgKind == msgRequest: let timeout = msg.timeoutParam[0] quote: `makeEth2Request`(`msgRecipient`, `msgProto`, `msgBytes`, - `responseRecord`, `timeout`) + `ResponseRecord`, `timeout`) elif msgId.intVal == 0: quote: `sendBytes`(`sendTo`, `msgBytes`) else: @@ -568,9 +567,9 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = `finalizeRequest` return `sendCall` - p.outProcRegistrations.add( + protocol.outProcRegistrations.add( newCall(registerMsg, - p.protocolInfoVar, + protocol.protocolInfoVar, newLit(msgName), thunkName, msgProto, diff --git a/beacon_chain/libp2p_spec_backend.nim b/beacon_chain/libp2p_spec_backend.nim index 2cb99ce4b..395a52ba4 100644 --- a/beacon_chain/libp2p_spec_backend.nim +++ b/beacon_chain/libp2p_spec_backend.nim @@ -34,7 +34,7 @@ type CompressedMsgId = tuple protocolIndex, msgId: int - ResponseWithId*[MsgType] = object + ResponderWithId*[MsgType] = object peer*: Peer id*: int @@ -411,15 +411,12 @@ proc prepareRequest(peer: Peer, proc implementSendProcBody(sendProc: SendProc) = let msg = sendProc.msg - resultIdent = ident "result" delayedWriteCursor = ident "delayedWriteCursor" proc preludeGenerator(stream: NimNode): NimNode = result = newStmtList() if msg.kind == msgRequest: let - reqId = ident "reqId" - appendPackedObject = bindSym "appendPackedObject" requestMethodId = newLit(msg.id) responseMethodId = newLit(msg.response.id) peer = sendProc.peerParam @@ -428,7 +425,8 @@ proc implementSendProcBody(sendProc: SendProc) = result.add quote do: let `delayedWriteCursor` = `prepareRequest`( - `peer`, `protocol`, `requestMethodId`, `responseMethodId`, `stream`, `timeout`, `resultIdent`) + `peer`, `protocol`, `requestMethodId`, `responseMethodId`, + `stream`, `timeout`, `resultIdent`) proc sendCallGenerator(peer, bytes: NimNode): NimNode = let @@ -452,17 +450,13 @@ proc implementSendProcBody(sendProc: SendProc) = proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = let - resultIdent = ident "result" Option = bindSym "Option" - - # XXX: Binding the int type causes instantiation failure for some reason - # Int = bindSym "int" - Int = ident "int" Peer = bindSym "Peer" EthereumNode = bindSym "EthereumNode" + Format = bindSym "SSZ" Response = bindSym "Response" - ResponseWithId = bindSym "ResponseWithId" + ResponderWithId = bindSym "ResponderWithId" perProtocolMsgId = ident"perProtocolMsgId" mount = bindSym "mount" @@ -474,9 +468,8 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = nextMsg = bindSym "nextMsg" initProtocol = bindSym "initProtocol" registerMsg = bindSym "registerMsg" + handshakeImpl = bindSym "handshakeImpl" - peer = ident "peer" - reqId = ident "reqId" stream = ident "stream" protocol = ident "protocol" response = ident "response" @@ -494,41 +487,17 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = result.PeerType = Peer result.NetworkType = EthereumNode result.SerializationFormat = Format - result.ResponseType = ResponseWithId - result.implementMsg = proc (protocol: P2PProtocol, msg: Message) = + p.useRequestIds = true + result.ResponderType = ResponderWithId + + result.implementMsg = proc (msg: Message) = var msgIdLit = newLit(msg.id) msgRecName = msg.recIdent - msgKind = msg.kind - n = msg.procDef - responseMethodId = if msg.response != nil: msg.response.id else: -1 - responseRecord = if msg.response != nil: msg.response.recIdent else: nil - msgIdent = n.name + msgIdent = msg.ident msgName = $msgIdent - hasReqIds = msgKind in {msgRequest, msgResponse} - userPragmas = n.pragma - - # variables used in the sending procs - msgRecipient = ident"msgRecipient" - rlpWriter = ident"writer" - paramsToWrite = newSeq[NimNode](0) - perPeerMsgIdVar = ident"perPeerMsgId" - - ## - ## Augment user handler - ## - if msg.userHandler != nil: - if msgKind == msgRequest: - msg.userHandler.params.insert(2, newIdentDefs(reqId, Int)) - - let peerParam = msg.userHandler.params[1][0] - let extraDefs = quote do: - let `response` = `ResponseWithId`[`responseRecord`](peer: `peerParam`, id: `reqId`) - - msg.userHandler.addPreludeDefs extraDefs - - protocol.outRecvProcs.add(msg.userHandler) + protocol = msg.protocol ## ## Implemenmt Thunk @@ -538,22 +507,25 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = else: newStmtList() - # variables used in the receiving procs - let callResolvedResponseFuture = if msgKind == msgResponse: - newCall(resolveResponseFuture, peer, msgIdLit, newCall("addr", receivedMsg), reqId) + let callResolvedResponseFuture = if msg.kind == msgResponse: + newCall(resolveResponseFuture, peer, msgIdLit, newCall("addr", receivedMsg), reqIdVar) else: newStmtList() + var userHandlerParams = @[peer] + if msg.kind == msgRequest: + userHandlerParams.add reqIdVar + let - awaitUserHandler = msg.genAwaitUserHandler(receivedMsg, peer, reqId) thunkName = ident(msgName & "_thunk") + awaitUserHandler = msg.genAwaitUserHandler(receivedMsg, userHandlerParams) var thunkProc = quote do: proc `thunkName`(`peer`: `Peer`, `stream`: `P2PStream`, - `reqId`: uint64, + `reqIdVar`: uint64, `msgContents`: `ByteStreamVar`) {.async, gcsafe.} = - var `receivedMsg` = `mount`(`SSZ`, `msgContents`, `msgRecName`) + var `receivedMsg` = `mount`(`Format`, `msgContents`, `msgRecName`) `traceMsg` `awaitUserHandler` `callResolvedResponseFuture` @@ -563,37 +535,13 @@ proc p2pProtocolBackendImpl*(p: P2PProtocol): Backend = ## ## Implement Senders and Handshake ## - var sendProc = createSendProc(msg, isRawSender = (msg.kind == msgHandshake)) + var sendProc = msg.createSendProc(isRawSender = (msg.kind == msgHandshake)) + implementSendProcBody sendProc protocol.outSendProcs.add sendProc.allDefs if msg.kind == msgHandshake: - var - rawSendProc = genSym(nskProc, msgName & "RawSend") - handshakeExchanger = createSendProc(msg, procType = nnkTemplateDef) - - handshakeExchanger.def.params[0] = newTree(nnkBracketExpr, ident("Future"), msgRecName) - - var - forwardCall = newCall(rawSendProc).appendAllParams(handshakeExchanger.def) - peerValue = forwardCall[1] - timeoutValue = msg.timeoutParam[0] - handshakeImpl = ident"handshakeImpl" - - forwardCall[1] = peer - forwardCall.del(forwardCall.len - 1) - - handshakeExchanger.def.body = quote do: - let `peer` = `peerValue` - let sendingFuture = `forwardCall` - `handshakeImpl`(`peer`, - sendingFuture, - `nextMsg`(`peer`, `msgRecName`), - `timeoutValue`) - - sendProc.def.name = rawSendProc - protocol.outSendProcs.add handshakeExchanger.def - else: - implementSendProcBody sendProc + protocol.outSendProcs.add msg.genHandshakeTemplate(sendProc.def.name, + handshakeImpl, nextMsg) protocol.outProcRegistrations.add( newCall(registerMsg,