Remove all Defect raises to avoid unnecessary warnings (#607)

As this module dropped support for Nim versions < 1.6, all Defect
raises can be removed to avoid unnecessary warnings
This commit is contained in:
Kim De Mey 2023-05-10 15:50:04 +02:00 committed by GitHub
parent 7564b21ade
commit d57a1094b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 248 additions and 183 deletions

View File

@ -268,8 +268,8 @@ func destination*(tx: Transaction): EthAddress =
if tx.to.isSome: if tx.to.isSome:
return tx.to.get return tx.to.get
func init*(T: type BlockHashOrNumber, str: string): T func init*(
{.raises: [ValueError, Defect].} = T: type BlockHashOrNumber, str: string): T {.raises: [ValueError].} =
if str.startsWith "0x": if str.startsWith "0x":
if str.len != sizeof(default(T).hash.data) * 2 + 2: if str.len != sizeof(default(T).hash.data) * 2 + 2:
raise newException(ValueError, "Block hash has incorrect length") raise newException(ValueError, "Block hash has incorrect length")

View File

@ -1,3 +1,9 @@
# Copyright (c) 2022-2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * 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.
import import
std/[times, net], std/[times, net],
json_serialization, nimcrypto/[hash, utils], json_serialization, nimcrypto/[hash, utils],
@ -6,7 +12,7 @@ import
export export
json_serialization json_serialization
{.push raises: [SerializationError, IOError, Defect].} {.push raises: [SerializationError, IOError].}
proc writeValue*(w: var JsonWriter, a: MDigest) = proc writeValue*(w: var JsonWriter, a: MDigest) =
w.writeValue a.data.toHex(true) w.writeValue a.data.toHex(true)

View File

@ -1,6 +1,6 @@
## Implementation of KvStore based on sqlite3 ## Implementation of KvStore based on sqlite3
{.push raises: [Defect].} {.push raises: [].}
{.pragma: callback, gcsafe, raises: [].} {.pragma: callback, gcsafe, raises: [].}
import import

View File

@ -7,7 +7,7 @@
# Apache License, version 2.0, (LICENSE-APACHEv2) # Apache License, version 2.0, (LICENSE-APACHEv2)
# MIT license (LICENSE-MIT) # MIT license (LICENSE-MIT)
{.push raises: [Defect].} {.push raises: [].}
import import
std/[strutils, json], std/[strutils, json],
@ -480,7 +480,8 @@ proc loadKeyFile*(pathname: string,
data = json.parseFile(pathname) data = json.parseFile(pathname)
except JsonParsingError: except JsonParsingError:
return err(JsonError) return err(JsonError)
except Exception: # json raises Exception except Exception:
# json parseFile also raises IOError, ValueError and raw Exception
return err(OsError) return err(OsError)
decodeKeyFileJson(data, password) decodeKeyFileJson(data, password)

View File

@ -16,7 +16,7 @@
## - ``FreeBSD``, ``OpenBSD``, ``NetBSD``, ## - ``FreeBSD``, ``OpenBSD``, ``NetBSD``,
## ``DragonflyBSD`` - using `uuid_create()`. ## ``DragonflyBSD`` - using `uuid_create()`.
{.push raises: [Defect].} {.push raises: [].}
import stew/[byteutils, endians2, results] import stew/[byteutils, endians2, results]

View File

@ -1,5 +1,5 @@
# Nim Ethereum Keys (nim-eth-keys) # Nim Ethereum Keys
# Copyright (c) 2020 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed under either of # Licensed under either of
# - Apache License, version 2.0, (LICENSE-APACHEv2) # - Apache License, version 2.0, (LICENSE-APACHEv2)
# - MIT license (LICENSE-MIT) # - MIT license (LICENSE-MIT)
@ -12,7 +12,7 @@
# * Shared secrets are serialized in raw format without the initial byte # * Shared secrets are serialized in raw format without the initial byte
# * distinct types are used to avoid confusion with the "standard" secp types # * distinct types are used to avoid confusion with the "standard" secp types
{.push raises: [Defect].} {.push raises: [].}
import import
std/strformat, std/strformat,

View File

@ -1,4 +1,4 @@
# Copyright (c) 2019-2021 Status Research & Development GmbH # Copyright (c) 2019-2023 Status Research & Development GmbH
# Licensed under either of # Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT)) # * MIT license ([LICENSE-MIT](LICENSE-MIT))
@ -6,7 +6,7 @@
# This file may not be copied, modified, or distributed except according to # This file may not be copied, modified, or distributed except according to
# those terms. # those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[options, os, strutils, times], std/[options, os, strutils, times],
@ -204,7 +204,7 @@ var
natThread: Thread[PortMappingArgs] natThread: Thread[PortMappingArgs]
natCloseChan: Channel[bool] natCloseChan: Channel[bool]
proc repeatPortMapping(args: PortMappingArgs) {.thread, raises: [Defect, ValueError].} = proc repeatPortMapping(args: PortMappingArgs) {.thread, raises: [ValueError].} =
ignoreSignalsInThread() ignoreSignalsInThread()
let let
(tcpPort, udpPort, description) = args (tcpPort, udpPort, description) = args
@ -323,7 +323,7 @@ type
of true: extIp*: ValidIpAddress of true: extIp*: ValidIpAddress
of false: nat*: NatStrategy of false: nat*: NatStrategy
func parseCmdArg*(T: type NatConfig, p: string): T {.raises: [Defect, ConfigurationError].} = func parseCmdArg*(T: type NatConfig, p: string): T {.raises: [ConfigurationError].} =
case p.toLowerAscii: case p.toLowerAscii:
of "any": of "any":
NatConfig(hasExtIp: false, nat: NatAny) NatConfig(hasExtIp: false, nat: NatAny)

View File

@ -1,11 +1,11 @@
# nim-eth # nim-eth
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, hashes], std/[tables, hashes],

View File

@ -1,11 +1,11 @@
# nim-eth # nim-eth
# Copyright (c) 2018-2022 Status Research & Development GmbH # Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, algorithm, random, typetraits, strutils, net], std/[tables, algorithm, random, typetraits, strutils, net],
@ -134,7 +134,7 @@ proc processIncoming(server: StreamServer,
proc listeningAddress*(node: EthereumNode): ENode = proc listeningAddress*(node: EthereumNode): ENode =
node.toENode() node.toENode()
proc startListening*(node: EthereumNode) {.raises: [CatchableError, Defect].} = proc startListening*(node: EthereumNode) {.raises: [CatchableError].} =
# TODO: allow binding to both IPv4 & IPv6 # TODO: allow binding to both IPv4 & IPv6
let ta = initTAddress(node.bindIp, node.bindPort) let ta = initTAddress(node.bindIp, node.bindPort)
if node.listeningServer == nil: if node.listeningServer == nil:
@ -165,7 +165,7 @@ proc connectToNetwork*(
trace "Waiting for more peers", peers = node.peerPool.connectedNodes.len trace "Waiting for more peers", peers = node.peerPool.connectedNodes.len
await sleepAsync(500.milliseconds) await sleepAsync(500.milliseconds)
proc stopListening*(node: EthereumNode) {.raises: [CatchableError, Defect].} = proc stopListening*(node: EthereumNode) {.raises: [CatchableError].} =
node.listeningServer.stop() node.listeningServer.stop()
iterator peers*(node: EthereumNode): Peer = iterator peers*(node: EthereumNode): Peer =

View File

@ -1,6 +1,6 @@
# #
# Ethereum P2P # Ethereum P2P
# (c) Copyright 2018-2022 # (c) Copyright 2018-2023
# Status Research & Development GmbH # Status Research & Development GmbH
# #
# Licensed under either of # Licensed under either of
@ -10,7 +10,7 @@
## This module implements Ethereum RLPx authentication ## This module implements Ethereum RLPx authentication
{.push raises: [Defect].} {.push raises: [].}
import import
nimcrypto/[rijndael, keccak, utils], nimcrypto/[rijndael, keccak, utils],

View File

@ -1,11 +1,11 @@
# nim-eth # nim-eth
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[times, net], std/[times, net],
@ -86,7 +86,7 @@ proc recoverMsgPublicKey(msg: openArray[byte]): DiscResult[PublicKey] =
recover(sig, msg.toOpenArray(HEAD_SIZE, msg.high)) recover(sig, msg.toOpenArray(HEAD_SIZE, msg.high))
proc unpack(msg: openArray[byte]): tuple[cmdId: CommandId, payload: seq[byte]] proc unpack(msg: openArray[byte]): tuple[cmdId: CommandId, payload: seq[byte]]
{.raises: [DiscProtocolError, Defect].} = {.raises: [DiscProtocolError].} =
# Check against possible RangeError # Check against possible RangeError
if msg[HEAD_SIZE].int < CommandId.low.ord or if msg[HEAD_SIZE].int < CommandId.low.ord or
msg[HEAD_SIZE].int > CommandId.high.ord: msg[HEAD_SIZE].int > CommandId.high.ord:
@ -99,14 +99,14 @@ proc expiration(): uint32 =
# Wire protocol # Wire protocol
proc send(d: DiscoveryProtocol, n: Node, data: seq[byte]) {.raises: [Defect].} = proc send(d: DiscoveryProtocol, n: Node, data: seq[byte]) =
let ta = initTAddress(n.node.address.ip, n.node.address.udpPort) let ta = initTAddress(n.node.address.ip, n.node.address.udpPort)
let f = d.transp.sendTo(ta, data) let f = d.transp.sendTo(ta, data)
f.callback = proc(data: pointer) {.gcsafe.} = f.callback = proc(data: pointer) {.gcsafe.} =
if f.failed: if f.failed:
debug "Discovery send failed", msg = f.readError.msg debug "Discovery send failed", msg = f.readError.msg
proc sendPing*(d: DiscoveryProtocol, n: Node): seq[byte] {.raises: [Defect].} = proc sendPing*(d: DiscoveryProtocol, n: Node): seq[byte] =
let payload = rlp.encode((PROTO_VERSION, d.address, n.node.address, let payload = rlp.encode((PROTO_VERSION, d.address, n.node.address,
expiration())) expiration()))
let msg = pack(cmdPing, payload, d.privKey) let msg = pack(cmdPing, payload, d.privKey)
@ -172,17 +172,17 @@ proc newDiscoveryProtocol*(
discovery discovery
proc recvPing(d: DiscoveryProtocol, node: Node, msgHash: MDigest[256]) proc recvPing(d: DiscoveryProtocol, node: Node, msgHash: MDigest[256])
{.raises: [ValueError, Defect].} = {.raises: [ValueError].} =
d.kademlia.recvPing(node, msgHash) d.kademlia.recvPing(node, msgHash)
proc recvPong(d: DiscoveryProtocol, node: Node, payload: seq[byte]) proc recvPong(d: DiscoveryProtocol, node: Node, payload: seq[byte])
{.raises: [RlpError, Defect].} = {.raises: [RlpError].} =
let rlp = rlpFromBytes(payload) let rlp = rlpFromBytes(payload)
let tok = rlp.listElem(1).toBytes() let tok = rlp.listElem(1).toBytes()
d.kademlia.recvPong(node, tok) d.kademlia.recvPong(node, tok)
proc recvNeighbours(d: DiscoveryProtocol, node: Node, payload: seq[byte]) proc recvNeighbours(d: DiscoveryProtocol, node: Node, payload: seq[byte])
{.raises: [RlpError, Defect].} = {.raises: [RlpError].} =
let rlp = rlpFromBytes(payload) let rlp = rlpFromBytes(payload)
let neighboursList = rlp.listElem(0) let neighboursList = rlp.listElem(0)
let sz = neighboursList.listLen() let sz = neighboursList.listLen()
@ -214,7 +214,7 @@ proc recvNeighbours(d: DiscoveryProtocol, node: Node, payload: seq[byte])
d.kademlia.recvNeighbours(node, neighbours) d.kademlia.recvNeighbours(node, neighbours)
proc recvFindNode(d: DiscoveryProtocol, node: Node, payload: openArray[byte]) proc recvFindNode(d: DiscoveryProtocol, node: Node, payload: openArray[byte])
{.raises: [RlpError, ValueError, Defect].} = {.raises: [RlpError, ValueError].} =
let rlp = rlpFromBytes(payload) let rlp = rlpFromBytes(payload)
trace "<<< find_node from ", node trace "<<< find_node from ", node
let rng = rlp.listElem(0).toBytes let rng = rlp.listElem(0).toBytes
@ -242,7 +242,7 @@ proc expirationValid(cmdId: CommandId, rlpEncodedPayload: openArray[byte]):
raise newException(DiscProtocolError, "Invalid RLP list for this packet id") raise newException(DiscProtocolError, "Invalid RLP list for this packet id")
proc receive*(d: DiscoveryProtocol, a: Address, msg: openArray[byte]) proc receive*(d: DiscoveryProtocol, a: Address, msg: openArray[byte])
{.raises: [DiscProtocolError, RlpError, ValueError, Defect].} = {.raises: [DiscProtocolError, RlpError, ValueError].} =
# Note: export only needed for testing # Note: export only needed for testing
let msgHash = validateMsgHash(msg) let msgHash = validateMsgHash(msg)
if msgHash.isOk(): if msgHash.isOk():
@ -272,7 +272,7 @@ proc receive*(d: DiscoveryProtocol, a: Address, msg: openArray[byte])
notice "Wrong msg mac from ", a notice "Wrong msg mac from ", a
proc processClient(transp: DatagramTransport, raddr: TransportAddress): proc processClient(transp: DatagramTransport, raddr: TransportAddress):
Future[void] {.async, raises: [Defect].} = Future[void] {.async.} =
var proto = getUserData[DiscoveryProtocol](transp) var proto = getUserData[DiscoveryProtocol](transp)
let buf = try: transp.getMessage() let buf = try: transp.getMessage()
except TransportOsError as e: except TransportOsError as e:
@ -289,7 +289,7 @@ proc processClient(transp: DatagramTransport, raddr: TransportAddress):
except ValueError as e: except ValueError as e:
debug "Receive failed", exc = e.name, err = e.msg debug "Receive failed", exc = e.name, err = e.msg
proc open*(d: DiscoveryProtocol) {.raises: [Defect, CatchableError].} = proc open*(d: DiscoveryProtocol) {.raises: [CatchableError].} =
# TODO: allow binding to both IPv4 and IPv6 # TODO: allow binding to both IPv4 and IPv6
let ta = initTAddress(d.bindIp, d.bindPort) let ta = initTAddress(d.bindIp, d.bindPort)
d.transp = newDatagramTransport(processClient, udata = d, local = ta) d.transp = newDatagramTransport(processClient, udata = d, local = ta)

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -11,7 +11,7 @@
## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#sessions ## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#sessions
## ##
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, options, hashes, net], std/[tables, options, hashes, net],

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -8,7 +8,7 @@
## ENR implementation according to specification in EIP-778: ## ENR implementation according to specification in EIP-778:
## https://github.com/ethereum/EIPs/blob/master/EIPS/eip-778.md ## https://github.com/ethereum/EIPs/blob/master/EIPS/eip-778.md
{.push raises: [Defect].} {.push raises: [].}
import import
std/[strutils, macros, algorithm, options], std/[strutils, macros, algorithm, options],
@ -394,7 +394,7 @@ func verifySignatureV4(
else: else:
false false
func verifySignature(r: Record): bool {.raises: [RlpError, Defect].} = func verifySignature(r: Record): bool {.raises: [RlpError].} =
var rlp = rlpFromBytes(r.raw) var rlp = rlpFromBytes(r.raw)
let sz = rlp.listLen let sz = rlp.listLen
if not rlp.enterList: if not rlp.enterList:
@ -420,7 +420,7 @@ func verifySignature(r: Record): bool {.raises: [RlpError, Defect].} =
# No Identity Scheme provided # No Identity Scheme provided
false false
func fromBytesAux(r: var Record): bool {.raises: [RlpError, Defect].} = func fromBytesAux(r: var Record): bool {.raises: [RlpError].} =
if r.raw.len > maxEnrSize: if r.raw.len > maxEnrSize:
return false return false
@ -546,7 +546,7 @@ func `==`*(a, b: Record): bool = a.raw == b.raw
func read*( func read*(
rlp: var Rlp, T: type Record): rlp: var Rlp, T: type Record):
T {.raises: [RlpError, ValueError, Defect].} = T {.raises: [RlpError, ValueError].} =
var res: T var res: T
if not rlp.hasData() or not res.fromBytes(rlp.rawData): if not rlp.hasData() or not res.fromBytes(rlp.rawData):
# TODO: This could also just be an invalid signature, would be cleaner to # TODO: This could also just be an invalid signature, would be cleaner to

View File

@ -1,9 +1,20 @@
# nim-eth
# Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * 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: [].}
import import
nimcrypto/[hmac, hash] nimcrypto/[hmac, hash]
export hmac, hash export hmac, hash
proc hkdf*(HashType: typedesc, ikm, salt, info: openArray[byte], proc hkdf*(
HashType: typedesc, ikm, salt, info: openArray[byte],
output: var openArray[byte]) = output: var openArray[byte]) =
var ctx: HMAC[HashType] var ctx: HMAC[HashType]
ctx.init(salt) ctx.init(salt)

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -15,7 +15,7 @@
## To select the right address, a majority count is done. This is done over a ## To select the right address, a majority count is done. This is done over a
## sort of moving window as votes expire after `IpVoteTimeout`. ## sort of moving window as votes expire after `IpVoteTimeout`.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, options], std/[tables, options],

View File

@ -1,6 +1,14 @@
import std/[tables, lists, options] # nim-eth
# Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * 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].} {.push raises: [].}
import std/[tables, lists, options]
type type
LRUCache*[K, V] = object of RootObj LRUCache*[K, V] = object of RootObj

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -9,7 +9,7 @@
## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-wire.md#protocol-messages ## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-wire.md#protocol-messages
## ##
{.push raises: [Defect].} {.push raises: [].}
import import
std/[hashes, net], std/[hashes, net],

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2022 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -7,7 +7,7 @@
# #
## Discovery v5 Protocol Messages RLP Encoding ## Discovery v5 Protocol Messages RLP Encoding
{.push raises: [Defect].} {.push raises: [].}
import import
std/net, std/net,
@ -20,7 +20,7 @@ from stew/objects import checkedEnumAssign
export messages, rlp, results export messages, rlp, results
func read*(rlp: var Rlp, T: type RequestId): T func read*(rlp: var Rlp, T: type RequestId): T
{.raises: [ValueError, RlpError, Defect].} = {.raises: [ValueError, RlpError].} =
mixin read mixin read
var reqId: RequestId var reqId: RequestId
reqId.id = rlp.toBytes() reqId.id = rlp.toBytes()
@ -34,7 +34,7 @@ func append*(writer: var RlpWriter, value: RequestId) =
writer.append(value.id) writer.append(value.id)
func read*(rlp: var Rlp, T: type IpAddress): T func read*(rlp: var Rlp, T: type IpAddress): T
{.raises: [RlpError, Defect].} = {.raises: [RlpError].} =
let ipBytes = rlp.toBytes() let ipBytes = rlp.toBytes()
rlp.skipElem() rlp.skipElem()
@ -93,7 +93,7 @@ func decodeMessage*(body: openArray[byte]): Result[Message, cstring] =
return err("Invalid request-id") return err("Invalid request-id")
func decode[T](rlp: var Rlp, v: var T) func decode[T](rlp: var Rlp, v: var T)
{.nimcall, raises:[RlpError, ValueError, Defect].} = {.nimcall, raises: [RlpError, ValueError].} =
for k, v in v.fieldPairs: for k, v in v.fieldPairs:
v = rlp.read(typeof(v)) v = rlp.read(typeof(v))

View File

@ -1,11 +1,11 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/hashes, std/hashes,

View File

@ -6,7 +6,7 @@
# This file may not be copied, modified, or distributed except according to # This file may not be copied, modified, or distributed except according to
# those terms. # those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[sets, options], std/[sets, options],

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2022 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -78,7 +78,7 @@
## When distance 0 is provided in the requested list of distances, only the own ## When distance 0 is provided in the requested list of distances, only the own
## ENR will be returned. ## ENR will be returned.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, sets, options, math, sequtils, algorithm], std/[tables, sets, options, math, sequtils, algorithm],
@ -158,7 +158,7 @@ type
TalkProtocolHandler* = proc( TalkProtocolHandler* = proc(
p: TalkProtocol, request: seq[byte], p: TalkProtocol, request: seq[byte],
fromId: NodeId, fromUdpAddress: Address): seq[byte] fromId: NodeId, fromUdpAddress: Address): seq[byte]
{.gcsafe, raises: [Defect].} {.gcsafe, raises: [].}
TalkProtocol* = ref object of RootObj TalkProtocol* = ref object of RootObj
protocolHandler*: TalkProtocolHandler protocolHandler*: TalkProtocolHandler
@ -1016,7 +1016,7 @@ proc newProtocol*(
template listeningAddress*(p: Protocol): Address = template listeningAddress*(p: Protocol): Address =
p.bindAddress p.bindAddress
proc open*(d: Protocol) {.raises: [Defect, CatchableError].} = proc open*(d: Protocol) {.raises: [CatchableError].} =
info "Starting discovery node", node = d.localNode, info "Starting discovery node", node = d.localNode,
bindAddress = d.bindAddress bindAddress = d.bindAddress

View File

@ -1,3 +1,13 @@
# nim-eth
# Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * 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: [].}
import import
bearssl/rand bearssl/rand

View File

@ -1,11 +1,11 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[algorithm, times, sequtils, bitops, sets, options], std/[algorithm, times, sequtils, bitops, sets, options],
@ -20,9 +20,12 @@ declarePublicGauge routing_table_nodes,
"Discovery routing table nodes", labels = ["state"] "Discovery routing table nodes", labels = ["state"]
type type
DistanceProc* = proc(a, b: NodeId): NodeId {.raises: [Defect], gcsafe, noSideEffect.} DistanceProc* =
LogDistanceProc* = proc(a, b: NodeId): uint16 {.raises: [Defect], gcsafe, noSideEffect.} proc(a, b: NodeId): NodeId {.raises: [], gcsafe, noSideEffect.}
IdAtDistanceProc* = proc (id: NodeId, dist: uint16): NodeId {.raises: [Defect], gcsafe, noSideEffect.} LogDistanceProc* =
proc(a, b: NodeId): uint16 {.raises: [], gcsafe, noSideEffect.}
IdAtDistanceProc* =
proc (id: NodeId, dist: uint16): NodeId {.raises: [], gcsafe, noSideEffect.}
DistanceCalculator* = object DistanceCalculator* = object
calculateDistance*: DistanceProc calculateDistance*: DistanceProc

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5 # nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -9,7 +9,7 @@
## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#session-cache ## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#session-cache
## ##
{.push raises: [Defect].} {.push raises: [].}
import import
std/options, std/options,

View File

@ -1,6 +1,6 @@
# #
# Ethereum P2P # Ethereum P2P
# (c) Copyright 2018-2022 # (c) Copyright 2018-2023
# Status Research & Development GmbH # Status Research & Development GmbH
# #
# Licensed under either of # Licensed under either of
@ -10,7 +10,7 @@
## This module implements ECIES method encryption/decryption. ## This module implements ECIES method encryption/decryption.
{.push raises: [Defect].} {.push raises: [].}
import import
stew/[results, endians2], stew/[results, endians2],

View File

@ -1,6 +1,6 @@
# #
# Ethereum P2P # Ethereum P2P
# (c) Copyright 2018-2020 # (c) Copyright 2018-2023
# Status Research & Development GmbH # Status Research & Development GmbH
# #
# Licensed under either of # Licensed under either of
@ -8,7 +8,7 @@
# MIT license (LICENSE-MIT) # MIT license (LICENSE-MIT)
# #
{.push raises: [Defect].} {.push raises: [].}
import import
std/[uri, strutils, net], std/[uri, strutils, net],

View File

@ -1,11 +1,11 @@
# nim-eth # nim-eth
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, hashes, times, algorithm, sets, sequtils], std/[tables, hashes, times, algorithm, sets, sequtils],
@ -31,7 +31,7 @@ type
routing: RoutingTable routing: RoutingTable
pongFutures: Table[seq[byte], Future[bool]] pongFutures: Table[seq[byte], Future[bool]]
pingFutures: Table[Node, Future[bool]] pingFutures: Table[Node, Future[bool]]
neighboursCallbacks: Table[Node, proc(n: seq[Node]) {.gcsafe, raises: [Defect].}] neighboursCallbacks: Table[Node, proc(n: seq[Node]) {.gcsafe, raises: [].}]
rng: ref HmacDrbgContext rng: ref HmacDrbgContext
pingPongTime: OrderedTable[TimeKey, int64] # int64 -> unix time pingPongTime: OrderedTable[TimeKey, int64] # int64 -> unix time
@ -253,7 +253,7 @@ proc isFull(k: KBucket): bool = k.len == BUCKET_SIZE
proc contains(k: KBucket, n: Node): bool = n in k.nodes proc contains(k: KBucket, n: Node): bool = n in k.nodes
proc binaryGetBucketForNode(buckets: openArray[KBucket], n: Node): proc binaryGetBucketForNode(buckets: openArray[KBucket], n: Node):
KBucket {.raises: [ValueError, Defect].} = KBucket {.raises: [ValueError].} =
## Given a list of ordered buckets, returns the bucket for a given node. ## Given a list of ordered buckets, returns the bucket for a given node.
let bucketPos = lowerBound(buckets, n.id) do(a: KBucket, b: NodeId) -> int: let bucketPos = lowerBound(buckets, n.id) do(a: KBucket, b: NodeId) -> int:
cmp(a.iend, b) cmp(a.iend, b)
@ -293,14 +293,14 @@ proc splitBucket(r: var RoutingTable, index: int) =
r.buckets.insert(b, index + 1) r.buckets.insert(b, index + 1)
proc bucketForNode(r: RoutingTable, n: Node): KBucket proc bucketForNode(r: RoutingTable, n: Node): KBucket
{.raises: [ValueError, Defect].} = {.raises: [ValueError].} =
binaryGetBucketForNode(r.buckets, n) binaryGetBucketForNode(r.buckets, n)
proc removeNode(r: var RoutingTable, n: Node) {.raises: [ValueError, Defect].} = proc removeNode(r: var RoutingTable, n: Node) {.raises: [ValueError].} =
r.bucketForNode(n).removeNode(n) r.bucketForNode(n).removeNode(n)
proc addNode(r: var RoutingTable, n: Node): Node proc addNode(r: var RoutingTable, n: Node): Node
{.raises: [ValueError, Defect].} = {.raises: [ValueError].} =
if n == r.thisNode: if n == r.thisNode:
warn "Trying to add ourselves to the routing table", node = n warn "Trying to add ourselves to the routing table", node = n
return return
@ -318,7 +318,7 @@ proc addNode(r: var RoutingTable, n: Node): Node
# Nothing added, ping evictionCandidate # Nothing added, ping evictionCandidate
return evictionCandidate return evictionCandidate
proc contains(r: RoutingTable, n: Node): bool {.raises: [ValueError, Defect].} = proc contains(r: RoutingTable, n: Node): bool {.raises: [ValueError].} =
n in r.bucketForNode(n) n in r.bucketForNode(n)
proc bucketsByDistanceTo(r: RoutingTable, id: NodeId): seq[KBucket] = proc bucketsByDistanceTo(r: RoutingTable, id: NodeId): seq[KBucket] =
@ -357,7 +357,7 @@ proc bond(k: KademliaProtocol, n: Node): Future[bool] {.async.}
proc bondDiscard(k: KademliaProtocol, n: Node) {.async.} proc bondDiscard(k: KademliaProtocol, n: Node) {.async.}
proc updateRoutingTable(k: KademliaProtocol, n: Node) proc updateRoutingTable(k: KademliaProtocol, n: Node)
{.raises: [ValueError, Defect], gcsafe.} = {.raises: [ValueError], gcsafe.} =
## Update the routing table entry for the given node. ## Update the routing table entry for the given node.
let evictionCandidate = k.routing.addNode(n) let evictionCandidate = k.routing.addNode(n)
if not evictionCandidate.isNil: if not evictionCandidate.isNil:
@ -367,7 +367,7 @@ proc updateRoutingTable(k: KademliaProtocol, n: Node)
# replacement cache. # replacement cache.
asyncSpawn k.bondDiscard(evictionCandidate) asyncSpawn k.bondDiscard(evictionCandidate)
proc doSleep(p: proc() {.gcsafe, raises: [Defect].}) {.async.} = proc doSleep(p: proc() {.gcsafe, raises: [].}) {.async.} =
await sleepAsync(REQUEST_TIMEOUT) await sleepAsync(REQUEST_TIMEOUT)
p() p()
@ -402,13 +402,12 @@ proc waitPing(k: KademliaProtocol, n: Node): Future[bool] =
k.pingFutures.del(n) k.pingFutures.del(n)
fut.complete(false) fut.complete(false)
proc waitNeighbours(k: KademliaProtocol, remote: Node): proc waitNeighbours(k: KademliaProtocol, remote: Node): Future[seq[Node]] =
Future[seq[Node]] {.raises: [Defect].} =
doAssert(remote notin k.neighboursCallbacks) doAssert(remote notin k.neighboursCallbacks)
result = newFuture[seq[Node]]("waitNeighbours") result = newFuture[seq[Node]]("waitNeighbours")
let fut = result let fut = result
var neighbours = newSeqOfCap[Node](BUCKET_SIZE) var neighbours = newSeqOfCap[Node](BUCKET_SIZE)
k.neighboursCallbacks[remote] = proc(n: seq[Node]) {.gcsafe, raises: [Defect].} = k.neighboursCallbacks[remote] = proc(n: seq[Node]) {.gcsafe, raises: [].} =
# This callback is expected to be called multiple times because nodes usually # This callback is expected to be called multiple times because nodes usually
# split the neighbours replies into multiple packets, so we only complete the # split the neighbours replies into multiple packets, so we only complete the
# future event.set() we've received enough neighbours. # future event.set() we've received enough neighbours.
@ -607,7 +606,7 @@ proc recvPong*(k: KademliaProtocol, n: Node, token: seq[byte]) =
k.updateLastPongReceived(n, getTime()) k.updateLastPongReceived(n, getTime())
proc recvPing*(k: KademliaProtocol, n: Node, msgHash: auto) proc recvPing*(k: KademliaProtocol, n: Node, msgHash: auto)
{.raises: [ValueError, Defect].} = {.raises: [ValueError].} =
trace "<<< ping from ", n trace "<<< ping from ", n
k.wire.sendPong(n, msgHash) k.wire.sendPong(n, msgHash)
@ -654,7 +653,7 @@ proc recvNeighbours*(k: KademliaProtocol, remote: Node, neighbours: seq[Node]) =
trace "Unexpected neighbours, probably came too late", remote trace "Unexpected neighbours, probably came too late", remote
proc recvFindNode*(k: KademliaProtocol, remote: Node, nodeId: NodeId) proc recvFindNode*(k: KademliaProtocol, remote: Node, nodeId: NodeId)
{.raises: [ValueError, Defect].} = {.raises: [ValueError].} =
if remote notin k.routing: if remote notin k.routing:
# FIXME: This is not correct; a node we've bonded before may have become unavailable # FIXME: This is not correct; a node we've bonded before may have become unavailable
# and thus removed from self.routing, but once it's back online we should accept # and thus removed from self.routing, but once it's back online we should accept

View File

@ -29,11 +29,11 @@ template networkState*(connection: Peer, Protocol: type): untyped =
protocolState(connection.network, Protocol) protocolState(connection.network, Protocol)
proc initProtocolState*[T](state: T, x: Peer|EthereumNode) proc initProtocolState*[T](state: T, x: Peer|EthereumNode)
{.gcsafe, raises: [Defect].} = {.gcsafe, raises: [].} =
discard discard
proc initProtocolStates(peer: Peer, protocols: openArray[ProtocolInfo]) proc initProtocolStates(peer: Peer, protocols: openArray[ProtocolInfo])
{.raises: [Defect].} = {.raises: [].} =
# Initialize all the active protocol states # Initialize all the active protocol states
newSeq(peer.protocolStates, allProtocols.len) newSeq(peer.protocolStates, allProtocols.len)
for protocol in protocols: for protocol in protocols:

View File

@ -1,4 +1,4 @@
{.push raises: [Defect].} {.push raises: [].}
import import
std/[options, sequtils], std/[options, sequtils],

View File

@ -1,5 +1,5 @@
# nim-eth # nim-eth
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -8,7 +8,7 @@
# PeerPool attempts to keep connections to at least min_peers # PeerPool attempts to keep connections to at least min_peers
# on the given network. # on the given network.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[os, tables, times, random, sequtils, options], std/[os, tables, times, random, sequtils, options],

View File

@ -1,10 +1,12 @@
# nim-eth # nim-eth
# Copyright (c) 2018-2022 Status Research & Development GmbH # Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import import
std/[deques, tables], std/[deques, tables],
chronos, chronos,
@ -74,8 +76,8 @@ type
observers*: Table[int, PeerObserver] observers*: Table[int, PeerObserver]
PeerObserver* = object PeerObserver* = object
onPeerConnected*: proc(p: Peer) {.gcsafe, raises: [Defect].} onPeerConnected*: proc(p: Peer) {.gcsafe, raises: [].}
onPeerDisconnected*: proc(p: Peer) {.gcsafe, raises: [Defect].} onPeerDisconnected*: proc(p: Peer) {.gcsafe, raises: [].}
protocol*: ProtocolInfo protocol*: ProtocolInfo
Capability* = object Capability* = object
@ -152,19 +154,19 @@ type
# Private types: # Private types:
MessageHandlerDecorator* = proc(msgId: int, n: NimNode): NimNode MessageHandlerDecorator* = proc(msgId: int, n: NimNode): NimNode
ThunkProc* = proc(x: Peer, msgId: int, data: Rlp): Future[void] ThunkProc* = proc(x: Peer, msgId: int, data: Rlp): Future[void]
{.gcsafe, raises: [RlpError, Defect].} {.gcsafe, raises: [RlpError].}
MessageContentPrinter* = proc(msg: pointer): string MessageContentPrinter* = proc(msg: pointer): string
{.gcsafe, raises: [Defect].} {.gcsafe, raises: [].}
RequestResolver* = proc(msg: pointer, future: FutureBase) RequestResolver* = proc(msg: pointer, future: FutureBase)
{.gcsafe, raises: [Defect].} {.gcsafe, raises: [].}
NextMsgResolver* = proc(msgData: Rlp, future: FutureBase) NextMsgResolver* = proc(msgData: Rlp, future: FutureBase)
{.gcsafe, raises: [RlpError, Defect].} {.gcsafe, raises: [RlpError].}
PeerStateInitializer* = proc(peer: Peer): RootRef {.gcsafe, raises: [Defect].} PeerStateInitializer* = proc(peer: Peer): RootRef {.gcsafe, raises: [].}
NetworkStateInitializer* = proc(network: EthereumNode): RootRef NetworkStateInitializer* = proc(network: EthereumNode): RootRef
{.gcsafe, raises: [Defect].} {.gcsafe, raises: [].}
HandshakeStep* = proc(peer: Peer): Future[void] {.gcsafe, raises: [Defect].} HandshakeStep* = proc(peer: Peer): Future[void] {.gcsafe, raises: [].}
DisconnectionHandler* = proc(peer: Peer, reason: DisconnectionReason): DisconnectionHandler* = proc(peer: Peer, reason: DisconnectionReason):
Future[void] {.gcsafe, raises: [Defect].} Future[void] {.gcsafe, raises: [].}
ConnectionState* = enum ConnectionState* = enum
None, None,

View File

@ -1,11 +1,11 @@
# nim-eth # nim-eth
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, algorithm, deques, hashes, options, typetraits, os], std/[tables, algorithm, deques, hashes, options, typetraits, os],
@ -71,7 +71,7 @@ type
value: DisconnectionReason value: DisconnectionReason
proc read(rlp: var Rlp; T: type DisconnectionReasonList): T proc read(rlp: var Rlp; T: type DisconnectionReasonList): T
{.gcsafe, raises: [RlpError, Defect].} = {.gcsafe, raises: [RlpError].} =
## Rlp mixin: `DisconnectionReasonList` parser ## Rlp mixin: `DisconnectionReasonList` parser
if rlp.isList: if rlp.isList:
@ -321,7 +321,7 @@ proc cmp*(lhs, rhs: ProtocolInfo): int =
return cmp(lhs.name, rhs.name) return cmp(lhs.name, rhs.name)
proc nextMsgResolver[MsgType](msgData: Rlp, future: FutureBase) proc nextMsgResolver[MsgType](msgData: Rlp, future: FutureBase)
{.gcsafe, raises: [RlpError, Defect].} = {.gcsafe, raises: [RlpError].} =
var reader = msgData var reader = msgData
Future[MsgType](future).complete reader.readRecordType(MsgType, Future[MsgType](future).complete reader.readRecordType(MsgType,
MsgType.rlpFieldsCount > 1) MsgType.rlpFieldsCount > 1)
@ -374,7 +374,7 @@ template perPeerMsgId(peer: Peer, MsgType: type): int =
perPeerMsgIdImpl(peer, MsgType.msgProtocol.protocolInfo, MsgType.msgId) perPeerMsgIdImpl(peer, MsgType.msgProtocol.protocolInfo, MsgType.msgId)
proc invokeThunk*(peer: Peer, msgId: int, msgData: var Rlp): Future[void] proc invokeThunk*(peer: Peer, msgId: int, msgData: var Rlp): Future[void]
{.raises: [UnsupportedMessageError, RlpError, Defect].} = {.raises: [UnsupportedMessageError, RlpError].} =
template invalidIdError: untyped = template invalidIdError: untyped =
raise newException(UnsupportedMessageError, raise newException(UnsupportedMessageError,
"RLPx message with an invalid id " & $msgId & "RLPx message with an invalid id " & $msgId &
@ -698,7 +698,7 @@ proc recvMsg*(peer: Peer): Future[tuple[msgId: int, msgData: Rlp]] {.async.} =
proc checkedRlpRead(peer: Peer, r: var Rlp, MsgType: type): proc checkedRlpRead(peer: Peer, r: var Rlp, MsgType: type):
auto {.raises: [RlpError, Defect].} = auto {.raises: [RlpError].} =
when defined(release): when defined(release):
return r.read(MsgType) return r.read(MsgType)
else: else:
@ -962,7 +962,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
proc `thunkName`(`peerVar`: `Peer`, _: int, data: Rlp) proc `thunkName`(`peerVar`: `Peer`, _: int, data: Rlp)
# Fun error if you just use `RlpError` instead of `rlp.RlpError`: # Fun error if you just use `RlpError` instead of `rlp.RlpError`:
# "Error: type expected, but got symbol 'RlpError' of kind 'EnumField'" # "Error: type expected, but got symbol 'RlpError' of kind 'EnumField'"
{.async, gcsafe, raises: [rlp.RlpError, Defect].} = {.async, gcsafe, raises: [rlp.RlpError].} =
var `receivedRlp` = data var `receivedRlp` = data
var `receivedMsg` {.noinit.}: `msgRecName` var `receivedMsg` {.noinit.}: `msgRecName`
`readParamsPrelude` `readParamsPrelude`
@ -1130,13 +1130,13 @@ func validatePubKeyInHello(msg: DevP2P.hello, pubKey: PublicKey): bool =
let pk = PublicKey.fromRaw(msg.nodeId) let pk = PublicKey.fromRaw(msg.nodeId)
pk.isOk and pk[] == pubKey pk.isOk and pk[] == pubKey
func checkUselessPeer(peer: Peer) {.raises: [UselessPeerError, Defect].} = func checkUselessPeer(peer: Peer) {.raises: [UselessPeerError].} =
if peer.dispatcher.numProtocols == 0: if peer.dispatcher.numProtocols == 0:
# XXX: Send disconnect + UselessPeer # XXX: Send disconnect + UselessPeer
raise newException(UselessPeerError, "Useless peer") raise newException(UselessPeerError, "Useless peer")
proc initPeerState*(peer: Peer, capabilities: openArray[Capability]) proc initPeerState*(peer: Peer, capabilities: openArray[Capability])
{.raises: [UselessPeerError, Defect].} = {.raises: [UselessPeerError].} =
peer.dispatcher = getDispatcher(peer.network, capabilities) peer.dispatcher = getDispatcher(peer.network, capabilities)
checkUselessPeer(peer) checkUselessPeer(peer)

View File

@ -1,6 +1,6 @@
# #
# Ethereum P2P # Ethereum P2P
# (c) Copyright 2018 # (c) Copyright 2018-2023
# Status Research & Development GmbH # Status Research & Development GmbH
# #
# Licensed under either of # Licensed under either of
@ -10,7 +10,7 @@
## This module implements RLPx cryptography ## This module implements RLPx cryptography
{.push raises: [Defect].} {.push raises: [].}
import import
nimcrypto/[bcmode, keccak, rijndael, utils], stew/results nimcrypto/[bcmode, keccak, rijndael, utils], stew/results

View File

@ -1,4 +1,12 @@
{.push raises: [Defect].} # nim-eth
# Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * 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: [].}
import import
std/[options, tables, hashes, sets], std/[options, tables, hashes, sets],
@ -15,17 +23,17 @@ type
# XXX: poor's man vtref types # XXX: poor's man vtref types
PutProc = proc (db: RootRef, key, val: openArray[byte]) {. PutProc = proc (db: RootRef, key, val: openArray[byte]) {.
gcsafe, raises: [Defect].} gcsafe, raises: [].}
GetProc = proc (db: RootRef, key: openArray[byte]): seq[byte] {. GetProc = proc (db: RootRef, key: openArray[byte]): seq[byte] {.
gcsafe, raises: [Defect].} gcsafe, raises: [].}
## The result will be empty seq if not found ## The result will be empty seq if not found
DelProc = proc (db: RootRef, key: openArray[byte]): bool {. DelProc = proc (db: RootRef, key: openArray[byte]): bool {.
gcsafe, raises: [Defect].} gcsafe, raises: [].}
ContainsProc = proc (db: RootRef, key: openArray[byte]): bool {. ContainsProc = proc (db: RootRef, key: openArray[byte]): bool {.
gcsafe, raises: [Defect].} gcsafe, raises: [].}
TrieDatabaseRef* = ref object TrieDatabaseRef* = ref object
obj: RootRef obj: RootRef

View File

@ -1,3 +1,10 @@
# nim-eth
# Copyright (c) 2018-2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * 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.
import import
std/[options, tables], std/[options, tables],
nimcrypto/[keccak, hash], nimcrypto/[keccak, hash],
@ -37,14 +44,14 @@ type MissingNodeError* = ref object of AssertionDefect
nodeHashBytes*: seq[byte] nodeHashBytes*: seq[byte]
proc dbGet(db: DB, data: openArray[byte]): seq[byte] proc dbGet(db: DB, data: openArray[byte]): seq[byte]
{.gcsafe, raises: [Defect].} = {.gcsafe, raises: [].} =
db.get(data) db.get(data)
proc dbGet(db: DB, key: Rlp): seq[byte] = proc dbGet(db: DB, key: Rlp): seq[byte] =
dbGet(db, key.expectHash) dbGet(db, key.expectHash)
proc dbPut(db: DB, data: openArray[byte]): TrieNodeKey proc dbPut(db: DB, data: openArray[byte]): TrieNodeKey
{.gcsafe, raises: [Defect].} {.gcsafe, raises: [].}
# For stateless mode, it's possible for nodes to be missing from the DB, # For stateless mode, it's possible for nodes to be missing from the DB,
# and we need the higher-level code to be able to find out the *path* to # and we need the higher-level code to be able to find out the *path* to
@ -52,7 +59,7 @@ proc dbPut(db: DB, data: openArray[byte]): TrieNodeKey
# node is missing we'll raise an exception to get that information up to # node is missing we'll raise an exception to get that information up to
# where it's needed. # where it's needed.
proc getPossiblyMissingNode(db: DB, data: openArray[byte], fullPath: NibblesSeq, pathIndex: int, errorIfMissing: bool): seq[byte] proc getPossiblyMissingNode(db: DB, data: openArray[byte], fullPath: NibblesSeq, pathIndex: int, errorIfMissing: bool): seq[byte]
{.gcsafe, raises: [Defect].} = {.gcsafe, raises: [].} =
let nodeBytes = db.get(data) # need to call this before the call to contains, otherwise CaptureDB complains let nodeBytes = db.get(data) # need to call this before the call to contains, otherwise CaptureDB complains
if nodeBytes.len > 0 or not errorIfMissing: if nodeBytes.len > 0 or not errorIfMissing:
nodeBytes nodeBytes
@ -76,7 +83,7 @@ template initSecureHexaryTrie*(db: DB, rootHash: KeccakHash, isPruning = true, s
SecureHexaryTrie initHexaryTrie(db, rootHash, isPruning, shouldMissingNodesBeErrors) SecureHexaryTrie initHexaryTrie(db, rootHash, isPruning, shouldMissingNodesBeErrors)
proc initHexaryTrie*(db: DB, isPruning = true, shouldMissingNodesBeErrors = false): HexaryTrie proc initHexaryTrie*(db: DB, isPruning = true, shouldMissingNodesBeErrors = false): HexaryTrie
{.raises: [Defect].} = {.raises: [].} =
result.db = db result.db = db
result.root = result.db.dbPut(emptyRlp) result.root = result.db.dbPut(emptyRlp)
result.isPruning = isPruning result.isPruning = isPruning
@ -115,7 +122,7 @@ proc getLookup(db: DB, elem: Rlp, fullPath: NibblesSeq, pathIndex: int, errorIfM
else: rlpFromBytes(getPossiblyMissingNode(db, elem.expectHash, fullPath, pathIndex, errorIfMissing)) else: rlpFromBytes(getPossiblyMissingNode(db, elem.expectHash, fullPath, pathIndex, errorIfMissing))
proc getAux(db: DB, nodeRlp: Rlp, fullPath: NibblesSeq, pathIndex: int, errorIfMissing: bool): seq[byte] proc getAux(db: DB, nodeRlp: Rlp, fullPath: NibblesSeq, pathIndex: int, errorIfMissing: bool): seq[byte]
{.gcsafe, raises: [RlpError, Defect].} = {.gcsafe, raises: [RlpError].} =
if not nodeRlp.hasData or nodeRlp.isEmpty: if not nodeRlp.hasData or nodeRlp.isEmpty:
return return
@ -377,7 +384,7 @@ proc dbDel(t: var HexaryTrie, data: openArray[byte]) =
if data.len >= 32: t.prune(data.keccakHash.data) if data.len >= 32: t.prune(data.keccakHash.data)
proc dbPut(db: DB, data: openArray[byte]): TrieNodeKey proc dbPut(db: DB, data: openArray[byte]): TrieNodeKey
{.raises: [Defect].} = {.raises: [].} =
result.hash = data.keccakHash result.hash = data.keccakHash
result.usedBytes = 32 result.usedBytes = 32
put(db, result.asDbKey, data) put(db, result.asDbKey, data)
@ -439,7 +446,7 @@ proc deleteAt(self: var HexaryTrie;
origRlp: Rlp, origRlp: Rlp,
fullPath: NibblesSeq, fullPath: NibblesSeq,
pathIndex: int): seq[byte] pathIndex: int): seq[byte]
{.gcsafe, raises: [RlpError, Defect].} {.gcsafe, raises: [RlpError].}
proc deleteAux(self: var HexaryTrie; proc deleteAux(self: var HexaryTrie;
rlpWriter: var RlpWriter; rlpWriter: var RlpWriter;
@ -498,7 +505,7 @@ proc mergeAndGraft(self: var HexaryTrie;
# If the key is present, returns the RLP bytes for a node that # If the key is present, returns the RLP bytes for a node that
# omits this key. Returns an empty seq if the key is absent. # omits this key. Returns an empty seq if the key is absent.
proc deleteAt(self: var HexaryTrie; origRlp: Rlp, fullPath: NibblesSeq, pathIndex: int): seq[byte] proc deleteAt(self: var HexaryTrie; origRlp: Rlp, fullPath: NibblesSeq, pathIndex: int): seq[byte]
{.gcsafe, raises: [RlpError, Defect].} = {.gcsafe, raises: [RlpError].} =
if origRlp.isEmpty: if origRlp.isEmpty:
# It's empty RLP, so the key is absent, so no change necessary. # It's empty RLP, so the key is absent, so no change necessary.
return return
@ -592,7 +599,7 @@ proc del*(self: var HexaryTrie; key: openArray[byte]) =
proc mergeAt(self: var HexaryTrie, orig: Rlp, origHash: KeccakHash, proc mergeAt(self: var HexaryTrie, orig: Rlp, origHash: KeccakHash,
fullPath: NibblesSeq, pathIndex: int, value: openArray[byte], fullPath: NibblesSeq, pathIndex: int, value: openArray[byte],
isInline = false): seq[byte] isInline = false): seq[byte]
{.gcsafe, raises: [RlpError, Defect].} {.gcsafe, raises: [RlpError].}
proc mergeAt(self: var HexaryTrie, rlp: Rlp, proc mergeAt(self: var HexaryTrie, rlp: Rlp,
fullPath: NibblesSeq, pathIndex: int, value: openArray[byte], fullPath: NibblesSeq, pathIndex: int, value: openArray[byte],
@ -613,7 +620,7 @@ proc mergeAtAux(self: var HexaryTrie, output: var RlpWriter, orig: Rlp,
proc mergeAt(self: var HexaryTrie, orig: Rlp, origHash: KeccakHash, proc mergeAt(self: var HexaryTrie, orig: Rlp, origHash: KeccakHash,
fullPath: NibblesSeq, pathIndex: int, value: openArray[byte], fullPath: NibblesSeq, pathIndex: int, value: openArray[byte],
isInline = false): seq[byte] isInline = false): seq[byte]
{.gcsafe, raises: [RlpError, Defect].} = {.gcsafe, raises: [RlpError].} =
let path = fullPath.slice(pathIndex) let path = fullPath.slice(pathIndex)
template origWithNewValue: auto = template origWithNewValue: auto =
self.prune(origHash.data) self.prune(origHash.data)
@ -771,7 +778,7 @@ proc maybeGetLookup(db: DB, elem: Rlp): Option[Rlp] =
some(rlpFromBytes(bytes)) some(rlpFromBytes(bytes))
proc maybeGetAux(db: DB, nodeRlp: Rlp, fullPath: NibblesSeq, pathIndex: int): Option[seq[byte]] proc maybeGetAux(db: DB, nodeRlp: Rlp, fullPath: NibblesSeq, pathIndex: int): Option[seq[byte]]
{.gcsafe, raises: [RlpError, Defect].} = {.gcsafe, raises: [RlpError].} =
# FIXME-Adam: do I need to distinguish between these two cases? # FIXME-Adam: do I need to distinguish between these two cases?
if not nodeRlp.hasData: if not nodeRlp.hasData:
let zero: seq[byte] = @[] let zero: seq[byte] = @[]

View File

@ -1,11 +1,11 @@
# proof verification # proof verification
# Copyright (c) 2022 Status Research & Development GmbH # Copyright (c) 2022-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, options, sequtils], std/[tables, options, sequtils],

View File

@ -1,10 +1,10 @@
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
chronos chronos

View File

@ -1,10 +1,10 @@
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
chronos, chronos,

View File

@ -1,21 +1,23 @@
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import import
std/[options, math] std/[options, math]
export options export options
# Buffer implementation similar to the one in in reference implementation. # Buffer implementation similar to the one in the reference implementation.
# Main rationale for it, is to refer to items in buffer by their sequence number, # Main rationale for it is to refer to items in buffer by their sequence number
# and support out of order packets. # and to support out of order packets.
# Therefore it is super specific data structure, and it mostly usefully for # Therefore it is a super specific data structure, and it mostly usefully for
# utp implementation. # the uTP implementation.
# Another alternative would be to use standard deque from deques module, and calculate # An alternative could be to use standard deque from deques module, and
# item indexes from their sequence numbers. # calculate item indexes from their sequence numbers.
type type
GrowableCircularBuffer*[A] = object GrowableCircularBuffer*[A] = object
items: seq[Option[A]] items: seq[Option[A]]
@ -44,7 +46,9 @@ 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, check: proc (x: A): bool): bool = proc exists*[A](
buff: GrowableCircularBuffer[A], i: uint32,
check: proc (x: A): bool {.gcsafe, raises: [].}): bool =
let maybeElem = buff.get(i) let maybeElem = buff.get(i)
if (maybeElem.isSome()): if (maybeElem.isSome()):
let elem = maybeElem.unsafeGet() let elem = maybeElem.unsafeGet()
@ -53,8 +57,8 @@ proc exists*[A](buff: GrowableCircularBuffer[A], i: uint32, check: proc (x: A):
false false
proc `[]`*[A](buff: var GrowableCircularBuffer[A], i: uint32): var A = proc `[]`*[A](buff: var GrowableCircularBuffer[A], i: uint32): var A =
## Returns contents of the `var GrowableCircularBuffer`. If it is not set, then an exception ## Returns contents of the `var GrowableCircularBuffer`. If it is not set,
## is thrown. ## then an exception is thrown.
buff.items[i and buff.mask].get() buff.items[i and buff.mask].get()
proc len*[A](buff: GrowableCircularBuffer[A]): int = proc len*[A](buff: GrowableCircularBuffer[A]): int =
@ -74,7 +78,8 @@ proc calculateNextMask(currentMask: uint32, index:uint32): uint32 =
# Item contains the element we want to make space for # Item contains the element we want to make space for
# index is the index in the list. # index is the index in the list.
proc ensureSize*[A](buff: var GrowableCircularBuffer[A], item: uint32, index: uint32) = proc ensureSize*[A](
buff: var GrowableCircularBuffer[A], item: uint32, index: uint32) =
if (index > buff.mask): if (index > buff.mask):
let newMask = calculateNextMask(buff.mask, index) let newMask = calculateNextMask(buff.mask, index)
var newSeq = newSeq[Option[A]](int(newMask) + 1) var newSeq = newSeq[Option[A]](int(newMask) + 1)

View File

@ -1,10 +1,10 @@
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
chronos, chronos,

View File

@ -7,7 +7,7 @@
# uTP packet format as specified in: # uTP packet format as specified in:
# https://www.bittorrent.org/beps/bep_0029.html # https://www.bittorrent.org/beps/bep_0029.html
{.push raises: [Defect].} {.push raises: [].}
import import
faststreams, faststreams,

View File

@ -1,10 +1,10 @@
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
chronos, stew/[results, byteutils], chronos, stew/[results, byteutils],
@ -12,8 +12,9 @@ import
./utp_socket, ./utp_socket,
./utp_protocol ./utp_protocol
# Exemple application to interact with reference implementation server to help with implementation # Example application to interact with the reference implementation server
# To run lib utp server: # to be able to test against the reference implementation.
# To run libutp server:
# 1. git clone https://github.com/bittorrent/libutp.git # 1. git clone https://github.com/bittorrent/libutp.git
# 2. cd libutp # 2. cd libutp
# 3. make # 3. make
@ -21,7 +22,9 @@ import
when isMainModule: when isMainModule:
proc echoIncomingSocketCallBack(): AcceptConnectionCallback[TransportAddress] = proc echoIncomingSocketCallBack(): AcceptConnectionCallback[TransportAddress] =
return ( return (
proc (server: UtpRouter[TransportAddress], client: UtpSocket[TransportAddress]): Future[void] {.gcsafe, raises: [Defect].} = proc (server: UtpRouter[TransportAddress],
client: UtpSocket[TransportAddress]):
Future[void] {.gcsafe, raises: [].} =
echo "received incoming connection" echo "received incoming connection"
let fakeFuture = newFuture[void]() let fakeFuture = newFuture[void]()
fakeFuture.complete() fakeFuture.complete()

View File

@ -1,10 +1,10 @@
# Copyright (c) 2021-2022 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[hashes, sugar], std/[hashes, sugar],

View File

@ -1,10 +1,10 @@
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, options, hashes, math], std/[tables, options, hashes, math],
@ -23,7 +23,9 @@ type
transport: DatagramTransport transport: DatagramTransport
utpRouter: UtpRouter[TransportAddress] utpRouter: UtpRouter[TransportAddress]
SendCallbackBuilder* = proc (d: DatagramTransport): SendCallback[TransportAddress] {.gcsafe, raises: [Defect].} SendCallbackBuilder* =
proc (d: DatagramTransport):
SendCallback[TransportAddress] {.gcsafe, raises: [].}
# This should probably be defined in TransportAddress module, as hash function should # This should probably be defined in TransportAddress module, as hash function should
# be consistent with equality function # be consistent with equality function
@ -82,7 +84,7 @@ proc new*(
socketConfig: SocketConfig = SocketConfig.init(), socketConfig: SocketConfig = SocketConfig.init(),
allowConnectionCb: AllowConnectionCallback[TransportAddress] = nil, allowConnectionCb: AllowConnectionCallback[TransportAddress] = nil,
sendCallbackBuilder: SendCallbackBuilder = nil, sendCallbackBuilder: SendCallbackBuilder = nil,
rng = newRng()): UtpProtocol {.raises: [Defect, CatchableError].} = rng = newRng()): UtpProtocol {.raises: [CatchableError].} =
doAssert(not(isNil(acceptConnectionCb))) doAssert(not(isNil(acceptConnectionCb)))
@ -111,7 +113,7 @@ proc new*(
socketConfig: SocketConfig = SocketConfig.init(), socketConfig: SocketConfig = SocketConfig.init(),
allowConnectionCb: AllowConnectionCallback[TransportAddress] = nil, allowConnectionCb: AllowConnectionCallback[TransportAddress] = nil,
sendCallbackBuilder: SendCallbackBuilder = nil, sendCallbackBuilder: SendCallbackBuilder = nil,
rng = newRng()): UtpProtocol {.raises: [Defect, CatchableError].} = rng = newRng()): UtpProtocol {.raises: [CatchableError].} =
GC_ref(udata) GC_ref(udata)
UtpProtocol.new( UtpProtocol.new(
acceptConnectionCb, acceptConnectionCb,

View File

@ -4,7 +4,7 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[tables, options, sugar], std/[tables, options, sugar],
@ -38,12 +38,12 @@ type
# ``server`` - UtpProtocol object. # ``server`` - UtpProtocol object.
# ``client`` - accepted client utp socket. # ``client`` - accepted client utp socket.
AcceptConnectionCallback*[A] = proc(server: UtpRouter[A], AcceptConnectionCallback*[A] = proc(server: UtpRouter[A],
client: UtpSocket[A]): Future[void] {.gcsafe, raises: [Defect].} client: UtpSocket[A]): Future[void] {.gcsafe, raises: [].}
# Callback to act as firewall for incoming peers. Should return true if peer # Callback to act as firewall for incoming peers. Should return true if peer
# is allowed to connect. # is allowed to connect.
AllowConnectionCallback*[A] = proc(r: UtpRouter[A], remoteAddress: A, AllowConnectionCallback*[A] = proc(r: UtpRouter[A], remoteAddress: A,
connectionId: uint16): bool {.gcsafe, raises: [Defect], noSideEffect.} connectionId: uint16): bool {.gcsafe, raises: [], noSideEffect.}
# Object responsible for creating and maintaining table of utp sockets. # Object responsible for creating and maintaining table of utp sockets.
# Caller should use `processIncomingBytes` proc to feed it with incoming byte # Caller should use `processIncomingBytes` proc to feed it with incoming byte

View File

@ -4,7 +4,7 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
std/[sugar, deques], std/[sugar, deques],
@ -49,7 +49,7 @@ type
# Socket callback to send data to remote peer # Socket callback to send data to remote peer
SendCallback*[A] = SendCallback*[A] =
proc (to: A, data: seq[byte]): Future[void] {.gcsafe, raises: [Defect]} proc (to: A, data: seq[byte]): Future[void] {.gcsafe, raises: []}
SocketConfig* = object SocketConfig* = object
# This is configurable (in contrast to reference impl), as with standard 2 # This is configurable (in contrast to reference impl), as with standard 2
@ -297,7 +297,7 @@ type
# User driven call back to be called whenever socket is permanently closed i.e # User driven call back to be called whenever socket is permanently closed i.e
# reaches destroy state # reaches destroy state
SocketCloseCallback* = proc (): void {.gcsafe, raises: [Defect].} SocketCloseCallback* = proc (): void {.gcsafe, raises: [].}
ConnectionError* = object of CatchableError ConnectionError* = object of CatchableError

View File

@ -1,10 +1,10 @@
# Copyright (c) 2021 Status Research & Development GmbH # Copyright (c) 2021-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].} {.push raises: [].}
import import
chronos chronos

View File

@ -793,7 +793,7 @@ suite "Discovery v5 Tests":
proc handler( proc handler(
protocol: TalkProtocol, request: seq[byte], protocol: TalkProtocol, request: seq[byte],
fromId: NodeId, fromUdpAddress: Address): fromId: NodeId, fromUdpAddress: Address):
seq[byte] {.gcsafe, raises: [Defect].} = seq[byte] {.gcsafe, raises: [].} =
request request
let echoProtocol = TalkProtocol(protocolHandler: handler) let echoProtocol = TalkProtocol(protocolHandler: handler)
@ -820,7 +820,7 @@ suite "Discovery v5 Tests":
proc handler( proc handler(
protocol: TalkProtocol, request: seq[byte], protocol: TalkProtocol, request: seq[byte],
fromId: NodeId, fromUdpAddress: Address): fromId: NodeId, fromUdpAddress: Address):
seq[byte] {.gcsafe, raises: [Defect].} = seq[byte] {.gcsafe, raises: [].} =
request request
let echoProtocol = TalkProtocol(protocolHandler: handler) let echoProtocol = TalkProtocol(protocolHandler: handler)
@ -844,7 +844,7 @@ suite "Discovery v5 Tests":
proc handler( proc handler(
protocol: TalkProtocol, request: seq[byte], protocol: TalkProtocol, request: seq[byte],
fromId: NodeId, fromUdpAddress: Address): fromId: NodeId, fromUdpAddress: Address):
seq[byte] {.gcsafe, raises: [Defect].} = seq[byte] {.gcsafe, raises: [].} =
request request
let echoProtocol = TalkProtocol(protocolHandler: handler) let echoProtocol = TalkProtocol(protocolHandler: handler)
@ -883,7 +883,7 @@ suite "Discovery v5 Tests":
proc handler( proc handler(
protocol: TalkProtocol, request: seq[byte], protocol: TalkProtocol, request: seq[byte],
fromId: NodeId, fromUdpAddress: Address): fromId: NodeId, fromUdpAddress: Address):
seq[byte] {.gcsafe, raises: [Defect].} = seq[byte] {.gcsafe, raises: [].} =
# Return the request + same protocol id + 2 bytes, to make it 1 byte # Return the request + same protocol id + 2 bytes, to make it 1 byte
# bigger than the request # bigger than the request
request & "echo12".toBytes() request & "echo12".toBytes()

View File

@ -58,7 +58,7 @@ suite "branches utils":
discard getBranch(db, trie.getRootHash(), key) discard getBranch(db, trie.getRootHash(), key)
except InvalidKeyError: except InvalidKeyError:
check(true) check(true)
except: except CatchableError:
check(false) check(false)
const trieNodesData = [ const trieNodesData = [

View File

@ -1,5 +1,5 @@
# proof verification # proof verification
# Copyright (c) 2022 Status Research & Development GmbH # Copyright (c) 2022-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -7,7 +7,7 @@
{.used.} {.used.}
{.push raises: [Defect].} {.push raises: [].}
import import
unittest2, unittest2,

View File

@ -1,4 +1,4 @@
# Copyright (c) 2020-2021 Status Research & Development GmbH # Copyright (c) 2020-2023 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -67,17 +67,17 @@ suite "Utp ring buffer":
let textIdx = 11'u32 let textIdx = 11'u32
check: check:
not buff.exists(textIdx, x => x.foo == text) not buff.exists(textIdx, x {.gcsafe, raises: [].} => x.foo == text)
buff.put(textIdx, TestObj(foo: "old")) buff.put(textIdx, TestObj(foo: "old"))
check: check:
not buff.exists(textIdx, x => x.foo == text) not buff.exists(textIdx, x {.gcsafe, raises: [].} => x.foo == text)
buff[textIdx].foo = text buff[textIdx].foo = text
check: check:
buff.exists(textIdx, x => x.foo == text) buff.exists(textIdx, x {.gcsafe, raises: [].} => x.foo == text)
test "Deleting elements from buffer": test "Deleting elements from buffer":
var buff = GrowableCircularBuffer[int].init(size = 4) var buff = GrowableCircularBuffer[int].init(size = 4)
@ -144,7 +144,7 @@ suite "Utp ring buffer":
buff.ensureSize(0, 1) buff.ensureSize(0, 1)
buff.put(0, 0) buff.put(0, 0)
# index 2 will not fit in buffer of size 2 so it will need to be expanded to 4 # index 2 will not fit in buffer of size 2 so it needs to be expanded to 4
buff.ensureSize(1, 2) buff.ensureSize(1, 2)
buff.put(1, 1) buff.put(1, 1)

View File

@ -4,7 +4,7 @@ import
../../eth/utp/packets, ../../eth/utp/packets,
../../eth/keys ../../eth/keys
type AssertionCallback = proc(): bool {.gcsafe, raises: [Defect].} type AssertionCallback = proc(): bool {.gcsafe, raises: [].}
let testBufferSize* = 1024'u32 let testBufferSize* = 1024'u32
let defaultRcvOutgoingId = 314'u16 let defaultRcvOutgoingId = 314'u16