Add top level push raises Defect to p2p code (#374)

This commit is contained in:
Kim De Mey 2021-07-16 21:44:30 +02:00 committed by GitHub
parent 2557fd35c6
commit a8d11dd30b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 22 deletions

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[tables, algorithm, random],
bearssl, chronos, chronos/timer, chronicles,
@ -14,8 +16,7 @@ import
export
p2p_types, rlpx, enode, kademlia
proc addCapability*(node: var EthereumNode, p: ProtocolInfo)
{.raises: [Defect].} =
proc addCapability*(node: var EthereumNode, p: ProtocolInfo) =
doAssert node.connectionState == ConnectionState.None
let pos = lowerBound(node.protocols, p, rlpx.cmp)
@ -36,7 +37,7 @@ proc newEthereumNode*(keys: KeyPair,
addAllCapabilities = true,
useCompression: bool = false,
minPeers = 10,
rng = newRng()): EthereumNode {.raises: [Defect].} =
rng = newRng()): EthereumNode =
if rng == nil: # newRng could fail
raise (ref Defect)(msg: "Cannot initialize RNG")
@ -79,7 +80,7 @@ proc processIncoming(server: StreamServer,
proc listeningAddress*(node: EthereumNode): ENode =
node.toENode()
proc startListening*(node: EthereumNode) =
proc startListening*(node: EthereumNode) {.raises: [CatchableError, Defect].} =
# TODO allow binding to specific IP / IPv6 / etc
let ta = initTAddress(IPv4_any(), node.address.tcpPort)
if node.listeningServer == nil:
@ -115,7 +116,7 @@ proc connectToNetwork*(node: EthereumNode,
trace "Waiting for more peers", peers = node.peerPool.connectedNodes.len
await sleepAsync(500.milliseconds)
proc stopListening*(node: EthereumNode) =
proc stopListening*(node: EthereumNode) {.raises: [CatchableError, Defect].} =
node.listeningServer.stop()
iterator peers*(node: EthereumNode): Peer =

View File

@ -1,3 +1,5 @@
{.push raises: [Defect].}
import
std/[options, sequtils],
stew/shims/macros, chronos, faststreams/outputs
@ -1004,7 +1006,11 @@ macro emitForSingleBackend(
peerState.getType, networkState.getType)
result = p.genCode()
try:
result.storeMacroResult true
except IOError:
# IO error so the generated nim code might not be stored, don't sweat it.
discard
macro emitForAllBackends(backendSyms: typed, options: untyped, body: untyped): untyped =
let name = $(options[0])

View File

@ -8,6 +8,8 @@
# PeerPool attempts to keep connections to at least min_peers
# on the given network.
{.push raises: [Defect].}
import
std/[os, tables, times, random, sequtils, options],
chronos, chronicles,
@ -100,7 +102,7 @@ proc connect(p: PeerPool, remote: Node): Future[Peer] {.async.} =
# self.logger.exception("Unexpected error during auth/p2p handshake with %s", remote)
# return None
proc lookupRandomNode(p: PeerPool) {.async, raises: [Defect].} =
proc lookupRandomNode(p: PeerPool) {.async.} =
discard await p.discovery.lookupRandom()
p.lastLookupTime = epochTime()
@ -108,7 +110,7 @@ proc getRandomBootnode(p: PeerPool): Option[Node] =
if p.discovery.bootstrapNodes.len != 0:
result = option(p.discovery.bootstrapNodes.sample())
proc addPeer*(pool: PeerPool, peer: Peer) {.gcsafe, raises: [Defect].} =
proc addPeer*(pool: PeerPool, peer: Peer) {.gcsafe.} =
doAssert(peer.remote notin pool.connectedNodes)
pool.connectedNodes[peer.remote] = peer
connected_peers.inc()
@ -163,7 +165,7 @@ proc maybeConnectToMorePeers(p: PeerPool) {.async.} =
if p.connectedNodes.len == 0 and (let n = p.getRandomBootnode(); n.isSome):
await p.connectToNode(n.get())
proc run(p: PeerPool) {.async, raises: [Defect].} =
proc run(p: PeerPool) {.async.} =
trace "Running PeerPool..."
p.running = true
while p.running:

View File

@ -70,8 +70,7 @@ chronicles.formatIt(Peer): $(it.remote)
include p2p_backends_helpers
proc requestResolver[MsgType](msg: pointer, future: FutureBase)
{.gcsafe, raises:[Defect].} =
proc requestResolver[MsgType](msg: pointer, future: FutureBase) {.gcsafe.} =
var f = Future[Option[MsgType]](future)
if not f.finished:
if msg != nil:
@ -117,7 +116,7 @@ proc messagePrinter[MsgType](msg: pointer): string {.gcsafe.} =
# result = $(cast[ptr MsgType](msg)[])
proc disconnect*(peer: Peer, reason: DisconnectionReason,
notifyOtherPeer = false) {.gcsafe, raises: [Defect], async.}
notifyOtherPeer = false) {.gcsafe, async.}
template raisePeerDisconnected(msg: string, r: DisconnectionReason) =
var e = newException(PeerDisconnected, msg)
@ -374,7 +373,7 @@ proc registerRequest(peer: Peer,
doAssert(not peer.dispatcher.isNil)
let requestResolver = peer.dispatcher.messages[responseMsgId].requestResolver
proc timeoutExpired(udata: pointer) {.gcsafe, raises:[Defect].} =
proc timeoutExpired(udata: pointer) {.gcsafe.} =
requestResolver(nil, responseFuture)
discard setTimer(timeoutAt, timeoutExpired, nil)
@ -880,7 +879,7 @@ p2pProtocol DevP2P(version = 5, rlpxName = "p2p"):
proc pong(peer: Peer, emptyList: EmptyList) =
discard
proc removePeer(network: EthereumNode, peer: Peer) {.raises: [Defect].} =
proc removePeer(network: EthereumNode, peer: Peer) =
# It is necessary to check if peer.remote still exists. The connection might
# have been dropped already from the peers side.
# E.g. when receiving a p2p.disconnect message from a peer, a race will happen
@ -914,7 +913,7 @@ proc callDisconnectHandlers(peer: Peer, reason: DisconnectionReason):
trace "Disconnection handler ended with an error", err = f.error.msg
proc disconnect*(peer: Peer, reason: DisconnectionReason,
notifyOtherPeer = false) {.async, raises: [Defect].} =
notifyOtherPeer = false) {.async.} =
if peer.connectionState notin {Disconnecting, Disconnected}:
peer.connectionState = Disconnecting
# Do this first so sub-protocols have time to clean up and stop sending

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[algorithm, bitops, math, options, tables, times, hashes],
chronicles, stew/[byteutils, endians2], metrics, bearssl,
@ -519,7 +521,7 @@ proc initQueue*(capacity: int): Queue =
result.capacity = capacity
result.itemHashes.init()
proc prune*(self: var Queue) {.raises: [].} =
proc prune*(self: var Queue) =
## Remove items that are past their expiry time
let now = epochTime().uint32
@ -654,7 +656,8 @@ proc notify*(filters: var Filters, msg: Message) {.gcsafe.} =
else:
filter.handler(receivedMsg)
proc getFilterMessages*(filters: var Filters, filterId: string): seq[ReceivedMessage] =
proc getFilterMessages*(filters: var Filters, filterId: string):
seq[ReceivedMessage] {.raises: [KeyError, Defect].} =
result = @[]
if filters.contains(filterId):
if filters[filterId].handler.isNil():

View File

@ -29,6 +29,8 @@
## However, they only make real sense after ``connectToNetwork`` was started. As
## else there will be no peers to send and receive messages from.
{.push raises: [Defect].}
import
std/[options, tables, times],
chronos, chronicles, metrics,
@ -247,7 +249,7 @@ p2pProtocol Whisper(version = whisperVersion,
# 'Runner' calls ---------------------------------------------------------------
proc processQueue(peer: Peer) {.raises: [Defect].} =
proc processQueue(peer: Peer) =
# Send to peer all valid and previously not send envelopes in the queue.
var
envelopes: seq[Envelope] = @[]
@ -278,12 +280,12 @@ proc processQueue(peer: Peer) {.raises: [Defect].} =
# gets dropped
traceAsyncErrors peer.messages(envelopes)
proc run(peer: Peer) {.async, raises: [Defect].} =
proc run(peer: Peer) {.async.} =
while peer.connectionState notin {Disconnecting, Disconnected}:
peer.processQueue()
await sleepAsync(messageInterval)
proc pruneReceived(node: EthereumNode) {.raises: [Defect].} =
proc pruneReceived(node: EthereumNode) =
if node.peerPool != nil: # XXX: a bit dirty to need to check for this here ...
var whisperNet = node.protocolState(Whisper)
@ -296,7 +298,7 @@ proc pruneReceived(node: EthereumNode) {.raises: [Defect].} =
# the received sets.
peer.received = intersection(peer.received, whisperNet.queue.itemHashes)
proc run(node: EthereumNode, network: WhisperNetwork) {.async, raises: [Defect].} =
proc run(node: EthereumNode, network: WhisperNetwork) {.async.} =
while true:
# prune message queue every second
# TTL unit is in seconds, so this should be sufficient?
@ -401,7 +403,8 @@ proc unsubscribeFilter*(node: EthereumNode, filterId: string): bool =
var filter: Filter
return node.protocolState(Whisper).filters.take(filterId, filter)
proc getFilterMessages*(node: EthereumNode, filterId: string): seq[ReceivedMessage] =
proc getFilterMessages*(node: EthereumNode, filterId: string):
seq[ReceivedMessage] {.raises: [KeyError, Defect].} =
## Get all the messages currently in the filter queue. This will reset the
## filter message queue.
return node.protocolState(Whisper).filters.getFilterMessages(filterId)