diff --git a/libp2p/helpers/debug.nim b/libp2p/helpers/debug.nim deleted file mode 100644 index 06239b061..000000000 --- a/libp2p/helpers/debug.nim +++ /dev/null @@ -1,77 +0,0 @@ -## Nim-LibP2P -## Copyright (c) 2018 Status Research & Development GmbH -## Licensed under either of -## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) -## * MIT license ([LICENSE-MIT](LICENSE-MIT)) -## at your option. -## This file may not be copied, modified, or distributed except according to -## those terms. - -## Small debug module that's only runs in non release builds. -## It's inspired by the Nodejs ``debug`` module which allows printing -## colorized output based on matched patterns. This module is powered -## by the standard ``nre`` module and as such it supports the same set -## of regexp expressions. -## -## The output is controled through two environment variables ``DEBUG`` -## and ``DEBUG_COLOR``. By default, it will print everything to stderr -## but if only some output is of interested, ``DEBUG`` accepts a coma -## separated list of regexp expressions to match the output against. -## Each match gets assigned a different color to help differentiate -## the output lines. -## -## Colorization is done with 256 ANSI colors, and each run gets a random -## color, if more than one match is specified, each one gets a random color -## to disable this behavior use ``DEBUG_COLOR`` with a valid ANSI color code. -## This will also disable individual colorization for each matched line. -## - -when not defined(release): - import random, - tables, - nre, - strutils, - times, - terminal, - sequtils, - os - - type - Match = object - pattern: Regex - color: string - - # if isTrueColorSupported(): - # system.addQuitProc(resetAttributes) - # enableTrueColors() - - var context {.threadvar.} : OrderedTableRef[string, Match] - proc initDebugCtx() = - let debugout = getEnv("DEBUG", ".*") - let debugColor = getEnv("DEBUG_COLOR") - let isDebugColor = debugColor.len > 0 - context = newOrderedTable[string, Match]() - var patrns: seq[string] = @[] - patrns = debugout.split(re"[,\s]").filterIt(it.len > 0) - - randomize() - for p in patrns: - context[p] = Match(pattern: re(p), color: if isDebugColor: debugColor else: $rand(0..272)) # 256 ansi colors - - proc doDebug(data: string, line: string): void {.gcsafe.} = - if isNil(context): - initDebugCtx() - for m in context.values: - if data.contains(m.pattern): - stderr.writeLine("\u001b[38;5;" & m.color & "m " & alignLeft(line & data, 4) & "\e[0m") - return - - template debug*(data: string) = - let module = instantiationInfo() - let line = "$# $#:$# - " % - [now().format("yyyy-MM-dd HH:mm:ss:fffffffff"), - module.filename[0..^5], - $module.line] - doDebug(data, line) -else: - template debug*(data: string) = discard \ No newline at end of file diff --git a/libp2p/multistream.nim b/libp2p/multistream.nim index 3cfaf52ce..a0ca2f888 100644 --- a/libp2p/multistream.nim +++ b/libp2p/multistream.nim @@ -8,12 +8,11 @@ ## those terms. import sequtils, strutils, strformat -import chronos +import chronos, chronicles import connection, varint, vbuffer, - protocols/protocol, - helpers/debug + protocols/protocol const MsgSize* = 64*1024 const Codec* = "/multistream/1.0.0" @@ -46,37 +45,37 @@ proc select*(m: MultisteamSelect, conn: Connection, proto: seq[string]): Future[string] {.async.} = - debug &"select: initiating handshake" + debug "select: initiating handshake" ## select a remote protocol await conn.write(m.codec) # write handshake if proto.len() > 0: - debug &"select: selecting proto {proto}" + debug "select: selecting proto", proto = proto await conn.writeLp((proto[0] & "\n")) # select proto result = cast[string](await conn.readLp()) # read ms header result.removeSuffix("\n") if result != Codec: - debug &"select: handshake failed" + debug "select: handshake failed" return "" if proto.len() == 0: # no protocols, must be a handshake call return result = cast[string](await conn.readLp()) # read the first proto - debug &"select: reading first requested proto" + debug "select: reading first requested proto" result.removeSuffix("\n") if result == proto[0]: - debug &"select: succesfully selected {proto}" + debug "select: succesfully selected ", proto = proto return if not result.len > 0: - debug &"select: selecting one of several protos" + debug "select: selecting one of several protos" for p in proto[1.. 0.uint: - debug &"readMsg: read size varint {$dataLenVarint}" + debug "readMsg: read size varint ", varint = dataLenVarint data = await conn.read(dataLenVarint.get().int) let header = headerVarint.get() diff --git a/libp2p/muxers/mplex/mplex.nim b/libp2p/muxers/mplex/mplex.nim index 9c8f1d7d8..60662c0f8 100644 --- a/libp2p/muxers/mplex/mplex.nim +++ b/libp2p/muxers/mplex/mplex.nim @@ -17,16 +17,15 @@ ## here to not forget that this needs to be fixed ASAP. import tables, sequtils, options, strformat -import chronos +import chronos, chronicles import coder, types, channel, + ../muxer, ../../varint, ../../connection, ../../vbuffer, ../../protocols/protocol, ../../stream/bufferstream, - ../../stream/lpstream, - ../muxer, - ../../helpers/debug + ../../stream/lpstream type Mplex* = ref object of Muxer @@ -35,9 +34,6 @@ type currentId*: uint maxChannels*: uint -proc newMplexNoSuchChannel(id: uint, msgType: MessageType): ref MplexNoSuchChannel = - result = newException(MplexNoSuchChannel, &"No such channel id {$id} and message {$msgType}") - proc newMplexUnknownMsgError(): ref MplexUnknownMsgError = result = newException(MplexUnknownMsgError, "Unknown mplex message type") @@ -71,7 +67,7 @@ method handle*(m: Mplex) {.async, gcsafe.} = if MessageType(msgType) != MessageType.New: let channels = m.getChannelList(initiator) if not channels.contains(id): - debug &"handle: Channel with id {id} message type {msgType} not found" + # debug "handle: Channel with id and msg type ", id = id, msg = msgType continue channel = channels[id] @@ -79,7 +75,7 @@ method handle*(m: Mplex) {.async, gcsafe.} = of MessageType.New: let name = cast[string](data) channel = await m.newStreamInternal(false, id, name) - debug &"handle: created channel with id {$id} and name {name}" + # debug "handle: created channel ", id = id, name = name if not isNil(m.streamHandler): let handlerFut = m.streamHandler(newConnection(channel)) @@ -91,19 +87,19 @@ method handle*(m: Mplex) {.async, gcsafe.} = proc(udata: pointer) = # TODO: is waitFor() OK here? channel.cleanUp() - .addCallback(proc(udata: pointer) - = debug &"handle: cleaned up channel {$id}")) - handlerFut.addCallback(cleanUpChan) + .addCallback(proc(udata: pointer) = + debug "handle: cleaned up channel ", id = id)) + handlerFut.addCallback(cleanUpChan) continue of MessageType.MsgIn, MessageType.MsgOut: - debug &"handle: pushing data to channel {$id} type {msgType}" + debug "handle: pushing data to channel ", id = id, msgType = msgType await channel.pushTo(data) of MessageType.CloseIn, MessageType.CloseOut: - debug &"handle: closing channel {$id} type {msgType}" + debug "handle: closing channel ", id = id, msgType = msgType await channel.closedByRemote() m.getChannelList(initiator).del(id) of MessageType.ResetIn, MessageType.ResetOut: - debug &"handle: resetting channel {$id} type {msgType}" + debug "handle: resetting channel ", id = id await channel.resetByRemote() break else: raise newMplexUnknownMsgError() diff --git a/libp2p/protocols/identify.nim b/libp2p/protocols/identify.nim index 17afeb368..cce90061a 100644 --- a/libp2p/protocols/identify.nim +++ b/libp2p/protocols/identify.nim @@ -8,15 +8,14 @@ ## those terms. import options, strformat -import chronos +import chronos, chronicles import ../protobuf/minprotobuf, ../peerinfo, ../connection, ../peer, ../crypto/crypto, ../multiaddress, - ../protocols/protocol, - ../helpers/debug + ../protocols/protocol const IdentifyCodec* = "/ipfs/id/1.0.0" const IdentifyPushCodec* = "/ipfs/id/push/1.0.0" @@ -108,7 +107,7 @@ proc identify*(p: Identify, "Invalid or empty message received!") result = decodeMsg(message) - debug &"identify: Identify for remote peer succeded" + debug "identify: Identify for remote peer succeded" if remotePeerInfo.isSome and remotePeerInfo.get().peerId.publicKey != result.pubKey: debug "identify: Peer's remote public key doesn't match" diff --git a/libp2p/switch.nim b/libp2p/switch.nim index b1fbe1b05..f8156f8ec 100644 --- a/libp2p/switch.nim +++ b/libp2p/switch.nim @@ -8,19 +8,19 @@ ## those terms. import tables, sequtils, options, strformat -import chronos +import chronos, chronicles import connection, transports/transport, stream/lpstream, multistream, protocols/protocol, - protocols/secure, + protocols/secure/secure, # for plain text + protocols/secure/secio, peerinfo, multiaddress, protocols/identify, muxers/muxer, - peer, - helpers/debug + peer type Switch* = ref object of RootObj @@ -33,13 +33,13 @@ type ms*: MultisteamSelect identity*: Identify streamHandler*: StreamHandler - secureManager*: Secure + secureManagers*: seq[Secure] proc secure(s: Switch, conn: Connection): Future[Connection] {.async, gcsafe.} = ## secure the incoming connection # plaintext for now, doesn't do anything - if not (await s.ms.select(conn, s.secureManager.codec)): + if (await s.ms.select(conn, s.secureManagers.mapIt(it.codec))).len == 0: raise newException(CatchableError, "Unable to negotiate a secure channel!") result = conn @@ -61,11 +61,11 @@ proc identify(s: Switch, conn: Connection) {.async, gcsafe.} = peerInfo.peerId = PeerID.init(info.pubKey) # we might not have a peerId at all peerInfo.addrs = info.addrs peerInfo.protocols = info.protos - debug &"identify: identified remote peer {peerInfo.peerId.pretty}" + debug "identify: identified remote peer ", peer = peerInfo.peerId.pretty except IdentityInvalidMsgError as exc: - debug exc.msg + debug "identify: invalid message", msg = exc.msg except IdentityNoMatchError as exc: - debug exc.msg + debug "identify: peer's public keys don't match ", msg = exc.msg proc mux(s: Switch, conn: Connection): Future[void] {.async, gcsafe.} = ## mux incoming connection @@ -87,7 +87,7 @@ proc mux(s: Switch, conn: Connection): Future[void] {.async, gcsafe.} = handlerFut.addCallback( proc(udata: pointer = nil) {.gcsafe.} = if handlerFut.finished: - debug &"Muxer handler completed for peer {conn.peerInfo.get().peerId.pretty}" + debug "mux: Muxer handler completed for peer ", peer = conn.peerInfo.get().peerId.pretty ) await s.identify(stream) await stream.close() # close idenity stream @@ -141,9 +141,9 @@ proc dial*(s: Switch, if s.muxed.contains(peer.peerId.pretty): result = await s.muxed[peer.peerId.pretty].newStream() - debug &"dial: attempting to select remote proto {proto}" + debug "dial: attempting to select remote ", proto = proto if not (await s.ms.select(result, proto)): - debug &"dial: Unable to select protocol: {proto}" + debug "dial: Unable to select protocol: ", proto = proto raise newException(CatchableError, &"Unable to select protocol: {proto}") @@ -177,7 +177,8 @@ proc stop*(s: Switch) {.async.} = proc newSwitch*(peerInfo: PeerInfo, transports: seq[Transport], identity: Identify, - muxers: Table[string, MuxerProvider]): Switch = + muxers: Table[string, MuxerProvider], + secureManagers: seq[Secure] = @[]): Switch = new result result.peerInfo = peerInfo result.ms = newMultistream() @@ -199,5 +200,10 @@ proc newSwitch*(peerInfo: PeerInfo, val.streamHandler = result.streamHandler result.mount(val) - result.secureManager = Secure(newPlainText()) - result.mount(result.secureManager) + for s in secureManagers: + result.secureManagers.add(s) + result.mount(s) + + if result.secureManagers.len == 0: + # use plain text if no secure managers are provided + result.mount(Secure(newPlainText())) diff --git a/tests/testmplex.nim b/tests/testmplex.nim index 9c5bfd3e1..6899b6f0f 100644 --- a/tests/testmplex.nim +++ b/tests/testmplex.nim @@ -1,5 +1,5 @@ -import unittest, sequtils, sugar, strformat, options -import chronos, nimcrypto/utils +import unittest, sequtils, sugar, strformat, options, strformat +import chronos, nimcrypto/utils, chronicles import ../libp2p/connection, ../libp2p/stream/lpstream, ../libp2p/stream/bufferstream, @@ -10,8 +10,7 @@ import ../libp2p/connection, ../libp2p/muxers/mplex/mplex, ../libp2p/muxers/mplex/coder, ../libp2p/muxers/mplex/types, - ../libp2p/muxers/mplex/channel, - ../libp2p/helpers/debug + ../libp2p/muxers/mplex/channel suite "Mplex": test "encode header with channel id 0": diff --git a/tests/testnative.nim b/tests/testnative.nim index cd7a268bd..bfc01c41e 100644 --- a/tests/testnative.nim +++ b/tests/testnative.nim @@ -2,4 +2,4 @@ import unittest import testvarint, testbase32, testbase58, testbase64 import testrsa, testecnist, tested25519, testsecp256k1, testcrypto import testmultibase, testmultihash, testmultiaddress, testcid, testpeer -import testidentify, testtransport, testmultistream, testbufferstream, testmplex +import testidentify, testtransport, testmultistream, testbufferstream, testmplex, testswitch diff --git a/tests/testswitch.nim b/tests/testswitch.nim index 8735ca043..5fa1df897 100644 --- a/tests/testswitch.nim +++ b/tests/testswitch.nim @@ -1,5 +1,5 @@ import unittest, tables -import chronos +import chronos, chronicles import ../libp2p/switch, ../libp2p/multistream, ../libp2p/protocols/identify, @@ -12,8 +12,7 @@ import ../libp2p/switch, ../libp2p/protocols/protocol, ../libp2p/muxers/muxer, ../libp2p/muxers/mplex/mplex, - ../libp2p/muxers/mplex/types, - ../libp2p/helpers/debug + ../libp2p/muxers/mplex/types const TestCodec = "/test/proto/1.0.0"