More raises cleanup (#575)

* use toException to map errors

* don't initialize address twice

* better error messages

* allow LPError to escape

* allow LPError to escape
This commit is contained in:
Dmitriy Ryajov 2021-05-22 12:27:30 -06:00 committed by GitHub
parent ac4e060e1a
commit 24132d7129
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 27 deletions

View File

@ -50,7 +50,7 @@ proc new*(T: type[SwitchBuilder]): T =
let address = MultiAddress let address = MultiAddress
.init("/ip4/127.0.0.1/tcp/0") .init("/ip4/127.0.0.1/tcp/0")
.expect("address should initialize to default") .expect("Should initialize to default")
SwitchBuilder( SwitchBuilder(
privKey: none(PrivateKey), privKey: none(PrivateKey),
@ -123,13 +123,15 @@ proc withAgentVersion*(b: SwitchBuilder, agentVersion: string): SwitchBuilder =
b.agentVersion = agentVersion b.agentVersion = agentVersion
b b
proc build*(b: SwitchBuilder): Switch = proc build*(b: SwitchBuilder): Switch
{.raises: [Defect, LPError].} =
if b.rng == nil: # newRng could fail if b.rng == nil: # newRng could fail
raise newException(Defect, "Cannot initialize RNG") raise newException(Defect, "Cannot initialize RNG")
let pkRes = PrivateKey.random(b.rng[]) let pkRes = PrivateKey.random(b.rng[])
let let
seckey = b.privKey.get(otherwise = pkRes.expect("Should supply a valid RNG")) seckey = b.privKey.get(otherwise = pkRes.expect("Expected default Private Key"))
var var
secureManagerInstances: seq[Secure] secureManagerInstances: seq[Secure]
@ -183,7 +185,7 @@ proc build*(b: SwitchBuilder): Switch =
return switch return switch
proc newStandardSwitch*(privKey = none(PrivateKey), proc newStandardSwitch*(privKey = none(PrivateKey),
address = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(), address = MultiAddress.init("/ip4/127.0.0.1/tcp/0"),
secureManagers: openarray[SecureProtocol] = [ secureManagers: openarray[SecureProtocol] = [
SecureProtocol.Noise, SecureProtocol.Noise,
], ],
@ -194,13 +196,14 @@ proc newStandardSwitch*(privKey = none(PrivateKey),
maxConnections = MaxConnections, maxConnections = MaxConnections,
maxIn = -1, maxIn = -1,
maxOut = -1, maxOut = -1,
maxConnsPerPeer = MaxConnectionsPerPeer): Switch = maxConnsPerPeer = MaxConnectionsPerPeer): Switch
{.raises: [Defect, LPError].} =
if SecureProtocol.Secio in secureManagers: if SecureProtocol.Secio in secureManagers:
quit("Secio is deprecated!") # use of secio is unsafe quit("Secio is deprecated!") # use of secio is unsafe
var b = SwitchBuilder var b = SwitchBuilder
.new() .new()
.withAddress(address) .withAddress(address.expect("Should have been initialized with default"))
.withRng(rng) .withRng(rng)
.withMaxConnections(maxConnections) .withMaxConnections(maxConnections)
.withMaxIn(maxIn) .withMaxIn(maxIn)

View File

@ -11,12 +11,13 @@
## This module implementes API for `go-libp2p-daemon`. ## This module implementes API for `go-libp2p-daemon`.
import std/[os, osproc, strutils, tables, strtabs] import std/[os, osproc, strutils, tables, strtabs]
import chronos, chronicles import pkg/[chronos, chronicles]
import ../varint, ../multiaddress, ../multicodec, ../cid, ../peerid import ../varint, ../multiaddress, ../multicodec, ../cid, ../peerid
import ../wire, ../multihash, ../protobuf/minprotobuf import ../wire, ../multihash, ../protobuf/minprotobuf
import ../crypto/crypto import ../crypto/crypto
export peerid, multiaddress, multicodec, multihash, cid, crypto, wire export
peerid, multiaddress, multicodec, multihash, cid, crypto, wire
when not defined(windows): when not defined(windows):
import posix import posix
@ -154,6 +155,9 @@ type
ticket: PubsubTicket, ticket: PubsubTicket,
message: PubSubMessage): Future[bool] {.gcsafe.} message: PubSubMessage): Future[bool] {.gcsafe.}
# TODO: would be nice to be able to map other errors to
# this types with `Result.toException`, but it doesn't work
# in this module
DaemonRemoteError* = object of CatchableError DaemonRemoteError* = object of CatchableError
DaemonLocalError* = object of CatchableError DaemonLocalError* = object of CatchableError
@ -833,15 +837,19 @@ proc getPeerInfo(pb: var ProtoBuffer): PeerInfo
result.addresses = newSeq[MultiAddress]() result.addresses = newSeq[MultiAddress]()
if pb.getValue(1, result.peer) == -1: if pb.getValue(1, result.peer) == -1:
raise newException(DaemonLocalError, "Missing required field `peer`!") raise newException(DaemonLocalError, "Missing required field `peer`!")
var address = newSeq[byte]() var address = newSeq[byte]()
while pb.getBytes(2, address) != -1: while pb.getBytes(2, address) != -1:
if len(address) != 0: if len(address) != 0:
var copyaddr = address var copyaddr = address
let addrRes = MultiAddress.init(copyaddr) let addrRes = MultiAddress.init(copyaddr)
# TODO: for some reason `toException` doesn't
# work for this module
if addrRes.isErr: if addrRes.isErr:
raise newException(DaemonLocalError, addrRes.error) raise newException(DaemonLocalError, addrRes.error)
result.addresses.add(MultiAddress.init(copyaddr).get()) result.addresses.add(addrRes.get())
address.setLen(0) address.setLen(0)
proc identity*(api: DaemonAPI): Future[PeerInfo] {.async.} = proc identity*(api: DaemonAPI): Future[PeerInfo] {.async.} =

View File

@ -9,11 +9,11 @@
{.push raises: [Defect].} {.push raises: [Defect].}
import options, sequtils, hashes import std/[options, sequtils, hashes]
import chronos, chronicles import pkg/[chronos, chronicles, stew/results]
import peerid, multiaddress, crypto/crypto import peerid, multiaddress, crypto/crypto, errors
export peerid, multiaddress, crypto export peerid, multiaddress, crypto, errors, results
## A peer can be constructed in one of tree ways: ## A peer can be constructed in one of tree ways:
## 1) A local peer with a private key ## 1) A local peer with a private key
@ -28,6 +28,8 @@ type
HasPrivate, HasPrivate,
HasPublic HasPublic
PeerInfoError* = LPError
PeerInfo* = ref object of RootObj PeerInfo* = ref object of RootObj
peerId*: PeerID peerId*: PeerID
addrs*: seq[MultiAddress] addrs*: seq[MultiAddress]
@ -51,6 +53,12 @@ func shortLog*(p: PeerInfo): auto =
) )
chronicles.formatIt(PeerInfo): shortLog(it) chronicles.formatIt(PeerInfo): shortLog(it)
func toException*(e: string): ref PeerInfoError =
(ref PeerInfoError)(msg: e)
func toException*(e: cstring): ref PeerInfoError =
(ref PeerInfoError)(msg: $e)
template postInit(peerinfo: PeerInfo, template postInit(peerinfo: PeerInfo,
addrs: openarray[MultiAddress], addrs: openarray[MultiAddress],
protocols: openarray[string]) = protocols: openarray[string]) =
@ -65,10 +73,12 @@ proc init*(
addrs: openarray[MultiAddress] = [], addrs: openarray[MultiAddress] = [],
protocols: openarray[string] = [], protocols: openarray[string] = [],
protoVersion: string = "", protoVersion: string = "",
agentVersion: string = ""): PeerInfo = agentVersion: string = ""): PeerInfo
{.raises: [Defect, PeerInfoError].} =
let peerInfo = PeerInfo( let peerInfo = PeerInfo(
keyType: HasPrivate, keyType: HasPrivate,
peerId: PeerID.init(key).expect("Unable to create peer id from key"), peerId: PeerID.init(key).tryGet(),
privateKey: key, privateKey: key,
protoVersion: protoVersion, protoVersion: protoVersion,
agentVersion: agentVersion) agentVersion: agentVersion)
@ -98,11 +108,12 @@ proc init*(
addrs: openarray[MultiAddress] = [], addrs: openarray[MultiAddress] = [],
protocols: openarray[string] = [], protocols: openarray[string] = [],
protoVersion: string = "", protoVersion: string = "",
agentVersion: string = ""): PeerInfo = agentVersion: string = ""): PeerInfo
{.raises: [Defect, PeerInfoError].} =
let peerInfo = PeerInfo( let peerInfo = PeerInfo(
keyType: HasPublic, keyType: HasPublic,
peerId: PeerID.init(peerId).expect("Unable to create peer id from string"), peerId: PeerID.init(peerId).tryGet(),
protoVersion: protoVersion, protoVersion: protoVersion,
agentVersion: agentVersion) agentVersion: agentVersion)
@ -115,11 +126,12 @@ proc init*(
addrs: openarray[MultiAddress] = [], addrs: openarray[MultiAddress] = [],
protocols: openarray[string] = [], protocols: openarray[string] = [],
protoVersion: string = "", protoVersion: string = "",
agentVersion: string = ""): PeerInfo = agentVersion: string = ""): PeerInfo
{.raises: [Defect, PeerInfoError].} =
let peerInfo = PeerInfo( let peerInfo = PeerInfo(
keyType: HasPublic, keyType: HasPublic,
peerId: PeerID.init(key).expect("Unable to create peer id from public key"), peerId: PeerID.init(key).tryGet(),
key: some(key), key: some(key),
protoVersion: protoVersion, protoVersion: protoVersion,
agentVersion: agentVersion) agentVersion: agentVersion)

View File

@ -189,7 +189,7 @@ proc mixKey(ss: var SymmetricState, ikm: ChaChaPolyKey) =
ss.cs = CipherState(k: temp_keys[1]) ss.cs = CipherState(k: temp_keys[1])
trace "mixKey", key = ss.cs.k.shortLog trace "mixKey", key = ss.cs.k.shortLog
proc mixHash(ss: var SymmetricState; data: openArray[byte]) = proc mixHash(ss: var SymmetricState, data: openArray[byte]) =
var ctx: sha256 var ctx: sha256
ctx.init() ctx.init()
ctx.update(ss.h.data) ctx.update(ss.h.data)
@ -198,7 +198,7 @@ proc mixHash(ss: var SymmetricState; data: openArray[byte]) =
trace "mixHash", hash = ss.h.data.shortLog trace "mixHash", hash = ss.h.data.shortLog
# We might use this for other handshake patterns/tokens # We might use this for other handshake patterns/tokens
proc mixKeyAndHash(ss: var SymmetricState; ikm: openArray[byte]) {.used.} = proc mixKeyAndHash(ss: var SymmetricState, ikm: openArray[byte]) {.used.} =
var var
temp_keys: array[3, ChaChaPolyKey] temp_keys: array[3, ChaChaPolyKey]
sha256.hkdf(ss.ck, ikm, [], temp_keys) sha256.hkdf(ss.ck, ikm, [], temp_keys)
@ -597,14 +597,16 @@ method init*(p: Noise) {.gcsafe.} =
proc newNoise*( proc newNoise*(
rng: ref BrHmacDrbgContext, rng: ref BrHmacDrbgContext,
privateKey: PrivateKey; privateKey: PrivateKey,
outgoing: bool = true; outgoing: bool = true,
commonPrologue: seq[byte] = @[]): Noise = commonPrologue: seq[byte] = @[]): Noise =
let pkBytes = privateKey.getKey() let pkBytes = privateKey
.expect("Expected valid private key") .getKey()
.expect("Expected valid Private Key")
.getBytes() .getBytes()
.expect("Couldn't get key bytes") .expect("Couldn't get Private Key bytes")
var noise = Noise( var noise = Noise(
rng: rng, rng: rng,
outgoing: outgoing, outgoing: outgoing,

View File

@ -259,7 +259,7 @@ proc newSecioConn(conn: Connection,
secrets: Secret, secrets: Secret,
order: int, order: int,
remotePubKey: PublicKey): SecioConn remotePubKey: PublicKey): SecioConn
{.raises: [Defect, SecioError].} = {.raises: [Defect, LPError].} =
## Create new secure stream/lpstream, using specified hash algorithm ``hash``, ## Create new secure stream/lpstream, using specified hash algorithm ``hash``,
## cipher algorithm ``cipher``, stretched keys ``secrets`` and order ## cipher algorithm ``cipher``, stretched keys ``secrets`` and order
## ``order``. ## ``order``.