Further simplifications
This commit is contained in:
parent
c060c0fc5d
commit
e177d17762
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue