mirror of https://github.com/status-im/nim-eth.git
This reverts commit:5d13052dd9
e1bdf1741a
d238693571
This commit is contained in:
parent
5d13052dd9
commit
10870d8b15
|
@ -93,10 +93,7 @@ type
|
||||||
KfResult*[T] = Result[T, KeyFileError]
|
KfResult*[T] = Result[T, KeyFileError]
|
||||||
|
|
||||||
proc mapErrTo[T, E](r: Result[T, E], v: static KeyFileError): KfResult[T] =
|
proc mapErrTo[T, E](r: Result[T, E], v: static KeyFileError): KfResult[T] =
|
||||||
if r.isOk:
|
r.mapErr(proc (e: E): KeyFileError = v)
|
||||||
ok(r.value)
|
|
||||||
else:
|
|
||||||
err(v)
|
|
||||||
|
|
||||||
const
|
const
|
||||||
SupportedHashes = [
|
SupportedHashes = [
|
||||||
|
|
|
@ -106,7 +106,7 @@ proc newEthereumNode*(
|
||||||
result.protocolVersion = if useCompression: devp2pSnappyVersion
|
result.protocolVersion = if useCompression: devp2pSnappyVersion
|
||||||
else: devp2pVersion
|
else: devp2pVersion
|
||||||
|
|
||||||
result.protocolStates.newSeq protocolCount()
|
result.protocolStates.newSeq allProtocols.len
|
||||||
|
|
||||||
result.peerPool = newPeerPool(
|
result.peerPool = newPeerPool(
|
||||||
result, networkId, keys, nil, clientId, minPeers = minPeers)
|
result, networkId, keys, nil, clientId, minPeers = minPeers)
|
||||||
|
@ -114,8 +114,8 @@ proc newEthereumNode*(
|
||||||
result.peerPool.discovery = result.discovery
|
result.peerPool.discovery = result.discovery
|
||||||
|
|
||||||
if addAllCapabilities:
|
if addAllCapabilities:
|
||||||
for cap in protocols():
|
for p in allProtocols:
|
||||||
result.addCapability(cap)
|
result.addCapability(p)
|
||||||
|
|
||||||
proc processIncoming(server: StreamServer,
|
proc processIncoming(server: StreamServer,
|
||||||
remote: StreamTransport): Future[void] {.async, gcsafe.} =
|
remote: StreamTransport): Future[void] {.async, gcsafe.} =
|
||||||
|
|
|
@ -132,7 +132,6 @@ proc sendNeighbours*(d: DiscoveryProtocol, node: Node, neighbours: seq[Node]) =
|
||||||
const MAX_NEIGHBOURS_PER_PACKET = 12 # TODO: Implement a smarter way to compute it
|
const MAX_NEIGHBOURS_PER_PACKET = 12 # TODO: Implement a smarter way to compute it
|
||||||
type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey]
|
type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey]
|
||||||
var nodes = newSeqOfCap[Neighbour](MAX_NEIGHBOURS_PER_PACKET)
|
var nodes = newSeqOfCap[Neighbour](MAX_NEIGHBOURS_PER_PACKET)
|
||||||
when not defined(nimSeqsV2):
|
|
||||||
shallow(nodes)
|
shallow(nodes)
|
||||||
|
|
||||||
template flush() =
|
template flush() =
|
||||||
|
|
|
@ -211,7 +211,7 @@ proc randomNodes*(d: Protocol, maxAmount: int): seq[Node] =
|
||||||
d.routingTable.randomNodes(maxAmount)
|
d.routingTable.randomNodes(maxAmount)
|
||||||
|
|
||||||
proc randomNodes*(d: Protocol, maxAmount: int,
|
proc randomNodes*(d: Protocol, maxAmount: int,
|
||||||
pred: proc(x: Node): bool {.gcsafe, noSideEffect, raises:[Defect].}): seq[Node] =
|
pred: proc(x: Node): bool {.gcsafe, noSideEffect.}): seq[Node] =
|
||||||
## Get a `maxAmount` of random nodes from the local routing table with the
|
## Get a `maxAmount` of random nodes from the local routing table with the
|
||||||
## `pred` predicate function applied as filter on the nodes selected.
|
## `pred` predicate function applied as filter on the nodes selected.
|
||||||
d.routingTable.randomNodes(maxAmount, pred)
|
d.routingTable.randomNodes(maxAmount, pred)
|
||||||
|
|
|
@ -482,10 +482,10 @@ proc len*(r: RoutingTable): int =
|
||||||
proc moveRight[T](arr: var openArray[T], a, b: int) =
|
proc moveRight[T](arr: var openArray[T], a, b: int) =
|
||||||
## In `arr` move elements in range [a, b] right by 1.
|
## In `arr` move elements in range [a, b] right by 1.
|
||||||
var t: T
|
var t: T
|
||||||
t = system.move(arr[b + 1])
|
shallowCopy(t, arr[b + 1])
|
||||||
for i in countdown(b, a):
|
for i in countdown(b, a):
|
||||||
arr[i + 1] = system.move(arr[i])
|
shallowCopy(arr[i + 1], arr[i])
|
||||||
arr[a] = system.move(t)
|
shallowCopy(arr[a], t)
|
||||||
|
|
||||||
proc setJustSeen*(r: RoutingTable, n: Node) =
|
proc setJustSeen*(r: RoutingTable, n: Node) =
|
||||||
## Move `n` to the head (most recently seen) of its bucket.
|
## Move `n` to the head (most recently seen) of its bucket.
|
||||||
|
@ -512,7 +512,7 @@ proc nodeToRevalidate*(r: RoutingTable): Node =
|
||||||
return b.nodes[^1]
|
return b.nodes[^1]
|
||||||
|
|
||||||
proc randomNodes*(r: RoutingTable, maxAmount: int,
|
proc randomNodes*(r: RoutingTable, maxAmount: int,
|
||||||
pred: proc(x: Node): bool {.gcsafe, noSideEffect, raises:[Defect].} = nil): seq[Node] =
|
pred: proc(x: Node): bool {.gcsafe, noSideEffect.} = nil): seq[Node] =
|
||||||
## Get a `maxAmount` of random nodes from the routing table with the `pred`
|
## Get a `maxAmount` of random nodes from the routing table with the `pred`
|
||||||
## predicate function applied as filter on the nodes selected.
|
## predicate function applied as filter on the nodes selected.
|
||||||
var maxAmount = maxAmount
|
var maxAmount = maxAmount
|
||||||
|
|
|
@ -1,33 +1,9 @@
|
||||||
let protocolManager = ProtocolManager()
|
var
|
||||||
|
gProtocols: seq[ProtocolInfo]
|
||||||
|
|
||||||
# The variables above are immutable RTTI information. We need to tell
|
# The variables above are immutable RTTI information. We need to tell
|
||||||
# Nim to not consider them GcSafe violations:
|
# Nim to not consider them GcSafe violations:
|
||||||
|
template allProtocols*: auto = {.gcsafe.}: gProtocols
|
||||||
proc registerProtocol*(proto: ProtocolInfo) {.gcsafe.} =
|
|
||||||
{.gcsafe.}:
|
|
||||||
proto.index = protocolManager.protocols.len
|
|
||||||
if proto.name == "p2p":
|
|
||||||
doAssert(proto.index == 0)
|
|
||||||
protocolManager.protocols.add proto
|
|
||||||
|
|
||||||
proc protocolCount*(): int {.gcsafe.} =
|
|
||||||
{.gcsafe.}:
|
|
||||||
protocolManager.protocols.len
|
|
||||||
|
|
||||||
proc getProtocol*(index: int): ProtocolInfo {.gcsafe.} =
|
|
||||||
{.gcsafe.}:
|
|
||||||
protocolManager.protocols[index]
|
|
||||||
|
|
||||||
iterator protocols*(): ProtocolInfo {.gcsafe.} =
|
|
||||||
{.gcsafe.}:
|
|
||||||
for x in protocolManager.protocols:
|
|
||||||
yield x
|
|
||||||
|
|
||||||
template getProtocol*(Protocol: type): ProtocolInfo =
|
|
||||||
getProtocol(Protocol.index)
|
|
||||||
|
|
||||||
template devp2pInfo*(): ProtocolInfo =
|
|
||||||
getProtocol(0)
|
|
||||||
|
|
||||||
proc getState*(peer: Peer, proto: ProtocolInfo): RootRef =
|
proc getState*(peer: Peer, proto: ProtocolInfo): RootRef =
|
||||||
peer.protocolStates[proto.index]
|
peer.protocolStates[proto.index]
|
||||||
|
@ -59,8 +35,9 @@ proc initProtocolState*[T](state: T, x: Peer|EthereumNode)
|
||||||
proc initProtocolStates(peer: Peer, protocols: openArray[ProtocolInfo])
|
proc initProtocolStates(peer: Peer, protocols: openArray[ProtocolInfo])
|
||||||
{.raises: [Defect].} =
|
{.raises: [Defect].} =
|
||||||
# Initialize all the active protocol states
|
# Initialize all the active protocol states
|
||||||
newSeq(peer.protocolStates, protocolCount())
|
newSeq(peer.protocolStates, allProtocols.len)
|
||||||
for protocol in protocols:
|
for protocol in protocols:
|
||||||
let peerStateInit = protocol.peerStateInitializer
|
let peerStateInit = protocol.peerStateInitializer
|
||||||
if peerStateInit != nil:
|
if peerStateInit != nil:
|
||||||
peer.protocolStates[protocol.index] = peerStateInit(peer)
|
peer.protocolStates[protocol.index] = peerStateInit(peer)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[options, sequtils, macrocache],
|
std/[options, sequtils],
|
||||||
stew/shims/macros, chronos, faststreams/outputs
|
stew/shims/macros, chronos, faststreams/outputs
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -76,7 +76,7 @@ type
|
||||||
|
|
||||||
# Cached properties
|
# Cached properties
|
||||||
nameIdent*: NimNode
|
nameIdent*: NimNode
|
||||||
protocolInfo*: NimNode
|
protocolInfoVar*: NimNode
|
||||||
|
|
||||||
# All messages
|
# All messages
|
||||||
messages*: seq[Message]
|
messages*: seq[Message]
|
||||||
|
@ -146,9 +146,6 @@ let
|
||||||
PROTO {.compileTime.} = ident "PROTO"
|
PROTO {.compileTime.} = ident "PROTO"
|
||||||
MSG {.compileTime.} = ident "MSG"
|
MSG {.compileTime.} = ident "MSG"
|
||||||
|
|
||||||
const
|
|
||||||
protocolCounter = CacheCounter"protocolCounter"
|
|
||||||
|
|
||||||
template Opt(T): auto = newTree(nnkBracketExpr, Option, T)
|
template Opt(T): auto = newTree(nnkBracketExpr, Option, T)
|
||||||
template Fut(T): auto = newTree(nnkBracketExpr, Future, T)
|
template Fut(T): auto = newTree(nnkBracketExpr, Future, T)
|
||||||
|
|
||||||
|
@ -314,7 +311,7 @@ proc init*(T: type P2PProtocol, backendFactory: BackendFactory,
|
||||||
PeerStateType: verifyStateType peerState,
|
PeerStateType: verifyStateType peerState,
|
||||||
NetworkStateType: verifyStateType networkState,
|
NetworkStateType: verifyStateType networkState,
|
||||||
nameIdent: ident(name),
|
nameIdent: ident(name),
|
||||||
protocolInfo: newCall(ident("protocolInfo"), ident(name)),
|
protocolInfoVar: ident(name & "Protocol"),
|
||||||
outSendProcs: newStmtList(),
|
outSendProcs: newStmtList(),
|
||||||
outRecvProcs: newStmtList(),
|
outRecvProcs: newStmtList(),
|
||||||
outProcRegistrations: newStmtList())
|
outProcRegistrations: newStmtList())
|
||||||
|
@ -346,7 +343,7 @@ proc augmentUserHandler(p: P2PProtocol, userHandlerProc: NimNode, msgId = -1) =
|
||||||
var
|
var
|
||||||
getState = ident"getState"
|
getState = ident"getState"
|
||||||
getNetworkState = ident"getNetworkState"
|
getNetworkState = ident"getNetworkState"
|
||||||
protocolInfo = p.protocolInfo
|
protocolInfoVar = p.protocolInfoVar
|
||||||
protocolNameIdent = p.nameIdent
|
protocolNameIdent = p.nameIdent
|
||||||
PeerType = p.backend.PeerType
|
PeerType = p.backend.PeerType
|
||||||
PeerStateType = p.PeerStateType
|
PeerStateType = p.PeerStateType
|
||||||
|
@ -373,12 +370,12 @@ proc augmentUserHandler(p: P2PProtocol, userHandlerProc: NimNode, msgId = -1) =
|
||||||
if PeerStateType != nil:
|
if PeerStateType != nil:
|
||||||
prelude.add quote do:
|
prelude.add quote do:
|
||||||
template state(`peerVar`: `PeerType`): `PeerStateType` =
|
template state(`peerVar`: `PeerType`): `PeerStateType` =
|
||||||
`PeerStateType`(`getState`(`peerVar`, `protocolInfo`))
|
cast[`PeerStateType`](`getState`(`peerVar`, `protocolInfoVar`))
|
||||||
|
|
||||||
if NetworkStateType != nil:
|
if NetworkStateType != nil:
|
||||||
prelude.add quote do:
|
prelude.add quote do:
|
||||||
template networkState(`peerVar`: `PeerType`): `NetworkStateType` =
|
template networkState(`peerVar`: `PeerType`): `NetworkStateType` =
|
||||||
`NetworkStateType`(`getNetworkState`(`peerVar`.network, `protocolInfo`))
|
cast[`NetworkStateType`](`getNetworkState`(`peerVar`.network, `protocolInfoVar`))
|
||||||
|
|
||||||
proc addPreludeDefs*(userHandlerProc: NimNode, definitions: NimNode) =
|
proc addPreludeDefs*(userHandlerProc: NimNode, definitions: NimNode) =
|
||||||
userHandlerProc.body[0].add definitions
|
userHandlerProc.body[0].add definitions
|
||||||
|
@ -702,7 +699,7 @@ proc useStandardBody*(sendProc: SendProc,
|
||||||
newStmtList()
|
newStmtList()
|
||||||
else:
|
else:
|
||||||
logSentMsgFields(recipient,
|
logSentMsgFields(recipient,
|
||||||
msg.protocol.protocolInfo,
|
msg.protocol.protocolInfoVar,
|
||||||
$msg.ident,
|
$msg.ident,
|
||||||
sendProc.msgParams)
|
sendProc.msgParams)
|
||||||
|
|
||||||
|
@ -898,24 +895,16 @@ proc processProtocolBody*(p: P2PProtocol, protocolBody: NimNode) =
|
||||||
|
|
||||||
proc genTypeSection*(p: P2PProtocol): NimNode =
|
proc genTypeSection*(p: P2PProtocol): NimNode =
|
||||||
var
|
var
|
||||||
protocolIdx = protocolCounter.value
|
|
||||||
protocolName = p.nameIdent
|
protocolName = p.nameIdent
|
||||||
peerState = p.PeerStateType
|
peerState = p.PeerStateType
|
||||||
networkState= p.NetworkStateType
|
networkState= p.NetworkStateType
|
||||||
|
|
||||||
protocolCounter.inc
|
|
||||||
result = newStmtList()
|
result = newStmtList()
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
# Create a type acting as a pseudo-object representing the protocol
|
# Create a type acting as a pseudo-object representing the protocol
|
||||||
# (e.g. p2p)
|
# (e.g. p2p)
|
||||||
type `protocolName`* = object
|
type `protocolName`* = object
|
||||||
|
|
||||||
# The protocol run-time index is available as a pseudo-field
|
|
||||||
# (e.g. `p2p.index`)
|
|
||||||
template index*(`PROTO`: type `protocolName`): auto = `protocolIdx`
|
|
||||||
template protocolInfo*(`PROTO`: type `protocolName`): auto =
|
|
||||||
getProtocol(`protocolIdx`)
|
|
||||||
|
|
||||||
if peerState != nil:
|
if peerState != nil:
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
template State*(`PROTO`: type `protocolName`): type = `peerState`
|
template State*(`PROTO`: type `protocolName`): type = `peerState`
|
||||||
|
@ -960,29 +949,33 @@ proc genCode*(p: P2PProtocol): NimNode =
|
||||||
result.add p.genTypeSection()
|
result.add p.genTypeSection()
|
||||||
|
|
||||||
let
|
let
|
||||||
|
protocolInfoVar = p.protocolInfoVar
|
||||||
|
protocolInfoVarObj = ident($protocolInfoVar & "Obj")
|
||||||
|
protocolName = p.nameIdent
|
||||||
protocolInit = p.backend.implementProtocolInit(p)
|
protocolInit = p.backend.implementProtocolInit(p)
|
||||||
protocolReg = ident($p.nameIdent & "Registration")
|
|
||||||
regBody = newStmtList()
|
result.add quote do:
|
||||||
|
# One global variable per protocol holds the protocol run-time data
|
||||||
|
var `protocolInfoVarObj` = `protocolInit`
|
||||||
|
var `protocolInfoVar` = addr `protocolInfoVarObj`
|
||||||
|
|
||||||
|
# The protocol run-time data is available as a pseudo-field
|
||||||
|
# (e.g. `p2p.protocolInfo`)
|
||||||
|
template protocolInfo*(`PROTO`: type `protocolName`): auto = `protocolInfoVar`
|
||||||
|
|
||||||
result.add p.outSendProcs,
|
result.add p.outSendProcs,
|
||||||
p.outRecvProcs
|
p.outRecvProcs,
|
||||||
|
p.outProcRegistrations
|
||||||
|
|
||||||
if p.onPeerConnected != nil: result.add p.onPeerConnected
|
if p.onPeerConnected != nil: result.add p.onPeerConnected
|
||||||
if p.onPeerDisconnected != nil: result.add p.onPeerDisconnected
|
if p.onPeerDisconnected != nil: result.add p.onPeerDisconnected
|
||||||
|
|
||||||
regBody.add newCall(p.backend.setEventHandlers,
|
result.add newCall(p.backend.setEventHandlers,
|
||||||
protocolVar,
|
protocolInfoVar,
|
||||||
nameOrNil p.onPeerConnected,
|
nameOrNil p.onPeerConnected,
|
||||||
nameOrNil p.onPeerDisconnected)
|
nameOrNil p.onPeerDisconnected)
|
||||||
|
|
||||||
regBody.add p.outProcRegistrations
|
result.add newCall(p.backend.registerProtocol, protocolInfoVar)
|
||||||
regBody.add newCall(p.backend.registerProtocol, protocolVar)
|
|
||||||
|
|
||||||
result.add quote do:
|
|
||||||
proc `protocolReg`() {.raises: [RlpError, Defect].} =
|
|
||||||
let `protocolVar` = `protocolInit`
|
|
||||||
`regBody`
|
|
||||||
`protocolReg`()
|
|
||||||
|
|
||||||
macro emitForSingleBackend(
|
macro emitForSingleBackend(
|
||||||
name: static[string],
|
name: static[string],
|
||||||
|
|
|
@ -93,10 +93,7 @@ type
|
||||||
## Quasy-private types. Use at your own risk.
|
## Quasy-private types. Use at your own risk.
|
||||||
##
|
##
|
||||||
|
|
||||||
ProtocolManager* = ref object
|
ProtocolInfoObj* = object
|
||||||
protocols*: seq[ProtocolInfo]
|
|
||||||
|
|
||||||
ProtocolInfo* = ref object
|
|
||||||
name*: string
|
name*: string
|
||||||
version*: int
|
version*: int
|
||||||
messages*: seq[MessageInfo]
|
messages*: seq[MessageInfo]
|
||||||
|
@ -109,7 +106,9 @@ type
|
||||||
handshake*: HandshakeStep
|
handshake*: HandshakeStep
|
||||||
disconnectHandler*: DisconnectionHandler
|
disconnectHandler*: DisconnectionHandler
|
||||||
|
|
||||||
MessageInfo* = ref object
|
ProtocolInfo* = ptr ProtocolInfoObj
|
||||||
|
|
||||||
|
MessageInfo* = object
|
||||||
id*: int
|
id*: int
|
||||||
name*: string
|
name*: string
|
||||||
|
|
||||||
|
@ -133,7 +132,7 @@ type
|
||||||
# `messages` holds a mapping from valid message IDs to their handler procs.
|
# `messages` holds a mapping from valid message IDs to their handler procs.
|
||||||
#
|
#
|
||||||
protocolOffsets*: seq[int]
|
protocolOffsets*: seq[int]
|
||||||
messages*: seq[MessageInfo]
|
messages*: seq[ptr MessageInfo]
|
||||||
activeProtocols*: seq[ProtocolInfo]
|
activeProtocols*: seq[ProtocolInfo]
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -192,6 +192,9 @@ proc handshakeImpl[T](peer: Peer,
|
||||||
else:
|
else:
|
||||||
return responseFut.read
|
return responseFut.read
|
||||||
|
|
||||||
|
var gDevp2pInfo: ProtocolInfo
|
||||||
|
template devp2pInfo: auto = {.gcsafe.}: gDevp2pInfo
|
||||||
|
|
||||||
# Dispatcher
|
# Dispatcher
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -217,7 +220,7 @@ proc getDispatcher(node: EthereumNode,
|
||||||
# We should be able to find an existing dispatcher without allocating a new one
|
# We should be able to find an existing dispatcher without allocating a new one
|
||||||
|
|
||||||
new result
|
new result
|
||||||
newSeq(result.protocolOffsets, protocolCount())
|
newSeq(result.protocolOffsets, allProtocols.len)
|
||||||
result.protocolOffsets.fill -1
|
result.protocolOffsets.fill -1
|
||||||
|
|
||||||
var nextUserMsgId = 0x10
|
var nextUserMsgId = 0x10
|
||||||
|
@ -234,9 +237,9 @@ proc getDispatcher(node: EthereumNode,
|
||||||
|
|
||||||
template copyTo(src, dest; index: int) =
|
template copyTo(src, dest; index: int) =
|
||||||
for i in 0 ..< src.len:
|
for i in 0 ..< src.len:
|
||||||
dest[index + i] = src[i]
|
dest[index + i] = addr src[i]
|
||||||
|
|
||||||
result.messages = newSeq[MessageInfo](nextUserMsgId)
|
result.messages = newSeq[ptr MessageInfo](nextUserMsgId)
|
||||||
devp2pInfo.messages.copyTo(result.messages, 0)
|
devp2pInfo.messages.copyTo(result.messages, 0)
|
||||||
|
|
||||||
for localProtocol in node.protocols:
|
for localProtocol in node.protocols:
|
||||||
|
@ -259,35 +262,30 @@ proc getMsgName*(peer: Peer, msgId: int): string =
|
||||||
of 3: "pong"
|
of 3: "pong"
|
||||||
else: $msgId
|
else: $msgId
|
||||||
|
|
||||||
proc getMsgMetadata*(peer: Peer, msgId: int): (ProtocolInfo, MessageInfo) =
|
proc getMsgMetadata*(peer: Peer, msgId: int): (ProtocolInfo, ptr MessageInfo) =
|
||||||
doAssert msgId >= 0
|
doAssert msgId >= 0
|
||||||
|
|
||||||
let dpInfo = devp2pInfo()
|
if msgId <= devp2pInfo.messages[^1].id:
|
||||||
if msgId <= dpInfo.messages[^1].id:
|
return (devp2pInfo, addr devp2pInfo.messages[msgId])
|
||||||
return (dpInfo, dpInfo.messages[msgId])
|
|
||||||
|
|
||||||
if msgId < peer.dispatcher.messages.len:
|
if msgId < peer.dispatcher.messages.len:
|
||||||
let numProtocol = protocolCount()
|
for i in 0 ..< allProtocols.len:
|
||||||
for i in 0 ..< numProtocol:
|
|
||||||
let protocol = getProtocol(i)
|
|
||||||
let offset = peer.dispatcher.protocolOffsets[i]
|
let offset = peer.dispatcher.protocolOffsets[i]
|
||||||
if offset != -1 and
|
if offset != -1 and
|
||||||
offset + protocol.messages[^1].id >= msgId:
|
offset + allProtocols[i].messages[^1].id >= msgId:
|
||||||
return (protocol, peer.dispatcher.messages[msgId])
|
return (allProtocols[i], peer.dispatcher.messages[msgId])
|
||||||
|
|
||||||
# Protocol info objects
|
# Protocol info objects
|
||||||
#
|
#
|
||||||
|
|
||||||
proc initProtocol(name: string, version: int,
|
proc initProtocol(name: string, version: int,
|
||||||
peerInit: PeerStateInitializer,
|
peerInit: PeerStateInitializer,
|
||||||
networkInit: NetworkStateInitializer): ProtocolInfo =
|
networkInit: NetworkStateInitializer): ProtocolInfoObj =
|
||||||
ProtocolInfo(
|
result.name = name
|
||||||
name : name,
|
result.version = version
|
||||||
version : version,
|
result.messages = @[]
|
||||||
messages: @[],
|
result.peerStateInitializer = peerInit
|
||||||
peerStateInitializer: peerInit,
|
result.networkStateInitializer = networkInit
|
||||||
networkStateInitializer: networkInit
|
|
||||||
)
|
|
||||||
|
|
||||||
proc setEventHandlers(p: ProtocolInfo,
|
proc setEventHandlers(p: ProtocolInfo,
|
||||||
handshake: HandshakeStep,
|
handshake: HandshakeStep,
|
||||||
|
@ -323,6 +321,16 @@ proc registerMsg(protocol: ProtocolInfo,
|
||||||
requestResolver: requestResolver,
|
requestResolver: requestResolver,
|
||||||
nextMsgResolver: nextMsgResolver)
|
nextMsgResolver: nextMsgResolver)
|
||||||
|
|
||||||
|
proc registerProtocol(protocol: ProtocolInfo) =
|
||||||
|
# TODO: This can be done at compile-time in the future
|
||||||
|
if protocol.name != "p2p":
|
||||||
|
let pos = lowerBound(gProtocols, protocol)
|
||||||
|
gProtocols.insert(protocol, pos)
|
||||||
|
for i in 0 ..< gProtocols.len:
|
||||||
|
gProtocols[i].index = i
|
||||||
|
else:
|
||||||
|
gDevp2pInfo = protocol
|
||||||
|
|
||||||
# Message composition and encryption
|
# Message composition and encryption
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -965,7 +973,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
quote: return `sendCall`
|
quote: return `sendCall`
|
||||||
|
|
||||||
let perPeerMsgIdValue = if isSubprotocol:
|
let perPeerMsgIdValue = if isSubprotocol:
|
||||||
newCall(perPeerMsgIdImpl, peerVar, protocol.protocolInfo, newLit(msgId))
|
newCall(perPeerMsgIdImpl, peerVar, protocol.protocolInfoVar, newLit(msgId))
|
||||||
else:
|
else:
|
||||||
newLit(msgId)
|
newLit(msgId)
|
||||||
|
|
||||||
|
@ -1001,7 +1009,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
|
|
||||||
protocol.outProcRegistrations.add(
|
protocol.outProcRegistrations.add(
|
||||||
newCall(registerMsg,
|
newCall(registerMsg,
|
||||||
protocolVar,
|
protocol.protocolInfoVar,
|
||||||
newLit(msgId),
|
newLit(msgId),
|
||||||
newLit(msgName),
|
newLit(msgName),
|
||||||
thunkName,
|
thunkName,
|
||||||
|
@ -1055,7 +1063,7 @@ proc removePeer(network: EthereumNode, peer: Peer) =
|
||||||
|
|
||||||
proc callDisconnectHandlers(peer: Peer, reason: DisconnectionReason):
|
proc callDisconnectHandlers(peer: Peer, reason: DisconnectionReason):
|
||||||
Future[void] {.async.} =
|
Future[void] {.async.} =
|
||||||
var futures = newSeqOfCap[Future[void]](protocolCount())
|
var futures = newSeqOfCap[Future[void]](allProtocols.len)
|
||||||
|
|
||||||
for protocol in peer.dispatcher.activeProtocols:
|
for protocol in peer.dispatcher.activeProtocols:
|
||||||
if protocol.disconnectHandler != nil:
|
if protocol.disconnectHandler != nil:
|
||||||
|
@ -1136,7 +1144,7 @@ proc postHelloSteps(peer: Peer, h: DevP2P.hello) {.async.} =
|
||||||
# chance to send any initial packages they might require over
|
# chance to send any initial packages they might require over
|
||||||
# the network and to yield on their `nextMsg` waits.
|
# the network and to yield on their `nextMsg` waits.
|
||||||
#
|
#
|
||||||
var subProtocolsHandshakes = newSeqOfCap[Future[void]](protocolCount())
|
var subProtocolsHandshakes = newSeqOfCap[Future[void]](allProtocols.len)
|
||||||
for protocol in peer.dispatcher.activeProtocols:
|
for protocol in peer.dispatcher.activeProtocols:
|
||||||
if protocol.handshake != nil:
|
if protocol.handshake != nil:
|
||||||
subProtocolsHandshakes.add((protocol.handshake)(peer))
|
subProtocolsHandshakes.add((protocol.handshake)(peer))
|
||||||
|
|
|
@ -21,9 +21,6 @@ type
|
||||||
items: seq[Option[A]]
|
items: seq[Option[A]]
|
||||||
mask: uint32
|
mask: uint32
|
||||||
|
|
||||||
when not defined(nimHasEffectsOfs):
|
|
||||||
template effectsOf(f: untyped) {.pragma.}
|
|
||||||
|
|
||||||
# provided size will always be adjusted to next power of two
|
# provided size will always be adjusted to next power of two
|
||||||
proc init*[A](T: type GrowableCircularBuffer[A], size: uint32 = 16): T =
|
proc init*[A](T: type GrowableCircularBuffer[A], size: uint32 = 16): T =
|
||||||
let powOfTwoSize = nextPowerOfTwo(int(size))
|
let powOfTwoSize = nextPowerOfTwo(int(size))
|
||||||
|
@ -47,12 +44,10 @@ proc delete*[A](buff: var GrowableCircularBuffer[A], i: uint32) =
|
||||||
proc hasKey*[A](buff: GrowableCircularBuffer[A], i: uint32): bool =
|
proc hasKey*[A](buff: GrowableCircularBuffer[A], i: uint32): bool =
|
||||||
buff.get(i).isSome()
|
buff.get(i).isSome()
|
||||||
|
|
||||||
proc exists*[A](buff: GrowableCircularBuffer[A], i: uint32,
|
proc exists*[A](buff: GrowableCircularBuffer[A], i: uint32, check: proc (x: A): bool): bool =
|
||||||
check: proc (x: A): bool): bool {.gcsafe, effectsOf: check.} =
|
|
||||||
let maybeElem = buff.get(i)
|
let maybeElem = buff.get(i)
|
||||||
if (maybeElem.isSome()):
|
if (maybeElem.isSome()):
|
||||||
let elem = maybeElem.unsafeGet()
|
let elem = maybeElem.unsafeGet()
|
||||||
{.gcsafe.}:
|
|
||||||
check(elem)
|
check(elem)
|
||||||
else:
|
else:
|
||||||
false
|
false
|
||||||
|
|
|
@ -6,7 +6,7 @@ import
|
||||||
# real eth protocol implementation is in nimbus-eth1 repo
|
# real eth protocol implementation is in nimbus-eth1 repo
|
||||||
|
|
||||||
type
|
type
|
||||||
PeerState = ref object of RootRef
|
PeerState = ref object
|
||||||
initialized*: bool
|
initialized*: bool
|
||||||
|
|
||||||
p2pProtocol eth(version = 63,
|
p2pProtocol eth(version = 63,
|
||||||
|
|
|
@ -16,12 +16,9 @@ import
|
||||||
./p2p_test_helper
|
./p2p_test_helper
|
||||||
|
|
||||||
type
|
type
|
||||||
network = ref object of RootRef
|
network = ref object
|
||||||
count*: int
|
count*: int
|
||||||
|
|
||||||
PeerState = ref object of RootRef
|
|
||||||
status*: string
|
|
||||||
|
|
||||||
p2pProtocol abc(version = 1,
|
p2pProtocol abc(version = 1,
|
||||||
rlpxName = "abc",
|
rlpxName = "abc",
|
||||||
networkState = network):
|
networkState = network):
|
||||||
|
@ -36,18 +33,15 @@ p2pProtocol abc(version = 1,
|
||||||
|
|
||||||
p2pProtocol xyz(version = 1,
|
p2pProtocol xyz(version = 1,
|
||||||
rlpxName = "xyz",
|
rlpxName = "xyz",
|
||||||
networkState = network,
|
networkState = network):
|
||||||
peerState = PeerState):
|
|
||||||
|
|
||||||
onPeerConnected do (peer: Peer):
|
onPeerConnected do (peer: Peer):
|
||||||
peer.networkState.count += 1
|
peer.networkState.count += 1
|
||||||
peer.state.status = "connected"
|
|
||||||
|
|
||||||
onPeerDisconnected do (peer: Peer, reason: DisconnectionReason) {.gcsafe.}:
|
onPeerDisconnected do (peer: Peer, reason: DisconnectionReason) {.gcsafe.}:
|
||||||
peer.networkState.count -= 1
|
peer.networkState.count -= 1
|
||||||
if true:
|
if true:
|
||||||
raise newException(CatchableError, "Fake xyz exception")
|
raise newException(CatchableError, "Fake xyz exception")
|
||||||
peer.state.status = "disconnected"
|
|
||||||
|
|
||||||
p2pProtocol hah(version = 1,
|
p2pProtocol hah(version = 1,
|
||||||
rlpxName = "hah",
|
rlpxName = "hah",
|
||||||
|
@ -73,7 +67,6 @@ suite "Testing protocol handlers":
|
||||||
let peer = await node1.rlpxConnect(newNode(node2.toENode()))
|
let peer = await node1.rlpxConnect(newNode(node2.toENode()))
|
||||||
check:
|
check:
|
||||||
peer.isNil == false
|
peer.isNil == false
|
||||||
peer.state(xyz).status == "connected"
|
|
||||||
|
|
||||||
await peer.disconnect(SubprotocolReason, true)
|
await peer.disconnect(SubprotocolReason, true)
|
||||||
check:
|
check:
|
||||||
|
@ -81,7 +74,6 @@ suite "Testing protocol handlers":
|
||||||
# handlers, each handler still ran
|
# handlers, each handler still ran
|
||||||
node1.protocolState(abc).count == 0
|
node1.protocolState(abc).count == 0
|
||||||
node1.protocolState(xyz).count == 0
|
node1.protocolState(xyz).count == 0
|
||||||
peer.state(xyz).status == "connected"
|
|
||||||
|
|
||||||
asyncTest "Failing connection handler":
|
asyncTest "Failing connection handler":
|
||||||
let rng = newRng()
|
let rng = newRng()
|
||||||
|
|
Loading…
Reference in New Issue