mirror of https://github.com/vacp2p/nim-libp2p.git
adding raises defect across the codebase (#572)
* adding raises defect across the codebase * use unittest2 * add windows deps caching * update mingw link * die on failed peerinfo initialization * use result.expect instead of get * use expect more consistently and rework inits * use expect more consistently * throw on missing public key * remove unused closure annotation * merge master
This commit is contained in:
parent
9674a6a6f6
commit
ac4e060e1a
|
@ -43,6 +43,38 @@ jobs:
|
||||||
with:
|
with:
|
||||||
path: nim-libp2p
|
path: nim-libp2p
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
|
- name: Derive environment variables
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ '${{ matrix.target.cpu }}' == 'amd64' ]]; then
|
||||||
|
ARCH=64
|
||||||
|
PLATFORM=x64
|
||||||
|
else
|
||||||
|
ARCH=32
|
||||||
|
PLATFORM=x86
|
||||||
|
fi
|
||||||
|
echo "ARCH=$ARCH" >> $GITHUB_ENV
|
||||||
|
echo "PLATFORM=$PLATFORM" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
ncpu=
|
||||||
|
ext=
|
||||||
|
case '${{ runner.os }}' in
|
||||||
|
'Linux')
|
||||||
|
ncpu=$(nproc)
|
||||||
|
;;
|
||||||
|
'macOS')
|
||||||
|
ncpu=$(sysctl -n hw.ncpu)
|
||||||
|
;;
|
||||||
|
'Windows')
|
||||||
|
ncpu=$NUMBER_OF_PROCESSORS
|
||||||
|
ext=.exe
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
|
||||||
|
echo "ncpu=$ncpu" >> $GITHUB_ENV
|
||||||
|
echo "ext=$ext" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Install build dependencies (Linux i386)
|
- name: Install build dependencies (Linux i386)
|
||||||
if: runner.os == 'Linux' && matrix.target.cpu == 'i386'
|
if: runner.os == 'Linux' && matrix.target.cpu == 'i386'
|
||||||
run: |
|
run: |
|
||||||
|
@ -63,22 +95,50 @@ jobs:
|
||||||
chmod 755 external/bin/gcc external/bin/g++
|
chmod 755 external/bin/gcc external/bin/g++
|
||||||
echo '${{ github.workspace }}/external/bin' >> $GITHUB_PATH
|
echo '${{ github.workspace }}/external/bin' >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Install build dependencies (Windows)
|
- name: Restore MinGW-W64 (Windows) from cache
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
|
id: windows-mingw-cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: external/mingw-${{ matrix.target.cpu }}
|
||||||
|
key: 'mingw-${{ matrix.target.cpu }}'
|
||||||
|
|
||||||
|
- name: Restore Nim DLLs dependencies (Windows) from cache
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
id: windows-dlls-cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: external/dlls-${{ matrix.target.cpu }}
|
||||||
|
key: 'dlls-${{ matrix.target.cpu }}'
|
||||||
|
|
||||||
|
- name: Install MinGW64 dependency (Windows)
|
||||||
|
if: >
|
||||||
|
steps.windows-mingw-cache.outputs.cache-hit != 'true' &&
|
||||||
|
runner.os == 'Windows'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
mkdir external
|
mkdir -p external
|
||||||
if [[ '${{ matrix.target.cpu }}' == 'amd64' ]]; then
|
curl -L "https://nim-lang.org/download/mingw$ARCH.7z" -o "external/mingw-${{ matrix.target.cpu }}.7z"
|
||||||
arch=64
|
7z x -y "external/mingw-${{ matrix.target.cpu }}.7z" -oexternal/
|
||||||
else
|
mv external/mingw$ARCH external/mingw-${{ matrix.target.cpu }}
|
||||||
arch=32
|
|
||||||
fi
|
- name: Install DLLs dependencies (Windows)
|
||||||
curl -L "https://nim-lang.org/download/mingw$arch-6.3.0.7z" -o "external/mingw$arch.7z"
|
if: >
|
||||||
|
steps.windows-dlls-cache.outputs.cache-hit != 'true' &&
|
||||||
|
runner.os == 'Windows'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p external
|
||||||
curl -L "https://nim-lang.org/download/windeps.zip" -o external/windeps.zip
|
curl -L "https://nim-lang.org/download/windeps.zip" -o external/windeps.zip
|
||||||
7z x "external/mingw$arch.7z" -oexternal/
|
7z x -y external/windeps.zip -oexternal/dlls-${{ matrix.target.cpu }}
|
||||||
7z x external/windeps.zip -oexternal/dlls
|
|
||||||
echo '${{ github.workspace }}'"/external/mingw$arch/bin" >> $GITHUB_PATH
|
- name: Path to cached dependencies (Windows)
|
||||||
echo '${{ github.workspace }}'"/external/dlls" >> $GITHUB_PATH
|
if: >
|
||||||
|
runner.os == 'Windows'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "${{ github.workspace }}/external/mingw-${{ matrix.target.cpu }}/bin" >> $GITHUB_PATH
|
||||||
|
echo "${{ github.workspace }}/external/dlls-${{ matrix.target.cpu }}" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Setup environment
|
- name: Setup environment
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -133,20 +193,6 @@ jobs:
|
||||||
if: steps.nim-cache.outputs.cache-hit != 'true'
|
if: steps.nim-cache.outputs.cache-hit != 'true'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
ncpu=
|
|
||||||
ext=
|
|
||||||
case '${{ runner.os }}' in
|
|
||||||
'Linux')
|
|
||||||
ncpu=$(nproc)
|
|
||||||
;;
|
|
||||||
'macOS')
|
|
||||||
ncpu=$(sysctl -n hw.ncpu)
|
|
||||||
;;
|
|
||||||
'Windows')
|
|
||||||
ncpu=$NUMBER_OF_PROCESSORS
|
|
||||||
ext=.exe
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
|
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
|
||||||
if [[ ! -e csources/bin/nim$ext ]]; then
|
if [[ ! -e csources/bin/nim$ext ]]; then
|
||||||
make -C csources -j $ncpu CC=gcc ucpu='${{ matrix.target.cpu }}'
|
make -C csources -j $ncpu CC=gcc ucpu='${{ matrix.target.cpu }}'
|
||||||
|
@ -164,29 +210,6 @@ jobs:
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
rm -rf .git
|
rm -rf .git
|
||||||
|
|
||||||
# - name: Install library dependencies (Linux amd64)
|
|
||||||
# if: runner.os == 'Linux' && matrix.target.cpu == 'amd64'
|
|
||||||
# run: |
|
|
||||||
# sudo DEBIAN_FRONTEND='noninteractive' apt-get install \
|
|
||||||
# --no-install-recommends -yq libgmp-dev
|
|
||||||
#
|
|
||||||
# - name: Install library dependencies (Linux i386)
|
|
||||||
# if: runner.os == 'Linux' && matrix.target.cpu == 'i386'
|
|
||||||
# run: |
|
|
||||||
# sudo DEBIAN_FRONTEND='noninteractive' apt-get install \
|
|
||||||
# libgmp-dev:i386
|
|
||||||
#
|
|
||||||
# - name: Install library dependencies (macOS)
|
|
||||||
# if: runner.os == 'macOS'
|
|
||||||
# run: brew install gmp
|
|
||||||
#
|
|
||||||
# - name: Install library dependencies (Windows)
|
|
||||||
# if: runner.os == 'Windows'
|
|
||||||
# shell: bash
|
|
||||||
# run: |
|
|
||||||
# choco install msys2
|
|
||||||
# pacman -S mingw-w64-x86_64-gmp
|
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
## Nim-Libp2p
|
||||||
|
## Copyright (c) 2020 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.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
options, tables, chronos, bearssl,
|
options, tables, chronos, bearssl,
|
||||||
switch, peerid, peerinfo, stream/connection, multiaddress,
|
switch, peerid, peerinfo, stream/connection, multiaddress,
|
||||||
|
@ -36,9 +47,14 @@ type
|
||||||
agentVersion: string
|
agentVersion: string
|
||||||
|
|
||||||
proc new*(T: type[SwitchBuilder]): T =
|
proc new*(T: type[SwitchBuilder]): T =
|
||||||
|
|
||||||
|
let address = MultiAddress
|
||||||
|
.init("/ip4/127.0.0.1/tcp/0")
|
||||||
|
.expect("address should initialize to default")
|
||||||
|
|
||||||
SwitchBuilder(
|
SwitchBuilder(
|
||||||
privKey: none(PrivateKey),
|
privKey: none(PrivateKey),
|
||||||
address: MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
address: address,
|
||||||
secureManagers: @[],
|
secureManagers: @[],
|
||||||
tcpTransportOpts: TcpTransportOpts(),
|
tcpTransportOpts: TcpTransportOpts(),
|
||||||
maxConnections: MaxConnections,
|
maxConnections: MaxConnections,
|
||||||
|
@ -109,10 +125,11 @@ proc withAgentVersion*(b: SwitchBuilder, agentVersion: string): SwitchBuilder =
|
||||||
|
|
||||||
proc build*(b: SwitchBuilder): Switch =
|
proc build*(b: SwitchBuilder): Switch =
|
||||||
if b.rng == nil: # newRng could fail
|
if b.rng == nil: # newRng could fail
|
||||||
raise (ref CatchableError)(msg: "Cannot initialize RNG")
|
raise newException(Defect, "Cannot initialize RNG")
|
||||||
|
|
||||||
|
let pkRes = PrivateKey.random(b.rng[])
|
||||||
let
|
let
|
||||||
seckey = b.privKey.get(otherwise = PrivateKey.random(b.rng[]).tryGet())
|
seckey = b.privKey.get(otherwise = pkRes.expect("Should supply a valid RNG"))
|
||||||
|
|
||||||
var
|
var
|
||||||
secureManagerInstances: seq[Secure]
|
secureManagerInstances: seq[Secure]
|
||||||
|
@ -120,11 +137,11 @@ proc build*(b: SwitchBuilder): Switch =
|
||||||
secureManagerInstances.add(newNoise(b.rng, seckey).Secure)
|
secureManagerInstances.add(newNoise(b.rng, seckey).Secure)
|
||||||
|
|
||||||
let
|
let
|
||||||
peerInfo = block:
|
peerInfo = PeerInfo.init(
|
||||||
var info = PeerInfo.init(seckey, [b.address])
|
seckey,
|
||||||
info.protoVersion = b.protoVersion
|
[b.address],
|
||||||
info.agentVersion = b.agentVersion
|
protoVersion = b.protoVersion,
|
||||||
info
|
agentVersion = b.agentVersion)
|
||||||
|
|
||||||
let
|
let
|
||||||
muxers = block:
|
muxers = block:
|
||||||
|
@ -149,16 +166,19 @@ proc build*(b: SwitchBuilder): Switch =
|
||||||
if isNil(b.rng):
|
if isNil(b.rng):
|
||||||
b.rng = newRng()
|
b.rng = newRng()
|
||||||
|
|
||||||
let switch = newSwitch(
|
let switch = try:
|
||||||
peerInfo = peerInfo,
|
newSwitch(
|
||||||
transports = transports,
|
peerInfo = peerInfo,
|
||||||
identity = identify,
|
transports = transports,
|
||||||
muxers = muxers,
|
identity = identify,
|
||||||
secureManagers = secureManagerInstances,
|
muxers = muxers,
|
||||||
maxConnections = b.maxConnections,
|
secureManagers = secureManagerInstances,
|
||||||
maxIn = b.maxIn,
|
maxConnections = b.maxConnections,
|
||||||
maxOut = b.maxOut,
|
maxIn = b.maxIn,
|
||||||
maxConnsPerPeer = b.maxConnsPerPeer)
|
maxOut = b.maxOut,
|
||||||
|
maxConnsPerPeer = b.maxConnsPerPeer)
|
||||||
|
except CatchableError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
return switch
|
return switch
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[options, tables, sequtils, sets]
|
import std/[options, tables, sequtils, sets]
|
||||||
import chronos, chronicles, metrics
|
import chronos, chronicles, metrics
|
||||||
import peerinfo,
|
import peerinfo,
|
||||||
|
@ -25,9 +27,10 @@ const
|
||||||
MaxConnectionsPerPeer* = 5
|
MaxConnectionsPerPeer* = 5
|
||||||
|
|
||||||
type
|
type
|
||||||
TooManyConnectionsError* = object of CatchableError
|
TooManyConnectionsError* = object of LPError
|
||||||
|
|
||||||
ConnProvider* = proc(): Future[Connection] {.gcsafe, closure.}
|
ConnProvider* = proc(): Future[Connection]
|
||||||
|
{.gcsafe, closure, raises: [Defect].}
|
||||||
|
|
||||||
ConnEventKind* {.pure.} = enum
|
ConnEventKind* {.pure.} = enum
|
||||||
Connected, # A connection was made and securely upgraded - there may be
|
Connected, # A connection was made and securely upgraded - there may be
|
||||||
|
@ -45,7 +48,8 @@ type
|
||||||
discard
|
discard
|
||||||
|
|
||||||
ConnEventHandler* =
|
ConnEventHandler* =
|
||||||
proc(peerId: PeerID, event: ConnEvent): Future[void] {.gcsafe.}
|
proc(peerId: PeerID, event: ConnEvent): Future[void]
|
||||||
|
{.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
PeerEventKind* {.pure.} = enum
|
PeerEventKind* {.pure.} = enum
|
||||||
Left,
|
Left,
|
||||||
|
@ -105,13 +109,27 @@ proc addConnEventHandler*(c: ConnManager,
|
||||||
## Add peer event handler - handlers must not raise exceptions!
|
## Add peer event handler - handlers must not raise exceptions!
|
||||||
##
|
##
|
||||||
|
|
||||||
if isNil(handler): return
|
try:
|
||||||
c.connEvents[kind].incl(handler)
|
if isNil(handler): return
|
||||||
|
c.connEvents[kind].incl(handler)
|
||||||
|
except Exception as exc:
|
||||||
|
# TODO: there is an Exception being raised
|
||||||
|
# somewhere in the depths of the std.
|
||||||
|
# Might be related to https://github.com/nim-lang/Nim/issues/17382
|
||||||
|
|
||||||
|
raiseAssert exc.msg
|
||||||
|
|
||||||
proc removeConnEventHandler*(c: ConnManager,
|
proc removeConnEventHandler*(c: ConnManager,
|
||||||
handler: ConnEventHandler,
|
handler: ConnEventHandler,
|
||||||
kind: ConnEventKind) =
|
kind: ConnEventKind) =
|
||||||
c.connEvents[kind].excl(handler)
|
try:
|
||||||
|
c.connEvents[kind].excl(handler)
|
||||||
|
except Exception as exc:
|
||||||
|
# TODO: there is an Exception being raised
|
||||||
|
# somewhere in the depths of the std.
|
||||||
|
# Might be related to https://github.com/nim-lang/Nim/issues/17382
|
||||||
|
|
||||||
|
raiseAssert exc.msg
|
||||||
|
|
||||||
proc triggerConnEvent*(c: ConnManager,
|
proc triggerConnEvent*(c: ConnManager,
|
||||||
peerId: PeerID,
|
peerId: PeerID,
|
||||||
|
@ -138,12 +156,26 @@ proc addPeerEventHandler*(c: ConnManager,
|
||||||
##
|
##
|
||||||
|
|
||||||
if isNil(handler): return
|
if isNil(handler): return
|
||||||
c.peerEvents[kind].incl(handler)
|
try:
|
||||||
|
c.peerEvents[kind].incl(handler)
|
||||||
|
except Exception as exc:
|
||||||
|
# TODO: there is an Exception being raised
|
||||||
|
# somewhere in the depths of the std.
|
||||||
|
# Might be related to https://github.com/nim-lang/Nim/issues/17382
|
||||||
|
|
||||||
|
raiseAssert exc.msg
|
||||||
|
|
||||||
proc removePeerEventHandler*(c: ConnManager,
|
proc removePeerEventHandler*(c: ConnManager,
|
||||||
handler: PeerEventHandler,
|
handler: PeerEventHandler,
|
||||||
kind: PeerEventKind) =
|
kind: PeerEventKind) =
|
||||||
c.peerEvents[kind].excl(handler)
|
try:
|
||||||
|
c.peerEvents[kind].excl(handler)
|
||||||
|
except Exception as exc:
|
||||||
|
# TODO: there is an Exception being raised
|
||||||
|
# somewhere in the depths of the std.
|
||||||
|
# Might be related to https://github.com/nim-lang/Nim/issues/17382
|
||||||
|
|
||||||
|
raiseAssert exc.msg
|
||||||
|
|
||||||
proc triggerPeerEvents*(c: ConnManager,
|
proc triggerPeerEvents*(c: ConnManager,
|
||||||
peerId: PeerID,
|
peerId: PeerID,
|
||||||
|
@ -205,7 +237,7 @@ proc contains*(c: ConnManager, muxer: Muxer): bool =
|
||||||
if conn notin c.muxed:
|
if conn notin c.muxed:
|
||||||
return
|
return
|
||||||
|
|
||||||
return muxer == c.muxed[conn].muxer
|
return muxer == c.muxed.getOrDefault(conn).muxer
|
||||||
|
|
||||||
proc closeMuxerHolder(muxerHolder: MuxerHolder) {.async.} =
|
proc closeMuxerHolder(muxerHolder: MuxerHolder) {.async.} =
|
||||||
trace "Cleaning up muxer", m = muxerHolder.muxer
|
trace "Cleaning up muxer", m = muxerHolder.muxer
|
||||||
|
@ -338,11 +370,12 @@ proc selectMuxer*(c: ConnManager, conn: Connection): Muxer =
|
||||||
return
|
return
|
||||||
|
|
||||||
if conn in c.muxed:
|
if conn in c.muxed:
|
||||||
return c.muxed[conn].muxer
|
return c.muxed.getOrDefault(conn).muxer
|
||||||
else:
|
else:
|
||||||
debug "no muxer for connection", conn
|
debug "no muxer for connection", conn
|
||||||
|
|
||||||
proc storeConn*(c: ConnManager, conn: Connection) =
|
proc storeConn*(c: ConnManager, conn: Connection)
|
||||||
|
{.raises: [Defect, CatchableError].} =
|
||||||
## store a connection
|
## store a connection
|
||||||
##
|
##
|
||||||
|
|
||||||
|
@ -456,7 +489,8 @@ proc trackOutgoingConn*(c: ConnManager,
|
||||||
|
|
||||||
proc storeMuxer*(c: ConnManager,
|
proc storeMuxer*(c: ConnManager,
|
||||||
muxer: Muxer,
|
muxer: Muxer,
|
||||||
handle: Future[void] = nil) =
|
handle: Future[void] = nil)
|
||||||
|
{.raises: [Defect, CatchableError].} =
|
||||||
## store the connection and muxer
|
## store the connection and muxer
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
## 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 chronos, chronicles
|
||||||
|
@ -467,7 +469,7 @@ proc checkResponse(pb: var ProtoBuffer): ResponseKind {.inline.} =
|
||||||
else:
|
else:
|
||||||
result = ResponseKind.Error
|
result = ResponseKind.Error
|
||||||
|
|
||||||
proc getErrorMessage(pb: var ProtoBuffer): string {.inline.} =
|
proc getErrorMessage(pb: var ProtoBuffer): string {.inline, raises: [Defect, DaemonLocalError].} =
|
||||||
if pb.enterSubmessage() == cast[int](ResponseType.ERROR):
|
if pb.enterSubmessage() == cast[int](ResponseType.ERROR):
|
||||||
if pb.getString(1, result) == -1:
|
if pb.getString(1, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Error message is missing!")
|
raise newException(DaemonLocalError, "Error message is missing!")
|
||||||
|
@ -825,7 +827,8 @@ proc transactMessage(transp: StreamTransport,
|
||||||
raise newException(DaemonLocalError, "Incorrect or empty message received!")
|
raise newException(DaemonLocalError, "Incorrect or empty message received!")
|
||||||
result = initProtoBuffer(message)
|
result = initProtoBuffer(message)
|
||||||
|
|
||||||
proc getPeerInfo(pb: var ProtoBuffer): PeerInfo =
|
proc getPeerInfo(pb: var ProtoBuffer): PeerInfo
|
||||||
|
{.raises: [Defect, DaemonLocalError].} =
|
||||||
## Get PeerInfo object from ``pb``.
|
## Get PeerInfo object from ``pb``.
|
||||||
result.addresses = newSeq[MultiAddress]()
|
result.addresses = newSeq[MultiAddress]()
|
||||||
if pb.getValue(1, result.peer) == -1:
|
if pb.getValue(1, result.peer) == -1:
|
||||||
|
@ -834,7 +837,11 @@ proc getPeerInfo(pb: var ProtoBuffer): PeerInfo =
|
||||||
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
|
||||||
result.addresses.add(MultiAddress.init(copyaddr).tryGet())
|
let addrRes = MultiAddress.init(copyaddr)
|
||||||
|
if addrRes.isErr:
|
||||||
|
raise newException(DaemonLocalError, addrRes.error)
|
||||||
|
|
||||||
|
result.addresses.add(MultiAddress.init(copyaddr).get())
|
||||||
address.setLen(0)
|
address.setLen(0)
|
||||||
|
|
||||||
proc identity*(api: DaemonAPI): Future[PeerInfo] {.async.} =
|
proc identity*(api: DaemonAPI): Future[PeerInfo] {.async.} =
|
||||||
|
@ -996,26 +1003,31 @@ proc cmTrimPeers*(api: DaemonAPI) {.async.} =
|
||||||
finally:
|
finally:
|
||||||
await api.closeConnection(transp)
|
await api.closeConnection(transp)
|
||||||
|
|
||||||
proc dhtGetSinglePeerInfo(pb: var ProtoBuffer): PeerInfo =
|
proc dhtGetSinglePeerInfo(pb: var ProtoBuffer): PeerInfo
|
||||||
|
{.raises: [Defect, DaemonLocalError].} =
|
||||||
if pb.enterSubmessage() == 2:
|
if pb.enterSubmessage() == 2:
|
||||||
result = pb.getPeerInfo()
|
result = pb.getPeerInfo()
|
||||||
else:
|
else:
|
||||||
raise newException(DaemonLocalError, "Missing required field `peer`!")
|
raise newException(DaemonLocalError, "Missing required field `peer`!")
|
||||||
|
|
||||||
proc dhtGetSingleValue(pb: var ProtoBuffer): seq[byte] =
|
proc dhtGetSingleValue(pb: var ProtoBuffer): seq[byte]
|
||||||
|
{.raises: [Defect, DaemonLocalError].} =
|
||||||
result = newSeq[byte]()
|
result = newSeq[byte]()
|
||||||
if pb.getLengthValue(3, result) == -1:
|
if pb.getLengthValue(3, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
proc dhtGetSinglePublicKey(pb: var ProtoBuffer): PublicKey =
|
proc dhtGetSinglePublicKey(pb: var ProtoBuffer): PublicKey
|
||||||
|
{.raises: [Defect, DaemonLocalError].} =
|
||||||
if pb.getValue(3, result) == -1:
|
if pb.getValue(3, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
proc dhtGetSinglePeerID(pb: var ProtoBuffer): PeerID =
|
proc dhtGetSinglePeerID(pb: var ProtoBuffer): PeerID
|
||||||
|
{.raises: [Defect, DaemonLocalError].} =
|
||||||
if pb.getValue(3, result) == -1:
|
if pb.getValue(3, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
proc enterDhtMessage(pb: var ProtoBuffer, rt: DHTResponseType) {.inline.} =
|
proc enterDhtMessage(pb: var ProtoBuffer, rt: DHTResponseType)
|
||||||
|
{.inline, raises: [Defect, DaemonLocalError].} =
|
||||||
var dtype: uint
|
var dtype: uint
|
||||||
var res = pb.enterSubmessage()
|
var res = pb.enterSubmessage()
|
||||||
if res == cast[int](ResponseType.DHT):
|
if res == cast[int](ResponseType.DHT):
|
||||||
|
@ -1026,12 +1038,14 @@ proc enterDhtMessage(pb: var ProtoBuffer, rt: DHTResponseType) {.inline.} =
|
||||||
else:
|
else:
|
||||||
raise newException(DaemonLocalError, "Wrong message type!")
|
raise newException(DaemonLocalError, "Wrong message type!")
|
||||||
|
|
||||||
proc enterPsMessage(pb: var ProtoBuffer) {.inline.} =
|
proc enterPsMessage(pb: var ProtoBuffer)
|
||||||
|
{.inline, raises: [Defect, DaemonLocalError].} =
|
||||||
var res = pb.enterSubmessage()
|
var res = pb.enterSubmessage()
|
||||||
if res != cast[int](ResponseType.PUBSUB):
|
if res != cast[int](ResponseType.PUBSUB):
|
||||||
raise newException(DaemonLocalError, "Wrong message type!")
|
raise newException(DaemonLocalError, "Wrong message type!")
|
||||||
|
|
||||||
proc getDhtMessageType(pb: var ProtoBuffer): DHTResponseType {.inline.} =
|
proc getDhtMessageType(pb: var ProtoBuffer): DHTResponseType
|
||||||
|
{.inline, raises: [Defect, DaemonLocalError].} =
|
||||||
var dtype: uint
|
var dtype: uint
|
||||||
if pb.getVarintValue(1, dtype) == 0:
|
if pb.getVarintValue(1, dtype) == 0:
|
||||||
raise newException(DaemonLocalError, "Missing required DHT field `type`!")
|
raise newException(DaemonLocalError, "Missing required DHT field `type`!")
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
## This module implements Pool of StreamTransport.
|
## This module implements Pool of StreamTransport.
|
||||||
import chronos
|
import chronos
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,14 @@ import chronos
|
||||||
import chronicles
|
import chronicles
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
|
type
|
||||||
|
# Base exception type for libp2p
|
||||||
|
LPError* = object of CatchableError
|
||||||
|
LPAllFuturesError* = object of LPError
|
||||||
|
errors*: seq[ref CatchableError]
|
||||||
|
|
||||||
# could not figure how to make it with a simple template
|
# could not figure how to make it with a simple template
|
||||||
# sadly nim needs more love for hygenic templates
|
# sadly nim needs more love for hygienic templates
|
||||||
# so here goes the macro, its based on the proc/template version
|
# so here goes the macro, its based on the proc/template version
|
||||||
# and uses quote do so it's quite readable
|
# and uses quote do so it's quite readable
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import nativesockets, hashes
|
import pkg/chronos
|
||||||
|
import std/[nativesockets, hashes]
|
||||||
import tables, strutils, stew/shims/net
|
import tables, strutils, stew/shims/net
|
||||||
import chronos
|
|
||||||
import multicodec, multihash, multibase, transcoder, vbuffer, peerid,
|
import multicodec, multihash, multibase, transcoder, vbuffer, peerid,
|
||||||
protobuf/minprotobuf
|
protobuf/minprotobuf, errors
|
||||||
import stew/[base58, base32, endians2, results]
|
import stew/[base58, base32, endians2, results]
|
||||||
export results, minprotobuf, vbuffer
|
export results, minprotobuf, vbuffer
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ type
|
||||||
|
|
||||||
MaResult*[T] = Result[T, string]
|
MaResult*[T] = Result[T, string]
|
||||||
|
|
||||||
MaError* = object of CatchableError
|
MaError* = object of LPError
|
||||||
MaInvalidAddress* = object of MaError
|
MaInvalidAddress* = object of MaError
|
||||||
|
|
||||||
IpTransportProtocol* = enum
|
IpTransportProtocol* = enum
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[strutils]
|
import std/[strutils]
|
||||||
import chronos, chronicles, stew/byteutils
|
import chronos, chronicles, stew/byteutils
|
||||||
import stream/connection,
|
import stream/connection,
|
||||||
|
@ -25,7 +27,7 @@ const
|
||||||
Ls* = "\x03ls\n"
|
Ls* = "\x03ls\n"
|
||||||
|
|
||||||
type
|
type
|
||||||
Matcher* = proc (proto: string): bool {.gcsafe.}
|
Matcher* = proc (proto: string): bool {.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
HandlerHolder* = object
|
HandlerHolder* = object
|
||||||
protos*: seq[string]
|
protos*: seq[string]
|
||||||
|
|
|
@ -7,12 +7,15 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import chronos
|
import chronos
|
||||||
import nimcrypto/utils, chronicles, stew/byteutils
|
import nimcrypto/utils, chronicles, stew/byteutils
|
||||||
import ../../stream/connection,
|
import ../../stream/connection,
|
||||||
../../utility,
|
../../utility,
|
||||||
../../varint,
|
../../varint,
|
||||||
../../vbuffer
|
../../vbuffer,
|
||||||
|
../muxer
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "libp2p mplexcoder"
|
topics = "libp2p mplexcoder"
|
||||||
|
@ -32,7 +35,7 @@ type
|
||||||
msgType: MessageType
|
msgType: MessageType
|
||||||
data: seq[byte]
|
data: seq[byte]
|
||||||
|
|
||||||
InvalidMplexMsgType = object of CatchableError
|
InvalidMplexMsgType* = object of MuxerError
|
||||||
|
|
||||||
# https://github.com/libp2p/specs/tree/master/mplex#writing-to-a-stream
|
# https://github.com/libp2p/specs/tree/master/mplex#writing-to-a-stream
|
||||||
const MaxMsgSize* = 1 shl 20 # 1mb
|
const MaxMsgSize* = 1 shl 20 # 1mb
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[oids, strformat]
|
import std/[oids, strformat]
|
||||||
import chronos, chronicles, metrics
|
import chronos, chronicles, metrics
|
||||||
import ./coder,
|
import ./coder,
|
||||||
|
@ -51,11 +53,15 @@ type
|
||||||
writes*: int # In-flight writes
|
writes*: int # In-flight writes
|
||||||
|
|
||||||
func shortLog*(s: LPChannel): auto =
|
func shortLog*(s: LPChannel): auto =
|
||||||
if s.isNil: "LPChannel(nil)"
|
try:
|
||||||
elif s.conn.peerInfo.isNil: $s.oid
|
if s.isNil: "LPChannel(nil)"
|
||||||
elif s.name != $s.oid and s.name.len > 0:
|
elif s.conn.peerInfo.isNil: $s.oid
|
||||||
&"{shortLog(s.conn.peerInfo.peerId)}:{s.oid}:{s.name}"
|
elif s.name != $s.oid and s.name.len > 0:
|
||||||
else: &"{shortLog(s.conn.peerInfo.peerId)}:{s.oid}"
|
&"{shortLog(s.conn.peerInfo.peerId)}:{s.oid}:{s.name}"
|
||||||
|
else: &"{shortLog(s.conn.peerInfo.peerId)}:{s.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(LPChannel): shortLog(it)
|
chronicles.formatIt(LPChannel): shortLog(it)
|
||||||
|
|
||||||
proc open*(s: LPChannel) {.async, gcsafe.} =
|
proc open*(s: LPChannel) {.async, gcsafe.} =
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import tables, sequtils, oids
|
import tables, sequtils, oids
|
||||||
import chronos, chronicles, stew/byteutils, metrics
|
import chronos, chronicles, stew/byteutils, metrics
|
||||||
import ../muxer,
|
import ../muxer,
|
||||||
|
@ -32,8 +34,8 @@ when defined(libp2p_expensive_metrics):
|
||||||
"mplex channels", labels = ["initiator", "peer"])
|
"mplex channels", labels = ["initiator", "peer"])
|
||||||
|
|
||||||
type
|
type
|
||||||
TooManyChannels* = object of CatchableError
|
TooManyChannels* = object of MuxerError
|
||||||
InvalidChannelIdError* = object of CatchableError
|
InvalidChannelIdError* = object of MuxerError
|
||||||
|
|
||||||
Mplex* = ref object of Muxer
|
Mplex* = ref object of Muxer
|
||||||
channels: array[bool, Table[uint64, LPChannel]]
|
channels: array[bool, Table[uint64, LPChannel]]
|
||||||
|
@ -44,7 +46,9 @@ type
|
||||||
oid*: Oid
|
oid*: Oid
|
||||||
maxChannCount: int
|
maxChannCount: int
|
||||||
|
|
||||||
func shortLog*(m: MPlex): auto = shortLog(m.connection)
|
func shortLog*(m: MPlex): auto =
|
||||||
|
shortLog(m.connection)
|
||||||
|
|
||||||
chronicles.formatIt(Mplex): shortLog(it)
|
chronicles.formatIt(Mplex): shortLog(it)
|
||||||
|
|
||||||
proc newTooManyChannels(): ref TooManyChannels =
|
proc newTooManyChannels(): ref TooManyChannels =
|
||||||
|
@ -66,17 +70,14 @@ proc cleanupChann(m: Mplex, chann: LPChannel) {.async, inline.} =
|
||||||
m.channels[chann.initiator].len.int64,
|
m.channels[chann.initiator].len.int64,
|
||||||
labelValues = [$chann.initiator, $m.connection.peerInfo.peerId])
|
labelValues = [$chann.initiator, $m.connection.peerInfo.peerId])
|
||||||
except CatchableError as exc:
|
except CatchableError as exc:
|
||||||
# This is top-level procedure which will work as separate task, so it
|
|
||||||
# do not need to propogate CancelledError, and no other exceptions should
|
|
||||||
# happen here
|
|
||||||
warn "Error cleaning up mplex channel", m, chann, msg = exc.msg
|
warn "Error cleaning up mplex channel", m, chann, msg = exc.msg
|
||||||
|
|
||||||
proc newStreamInternal*(m: Mplex,
|
proc newStreamInternal*(m: Mplex,
|
||||||
initiator: bool = true,
|
initiator: bool = true,
|
||||||
chanId: uint64 = 0,
|
chanId: uint64 = 0,
|
||||||
name: string = "",
|
name: string = "",
|
||||||
timeout: Duration):
|
timeout: Duration): LPChannel
|
||||||
LPChannel {.gcsafe.} =
|
{.gcsafe, raises: [Defect, InvalidChannelIdError].} =
|
||||||
## create new channel/stream
|
## create new channel/stream
|
||||||
##
|
##
|
||||||
let id = if initiator:
|
let id = if initiator:
|
||||||
|
@ -117,8 +118,6 @@ proc handleStream(m: Mplex, chann: LPChannel) {.async.} =
|
||||||
trace "finished handling stream", m, chann
|
trace "finished handling stream", m, chann
|
||||||
doAssert(chann.closed, "connection not closed by handler!")
|
doAssert(chann.closed, "connection not closed by handler!")
|
||||||
except CatchableError as exc:
|
except CatchableError as exc:
|
||||||
# This is top-level procedure which will work as separate task, so it
|
|
||||||
# do not need to propogate CancelledError.
|
|
||||||
trace "Exception in mplex stream handler", m, chann, msg = exc.msg
|
trace "Exception in mplex stream handler", m, chann, msg = exc.msg
|
||||||
await chann.reset()
|
await chann.reset()
|
||||||
|
|
||||||
|
@ -182,8 +181,6 @@ method handle*(m: Mplex) {.async, gcsafe.} =
|
||||||
of MessageType.ResetIn, MessageType.ResetOut:
|
of MessageType.ResetIn, MessageType.ResetOut:
|
||||||
await channel.reset()
|
await channel.reset()
|
||||||
except CancelledError:
|
except CancelledError:
|
||||||
# This procedure is spawned as task and it is not part of public API, so
|
|
||||||
# there no way for this procedure to be cancelled implicitly.
|
|
||||||
debug "Unexpected cancellation in mplex handler", m
|
debug "Unexpected cancellation in mplex handler", m
|
||||||
except LPStreamEOFError as exc:
|
except LPStreamEOFError as exc:
|
||||||
trace "Stream EOF", m, msg = exc.msg
|
trace "Stream EOF", m, msg = exc.msg
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import chronos, chronicles
|
import chronos, chronicles
|
||||||
import ../protocols/protocol,
|
import ../protocols/protocol,
|
||||||
../stream/connection,
|
../stream/connection,
|
||||||
|
@ -19,15 +21,17 @@ const
|
||||||
DefaultChanTimeout* = 5.minutes
|
DefaultChanTimeout* = 5.minutes
|
||||||
|
|
||||||
type
|
type
|
||||||
StreamHandler* = proc(conn: Connection): Future[void] {.gcsafe.}
|
MuxerError* = object of LPError
|
||||||
MuxerHandler* = proc(muxer: Muxer): Future[void] {.gcsafe.}
|
|
||||||
|
StreamHandler* = proc(conn: Connection): Future[void] {.gcsafe, raises: [Defect].}
|
||||||
|
MuxerHandler* = proc(muxer: Muxer): Future[void] {.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
Muxer* = ref object of RootObj
|
Muxer* = ref object of RootObj
|
||||||
streamHandler*: StreamHandler
|
streamHandler*: StreamHandler
|
||||||
connection*: Connection
|
connection*: Connection
|
||||||
|
|
||||||
# user provider proc that returns a constructed Muxer
|
# user provider proc that returns a constructed Muxer
|
||||||
MuxerConstructor* = proc(conn: Connection): Muxer {.gcsafe, closure.}
|
MuxerConstructor* = proc(conn: Connection): Muxer {.gcsafe, closure, raises: [Defect].}
|
||||||
|
|
||||||
# this wraps a creator proc that knows how to make muxers
|
# this wraps a creator proc that knows how to make muxers
|
||||||
MuxerProvider* = ref object of LPProtocol
|
MuxerProvider* = ref object of LPProtocol
|
||||||
|
|
|
@ -59,52 +59,89 @@ template postInit(peerinfo: PeerInfo,
|
||||||
if len(protocols) > 0:
|
if len(protocols) > 0:
|
||||||
peerinfo.protocols = @protocols
|
peerinfo.protocols = @protocols
|
||||||
|
|
||||||
proc init*(p: typedesc[PeerInfo],
|
proc init*(
|
||||||
key: PrivateKey,
|
p: typedesc[PeerInfo],
|
||||||
addrs: openarray[MultiAddress] = [],
|
key: PrivateKey,
|
||||||
protocols: openarray[string] = []): PeerInfo {.
|
addrs: openarray[MultiAddress] = [],
|
||||||
raises: [Defect, ResultError[cstring]].} =
|
protocols: openarray[string] = [],
|
||||||
result = PeerInfo(keyType: HasPrivate, peerId: PeerID.init(key).tryGet(),
|
protoVersion: string = "",
|
||||||
privateKey: key)
|
agentVersion: string = ""): PeerInfo =
|
||||||
result.postInit(addrs, protocols)
|
let peerInfo = PeerInfo(
|
||||||
|
keyType: HasPrivate,
|
||||||
|
peerId: PeerID.init(key).expect("Unable to create peer id from key"),
|
||||||
|
privateKey: key,
|
||||||
|
protoVersion: protoVersion,
|
||||||
|
agentVersion: agentVersion)
|
||||||
|
|
||||||
proc init*(p: typedesc[PeerInfo],
|
peerInfo.postInit(addrs, protocols)
|
||||||
peerId: PeerID,
|
return peerInfo
|
||||||
addrs: openarray[MultiAddress] = [],
|
|
||||||
protocols: openarray[string] = []): PeerInfo =
|
|
||||||
result = PeerInfo(keyType: HasPublic, peerId: peerId)
|
|
||||||
result.postInit(addrs, protocols)
|
|
||||||
|
|
||||||
proc init*(p: typedesc[PeerInfo],
|
proc init*(
|
||||||
peerId: string,
|
p: typedesc[PeerInfo],
|
||||||
addrs: openarray[MultiAddress] = [],
|
peerId: PeerID,
|
||||||
protocols: openarray[string] = []): PeerInfo {.
|
addrs: openarray[MultiAddress] = [],
|
||||||
raises: [Defect, ResultError[cstring]].} =
|
protocols: openarray[string] = [],
|
||||||
result = PeerInfo(keyType: HasPublic, peerId: PeerID.init(peerId).tryGet())
|
protoVersion: string = "",
|
||||||
result.postInit(addrs, protocols)
|
agentVersion: string = ""): PeerInfo =
|
||||||
|
let peerInfo = PeerInfo(
|
||||||
|
keyType: HasPublic,
|
||||||
|
peerId: peerId,
|
||||||
|
protoVersion: protoVersion,
|
||||||
|
agentVersion: agentVersion)
|
||||||
|
|
||||||
proc init*(p: typedesc[PeerInfo],
|
peerInfo.postInit(addrs, protocols)
|
||||||
key: PublicKey,
|
return peerInfo
|
||||||
addrs: openarray[MultiAddress] = [],
|
|
||||||
protocols: openarray[string] = []): PeerInfo {.
|
|
||||||
raises: [Defect, ResultError[cstring]].}=
|
|
||||||
result = PeerInfo(keyType: HasPublic,
|
|
||||||
peerId: PeerID.init(key).tryGet(),
|
|
||||||
key: some(key))
|
|
||||||
|
|
||||||
result.postInit(addrs, protocols)
|
proc init*(
|
||||||
|
p: typedesc[PeerInfo],
|
||||||
|
peerId: string,
|
||||||
|
addrs: openarray[MultiAddress] = [],
|
||||||
|
protocols: openarray[string] = [],
|
||||||
|
protoVersion: string = "",
|
||||||
|
agentVersion: string = ""): PeerInfo =
|
||||||
|
|
||||||
proc publicKey*(p: PeerInfo): Option[PublicKey] {.
|
let peerInfo = PeerInfo(
|
||||||
raises: [Defect, ResultError[CryptoError]].} =
|
keyType: HasPublic,
|
||||||
|
peerId: PeerID.init(peerId).expect("Unable to create peer id from string"),
|
||||||
|
protoVersion: protoVersion,
|
||||||
|
agentVersion: agentVersion)
|
||||||
|
|
||||||
|
peerInfo.postInit(addrs, protocols)
|
||||||
|
return peerInfo
|
||||||
|
|
||||||
|
proc init*(
|
||||||
|
p: typedesc[PeerInfo],
|
||||||
|
key: PublicKey,
|
||||||
|
addrs: openarray[MultiAddress] = [],
|
||||||
|
protocols: openarray[string] = [],
|
||||||
|
protoVersion: string = "",
|
||||||
|
agentVersion: string = ""): PeerInfo =
|
||||||
|
|
||||||
|
let peerInfo = PeerInfo(
|
||||||
|
keyType: HasPublic,
|
||||||
|
peerId: PeerID.init(key).expect("Unable to create peer id from public key"),
|
||||||
|
key: some(key),
|
||||||
|
protoVersion: protoVersion,
|
||||||
|
agentVersion: agentVersion)
|
||||||
|
|
||||||
|
peerInfo.postInit(addrs, protocols)
|
||||||
|
return peerInfo
|
||||||
|
|
||||||
|
proc publicKey*(p: PeerInfo): Option[PublicKey] =
|
||||||
|
var res = none(PublicKey)
|
||||||
if p.keyType == HasPublic:
|
if p.keyType == HasPublic:
|
||||||
if p.peerId.hasPublicKey():
|
if p.peerId.hasPublicKey():
|
||||||
var pubKey: PublicKey
|
var pubKey: PublicKey
|
||||||
if p.peerId.extractPublicKey(pubKey):
|
if p.peerId.extractPublicKey(pubKey):
|
||||||
result = some(pubKey)
|
res = some(pubKey)
|
||||||
elif p.key.isSome:
|
elif p.key.isSome:
|
||||||
result = p.key
|
res = p.key
|
||||||
else:
|
else:
|
||||||
result = some(p.privateKey.getKey().tryGet())
|
let pkeyRes = p.privateKey.getKey()
|
||||||
|
if pkeyRes.isOk:
|
||||||
|
res = some(pkeyRes.get())
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
func hash*(p: PeerInfo): Hash =
|
func hash*(p: PeerInfo): Hash =
|
||||||
cast[pointer](p).hash
|
cast[pointer](p).hash
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import options
|
import options
|
||||||
import chronos, chronicles
|
import chronos, chronicles
|
||||||
import ../protobuf/minprotobuf,
|
import ../protobuf/minprotobuf,
|
||||||
|
@ -16,7 +18,8 @@ import ../protobuf/minprotobuf,
|
||||||
../crypto/crypto,
|
../crypto/crypto,
|
||||||
../multiaddress,
|
../multiaddress,
|
||||||
../protocols/protocol,
|
../protocols/protocol,
|
||||||
../utility
|
../utility,
|
||||||
|
../errors
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "libp2p identify"
|
topics = "libp2p identify"
|
||||||
|
@ -30,9 +33,10 @@ const
|
||||||
#TODO: implement push identify, leaving out for now as it is not essential
|
#TODO: implement push identify, leaving out for now as it is not essential
|
||||||
|
|
||||||
type
|
type
|
||||||
IdentifyError* = object of CatchableError
|
IdentifyError* = object of LPError
|
||||||
IdentityNoMatchError* = object of IdentifyError
|
IdentityNoMatchError* = object of IdentifyError
|
||||||
IdentityInvalidMsgError* = object of IdentifyError
|
IdentityInvalidMsgError* = object of IdentifyError
|
||||||
|
IdentifyNoPubKeyError* = object of IdentifyError
|
||||||
|
|
||||||
IdentifyInfo* = object
|
IdentifyInfo* = object
|
||||||
pubKey*: Option[PublicKey]
|
pubKey*: Option[PublicKey]
|
||||||
|
@ -45,9 +49,13 @@ type
|
||||||
Identify* = ref object of LPProtocol
|
Identify* = ref object of LPProtocol
|
||||||
peerInfo*: PeerInfo
|
peerInfo*: PeerInfo
|
||||||
|
|
||||||
proc encodeMsg*(peerInfo: PeerInfo, observedAddr: Multiaddress): ProtoBuffer =
|
proc encodeMsg*(peerInfo: PeerInfo, observedAddr: Multiaddress): ProtoBuffer
|
||||||
|
{.raises: [Defect, IdentifyNoPubKeyError].} =
|
||||||
result = initProtoBuffer()
|
result = initProtoBuffer()
|
||||||
result.write(1, peerInfo.publicKey.get().getBytes().tryGet())
|
if peerInfo.publicKey.isNone:
|
||||||
|
raise newException(IdentifyNoPubKeyError, "No public key found for peer!")
|
||||||
|
|
||||||
|
result.write(1, peerInfo.publicKey.get().getBytes().get())
|
||||||
for ma in peerInfo.addrs:
|
for ma in peerInfo.addrs:
|
||||||
result.write(2, ma.data.buffer)
|
result.write(2, ma.data.buffer)
|
||||||
for proto in peerInfo.protocols:
|
for proto in peerInfo.protocols:
|
||||||
|
|
|
@ -7,13 +7,17 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import chronos
|
import chronos
|
||||||
import ../stream/connection
|
import ../stream/connection
|
||||||
|
|
||||||
type
|
type
|
||||||
LPProtoHandler* = proc (conn: Connection,
|
LPProtoHandler* = proc (
|
||||||
proto: string):
|
conn: Connection,
|
||||||
Future[void] {.gcsafe, closure.}
|
proto: string):
|
||||||
|
Future[void]
|
||||||
|
{.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
LPProtocol* = ref object of RootObj
|
LPProtocol* = ref object of RootObj
|
||||||
codecs*: seq[string]
|
codecs*: seq[string]
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[sequtils, sets, hashes, tables]
|
import std/[sequtils, sets, hashes, tables]
|
||||||
import chronos, chronicles, metrics, bearssl
|
import chronos, chronicles, metrics, bearssl
|
||||||
import ./pubsub,
|
import ./pubsub,
|
||||||
|
@ -201,7 +203,8 @@ method publish*(f: FloodSub,
|
||||||
|
|
||||||
return peers.len
|
return peers.len
|
||||||
|
|
||||||
method initPubSub*(f: FloodSub) =
|
method initPubSub*(f: FloodSub)
|
||||||
|
{.raises: [Defect, InitializationError].} =
|
||||||
procCall PubSub(f).initPubSub()
|
procCall PubSub(f).initPubSub()
|
||||||
f.seen = TimedCache[MessageID].init(2.minutes)
|
f.seen = TimedCache[MessageID].init(2.minutes)
|
||||||
var rng = newRng()
|
var rng = newRng()
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[tables, sets, options, sequtils, random]
|
import std/[tables, sets, options, sequtils, random]
|
||||||
import chronos, chronicles, metrics
|
import chronos, chronicles, metrics
|
||||||
import ./pubsub,
|
import ./pubsub,
|
||||||
|
@ -26,10 +28,9 @@ import ./pubsub,
|
||||||
import stew/results
|
import stew/results
|
||||||
export results
|
export results
|
||||||
|
|
||||||
import gossipsub/[types, scoring, behavior]
|
import ./gossipsub/[types, scoring, behavior]
|
||||||
export types
|
|
||||||
export scoring
|
export types, scoring, behavior, pubsub
|
||||||
export behavior
|
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "libp2p gossipsub"
|
topics = "libp2p gossipsub"
|
||||||
|
@ -536,13 +537,16 @@ method stop*(g: GossipSub) {.async.} =
|
||||||
trace "heartbeat stopped"
|
trace "heartbeat stopped"
|
||||||
g.heartbeatFut = nil
|
g.heartbeatFut = nil
|
||||||
|
|
||||||
method initPubSub*(g: GossipSub) =
|
method initPubSub*(g: GossipSub)
|
||||||
|
{.raises: [Defect, InitializationError].} =
|
||||||
procCall FloodSub(g).initPubSub()
|
procCall FloodSub(g).initPubSub()
|
||||||
|
|
||||||
if not g.parameters.explicit:
|
if not g.parameters.explicit:
|
||||||
g.parameters = GossipSubParams.init()
|
g.parameters = GossipSubParams.init()
|
||||||
|
|
||||||
g.parameters.validateParameters().tryGet()
|
let validationRes = g.parameters.validateParameters()
|
||||||
|
if validationRes.isErr:
|
||||||
|
raise newException(InitializationError, $validationRes.error)
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,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].} TODO compile error on windows due to chronicles?
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import std/[tables, sequtils, sets, algorithm]
|
import std/[tables, sequtils, sets, algorithm]
|
||||||
import random # for shuffle
|
import random # for shuffle
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
## Nim-LibP2P
|
||||||
|
## Copyright (c) 2021 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.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import chronos
|
import chronos
|
||||||
import std/[tables, sets]
|
import std/[tables, sets]
|
||||||
import ".."/[floodsub, peertable, mcache, pubsubpeer]
|
import ".."/[floodsub, peertable, mcache, pubsubpeer]
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[tables, sequtils, sets, strutils]
|
import std/[tables, sequtils, sets, strutils]
|
||||||
import chronos, chronicles, metrics
|
import chronos, chronicles, metrics
|
||||||
import ./pubsubpeer,
|
import ./pubsubpeer,
|
||||||
|
@ -68,6 +70,8 @@ declarePublicCounter(libp2p_pubsub_received_graft, "pubsub broadcast graft", lab
|
||||||
declarePublicCounter(libp2p_pubsub_received_prune, "pubsub broadcast prune", labels = ["topic"])
|
declarePublicCounter(libp2p_pubsub_received_prune, "pubsub broadcast prune", labels = ["topic"])
|
||||||
|
|
||||||
type
|
type
|
||||||
|
InitializationError* = object of LPError
|
||||||
|
|
||||||
TopicHandler* = proc(topic: string,
|
TopicHandler* = proc(topic: string,
|
||||||
data: seq[byte]): Future[void] {.gcsafe, raises: [Defect].}
|
data: seq[byte]): Future[void] {.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
|
@ -468,7 +472,8 @@ method publish*(p: PubSub,
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
method initPubSub*(p: PubSub) {.base.} =
|
method initPubSub*(p: PubSub)
|
||||||
|
{.base, raises: [Defect, InitializationError].} =
|
||||||
## perform pubsub initialization
|
## perform pubsub initialization
|
||||||
p.observers = new(seq[PubSubObserver])
|
p.observers = new(seq[PubSubObserver])
|
||||||
if p.msgIdProvider == nil:
|
if p.msgIdProvider == nil:
|
||||||
|
@ -538,7 +543,8 @@ proc init*[PubParams: object | bool](
|
||||||
sign: bool = true,
|
sign: bool = true,
|
||||||
msgIdProvider: MsgIdProvider = defaultMsgIdProvider,
|
msgIdProvider: MsgIdProvider = defaultMsgIdProvider,
|
||||||
subscriptionValidator: SubscriptionValidator = nil,
|
subscriptionValidator: SubscriptionValidator = nil,
|
||||||
parameters: PubParams = false): P =
|
parameters: PubParams = false): P
|
||||||
|
{.raises: [Defect, InitializationError].} =
|
||||||
let pubsub =
|
let pubsub =
|
||||||
when PubParams is bool:
|
when PubParams is bool:
|
||||||
P(switch: switch,
|
P(switch: switch,
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[sequtils, strutils, tables, hashes]
|
import std/[sequtils, strutils, tables, hashes]
|
||||||
import chronos, chronicles, nimcrypto/sha2, metrics
|
import chronos, chronicles, nimcrypto/sha2, metrics
|
||||||
import rpc/[messages, message, protobuf],
|
import rpc/[messages, message, protobuf],
|
||||||
|
@ -40,9 +42,9 @@ type
|
||||||
PubsubPeerEvent* = object
|
PubsubPeerEvent* = object
|
||||||
kind*: PubSubPeerEventKind
|
kind*: PubSubPeerEventKind
|
||||||
|
|
||||||
GetConn* = proc(): Future[Connection] {.gcsafe.}
|
GetConn* = proc(): Future[Connection] {.gcsafe, raises: [Defect].}
|
||||||
DropConn* = proc(peer: PubsubPeer) {.gcsafe.} # have to pass peer as it's unknown during init
|
DropConn* = proc(peer: PubsubPeer) {.gcsafe, raises: [Defect].} # have to pass peer as it's unknown during init
|
||||||
OnEvent* = proc(peer: PubSubPeer, event: PubsubPeerEvent) {.gcsafe.}
|
OnEvent* = proc(peer: PubSubPeer, event: PubsubPeerEvent) {.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
PubSubPeer* = ref object of RootObj
|
PubSubPeer* = ref object of RootObj
|
||||||
getConn*: GetConn # callback to establish a new send connection
|
getConn*: GetConn # callback to establish a new send connection
|
||||||
|
@ -64,7 +66,8 @@ type
|
||||||
when defined(libp2p_agents_metrics):
|
when defined(libp2p_agents_metrics):
|
||||||
shortAgent*: string
|
shortAgent*: string
|
||||||
|
|
||||||
RPCHandler* = proc(peer: PubSubPeer, msg: RPCMsg): Future[void] {.gcsafe.}
|
RPCHandler* = proc(peer: PubSubPeer, msg: RPCMsg): Future[void]
|
||||||
|
{.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
func hash*(p: PubSubPeer): Hash =
|
func hash*(p: PubSubPeer): Hash =
|
||||||
p.peerId.hash
|
p.peerId.hash
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import options, sequtils
|
import options, sequtils
|
||||||
import ../../../utility
|
import ../../../utility
|
||||||
import ../../../peerid
|
import ../../../peerid
|
||||||
|
@ -17,7 +19,7 @@ type
|
||||||
PeerInfoMsg* = object
|
PeerInfoMsg* = object
|
||||||
peerID*: seq[byte]
|
peerID*: seq[byte]
|
||||||
signedPeerRecord*: seq[byte]
|
signedPeerRecord*: seq[byte]
|
||||||
|
|
||||||
SubOpts* = object
|
SubOpts* = object
|
||||||
subscribe*: bool
|
subscribe*: bool
|
||||||
topic*: string
|
topic*: string
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import options
|
import options
|
||||||
import stew/assign2
|
import stew/assign2
|
||||||
import chronicles
|
import chronicles
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[tables]
|
import std/[tables]
|
||||||
|
|
||||||
import chronos/timer
|
import chronos/timer
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[oids, strformat]
|
import std/[oids, strformat]
|
||||||
import chronos
|
import chronos
|
||||||
import chronicles
|
import chronicles
|
||||||
|
@ -18,8 +20,10 @@ import ../../peerid
|
||||||
import ../../peerinfo
|
import ../../peerinfo
|
||||||
import ../../protobuf/minprotobuf
|
import ../../protobuf/minprotobuf
|
||||||
import ../../utility
|
import ../../utility
|
||||||
|
import ../../errors
|
||||||
|
|
||||||
import secure,
|
import secure,
|
||||||
../../crypto/[crypto, chacha20poly1305, curve25519, hkdf]
|
../../crypto/[crypto, chacha20poly1305, curve25519, hkdf]
|
||||||
|
|
||||||
when defined(libp2p_dump):
|
when defined(libp2p_dump):
|
||||||
import ../../debugutils
|
import ../../debugutils
|
||||||
|
@ -85,17 +89,22 @@ type
|
||||||
readCs: CipherState
|
readCs: CipherState
|
||||||
writeCs: CipherState
|
writeCs: CipherState
|
||||||
|
|
||||||
NoiseHandshakeError* = object of CatchableError
|
NoiseError* = object of LPError
|
||||||
NoiseDecryptTagError* = object of CatchableError
|
NoiseHandshakeError* = object of NoiseError
|
||||||
NoiseOversizedPayloadError* = object of CatchableError
|
NoiseDecryptTagError* = object of NoiseError
|
||||||
NoiseNonceMaxError* = object of CatchableError # drop connection on purpose
|
NoiseOversizedPayloadError* = object of NoiseError
|
||||||
|
NoiseNonceMaxError* = object of NoiseError # drop connection on purpose
|
||||||
|
|
||||||
# Utility
|
# Utility
|
||||||
|
|
||||||
func shortLog*(conn: NoiseConnection): auto =
|
func shortLog*(conn: NoiseConnection): auto =
|
||||||
if conn.isNil: "NoiseConnection(nil)"
|
try:
|
||||||
elif conn.peerInfo.isNil: $conn.oid
|
if conn.isNil: "NoiseConnection(nil)"
|
||||||
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
elif conn.peerInfo.isNil: $conn.oid
|
||||||
|
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(NoiseConnection): shortLog(it)
|
chronicles.formatIt(NoiseConnection): shortLog(it)
|
||||||
|
|
||||||
proc genKeyPair(rng: var BrHmacDrbgContext): KeyPair =
|
proc genKeyPair(rng: var BrHmacDrbgContext): KeyPair =
|
||||||
|
@ -122,8 +131,11 @@ proc hasKey(cs: CipherState): bool =
|
||||||
cs.k != EmptyKey
|
cs.k != EmptyKey
|
||||||
|
|
||||||
proc encrypt(
|
proc encrypt(
|
||||||
state: var CipherState, data: var openArray[byte],
|
state: var CipherState,
|
||||||
ad: openArray[byte]): ChaChaPolyTag {.noinit.} =
|
data: var openArray[byte],
|
||||||
|
ad: openArray[byte]): ChaChaPolyTag
|
||||||
|
{.noinit, raises: [Defect, NoiseNonceMaxError].} =
|
||||||
|
|
||||||
var nonce: ChaChaPolyNonce
|
var nonce: ChaChaPolyNonce
|
||||||
nonce[4..<12] = toBytesLE(state.n)
|
nonce[4..<12] = toBytesLE(state.n)
|
||||||
|
|
||||||
|
@ -133,7 +145,8 @@ proc encrypt(
|
||||||
if state.n > NonceMax:
|
if state.n > NonceMax:
|
||||||
raise newException(NoiseNonceMaxError, "Noise max nonce value reached")
|
raise newException(NoiseNonceMaxError, "Noise max nonce value reached")
|
||||||
|
|
||||||
proc encryptWithAd(state: var CipherState, ad, data: openArray[byte]): seq[byte] =
|
proc encryptWithAd(state: var CipherState, ad, data: openArray[byte]): seq[byte]
|
||||||
|
{.raises: [Defect, NoiseNonceMaxError].} =
|
||||||
result = newSeqOfCap[byte](data.len + sizeof(ChachaPolyTag))
|
result = newSeqOfCap[byte](data.len + sizeof(ChachaPolyTag))
|
||||||
result.add(data)
|
result.add(data)
|
||||||
|
|
||||||
|
@ -144,7 +157,8 @@ proc encryptWithAd(state: var CipherState, ad, data: openArray[byte]): seq[byte]
|
||||||
trace "encryptWithAd",
|
trace "encryptWithAd",
|
||||||
tag = byteutils.toHex(tag), data = result.shortLog, nonce = state.n - 1
|
tag = byteutils.toHex(tag), data = result.shortLog, nonce = state.n - 1
|
||||||
|
|
||||||
proc decryptWithAd(state: var CipherState, ad, data: openArray[byte]): seq[byte] =
|
proc decryptWithAd(state: var CipherState, ad, data: openArray[byte]): seq[byte]
|
||||||
|
{.raises: [Defect, NoiseDecryptTagError, NoiseNonceMaxError].} =
|
||||||
var
|
var
|
||||||
tagIn = data.toOpenArray(data.len - ChaChaPolyTag.len, data.high).intoChaChaPolyTag
|
tagIn = data.toOpenArray(data.len - ChaChaPolyTag.len, data.high).intoChaChaPolyTag
|
||||||
tagOut: ChaChaPolyTag
|
tagOut: ChaChaPolyTag
|
||||||
|
@ -192,7 +206,8 @@ proc mixKeyAndHash(ss: var SymmetricState; ikm: openArray[byte]) {.used.} =
|
||||||
ss.mixHash(temp_keys[1])
|
ss.mixHash(temp_keys[1])
|
||||||
ss.cs = CipherState(k: temp_keys[2])
|
ss.cs = CipherState(k: temp_keys[2])
|
||||||
|
|
||||||
proc encryptAndHash(ss: var SymmetricState, data: openArray[byte]): seq[byte] =
|
proc encryptAndHash(ss: var SymmetricState, data: openArray[byte]): seq[byte]
|
||||||
|
{.raises: [Defect, NoiseNonceMaxError].} =
|
||||||
# according to spec if key is empty leave plaintext
|
# according to spec if key is empty leave plaintext
|
||||||
if ss.cs.hasKey:
|
if ss.cs.hasKey:
|
||||||
result = ss.cs.encryptWithAd(ss.h.data, data)
|
result = ss.cs.encryptWithAd(ss.h.data, data)
|
||||||
|
@ -200,7 +215,8 @@ proc encryptAndHash(ss: var SymmetricState, data: openArray[byte]): seq[byte] =
|
||||||
result = @data
|
result = @data
|
||||||
ss.mixHash(result)
|
ss.mixHash(result)
|
||||||
|
|
||||||
proc decryptAndHash(ss: var SymmetricState, data: openArray[byte]): seq[byte] =
|
proc decryptAndHash(ss: var SymmetricState, data: openArray[byte]): seq[byte]
|
||||||
|
{.raises: [Defect, NoiseDecryptTagError, NoiseNonceMaxError].} =
|
||||||
# according to spec if key is empty leave plaintext
|
# according to spec if key is empty leave plaintext
|
||||||
if ss.cs.hasKey:
|
if ss.cs.hasKey:
|
||||||
result = ss.cs.decryptWithAd(ss.h.data, data)
|
result = ss.cs.decryptWithAd(ss.h.data, data)
|
||||||
|
@ -429,7 +445,10 @@ method readMessage*(sconn: NoiseConnection): Future[seq[byte]] {.async.} =
|
||||||
|
|
||||||
|
|
||||||
proc encryptFrame(
|
proc encryptFrame(
|
||||||
sconn: NoiseConnection, cipherFrame: var openArray[byte], src: openArray[byte]) =
|
sconn: NoiseConnection,
|
||||||
|
cipherFrame: var openArray[byte],
|
||||||
|
src: openArray[byte])
|
||||||
|
{.raises: [Defect, NoiseNonceMaxError].} =
|
||||||
# Frame consists of length + cipher data + tag
|
# Frame consists of length + cipher data + tag
|
||||||
doAssert src.len <= MaxPlainSize
|
doAssert src.len <= MaxPlainSize
|
||||||
doAssert cipherFrame.len == 2 + src.len + sizeof(ChaChaPolyTag)
|
doAssert cipherFrame.len == 2 + src.len + sizeof(ChaChaPolyTag)
|
||||||
|
@ -581,12 +600,19 @@ proc newNoise*(
|
||||||
privateKey: PrivateKey;
|
privateKey: PrivateKey;
|
||||||
outgoing: bool = true;
|
outgoing: bool = true;
|
||||||
commonPrologue: seq[byte] = @[]): Noise =
|
commonPrologue: seq[byte] = @[]): Noise =
|
||||||
result = Noise(
|
|
||||||
|
let pkBytes = privateKey.getKey()
|
||||||
|
.expect("Expected valid private key")
|
||||||
|
.getBytes()
|
||||||
|
.expect("Couldn't get key bytes")
|
||||||
|
var noise = Noise(
|
||||||
rng: rng,
|
rng: rng,
|
||||||
outgoing: outgoing,
|
outgoing: outgoing,
|
||||||
localPrivateKey: privateKey,
|
localPrivateKey: privateKey,
|
||||||
localPublicKey: privateKey.getKey().tryGet().getBytes().tryGet(),
|
localPublicKey: pkBytes,
|
||||||
noiseKeys: genKeyPair(rng[]),
|
noiseKeys: genKeyPair(rng[]),
|
||||||
commonPrologue: commonPrologue,
|
commonPrologue: commonPrologue,
|
||||||
)
|
)
|
||||||
result.init()
|
|
||||||
|
noise.init()
|
||||||
|
return noise
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import chronos
|
import chronos
|
||||||
import secure, ../../stream/connection
|
import secure, ../../stream/connection
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
## at your option.
|
## at your option.
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[oids, strformat]
|
import std/[oids, strformat]
|
||||||
import chronos, chronicles, stew/endians2, bearssl
|
import chronos, chronicles, stew/endians2, bearssl
|
||||||
import nimcrypto/[hmac, sha2, sha, hash, rijndael, twofish, bcmode]
|
import nimcrypto/[hmac, sha2, sha, hash, rijndael, twofish, bcmode]
|
||||||
|
@ -15,7 +18,8 @@ import secure,
|
||||||
../../crypto/crypto,
|
../../crypto/crypto,
|
||||||
../../crypto/ecnist,
|
../../crypto/ecnist,
|
||||||
../../peerid,
|
../../peerid,
|
||||||
../../utility
|
../../utility,
|
||||||
|
../../errors
|
||||||
|
|
||||||
export hmac, sha2, sha, hash, rijndael, bcmode
|
export hmac, sha2, sha, hash, rijndael, bcmode
|
||||||
|
|
||||||
|
@ -68,12 +72,16 @@ type
|
||||||
writerCoder: SecureCipher
|
writerCoder: SecureCipher
|
||||||
readerCoder: SecureCipher
|
readerCoder: SecureCipher
|
||||||
|
|
||||||
SecioError* = object of CatchableError
|
SecioError* = object of LPError
|
||||||
|
|
||||||
func shortLog*(conn: SecioConn): auto =
|
func shortLog*(conn: SecioConn): auto =
|
||||||
if conn.isNil: "SecioConn(nil)"
|
try:
|
||||||
elif conn.peerInfo.isNil: $conn.oid
|
if conn.isNil: "SecioConn(nil)"
|
||||||
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
elif conn.peerInfo.isNil: $conn.oid
|
||||||
|
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(SecioConn): shortLog(it)
|
chronicles.formatIt(SecioConn): shortLog(it)
|
||||||
|
|
||||||
proc init(mac: var SecureMac, hash: string, key: openarray[byte]) =
|
proc init(mac: var SecureMac, hash: string, key: openarray[byte]) =
|
||||||
|
@ -250,7 +258,8 @@ proc newSecioConn(conn: Connection,
|
||||||
cipher: string,
|
cipher: string,
|
||||||
secrets: Secret,
|
secrets: Secret,
|
||||||
order: int,
|
order: int,
|
||||||
remotePubKey: PublicKey): SecioConn =
|
remotePubKey: PublicKey): SecioConn
|
||||||
|
{.raises: [Defect, SecioError].} =
|
||||||
## 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``.
|
||||||
|
@ -259,7 +268,7 @@ proc newSecioConn(conn: Connection,
|
||||||
if conn.peerInfo != nil:
|
if conn.peerInfo != nil:
|
||||||
conn.peerInfo
|
conn.peerInfo
|
||||||
else:
|
else:
|
||||||
PeerInfo.init(PeerID.init(remotePubKey).tryGet())
|
PeerInfo.init(remotePubKey)
|
||||||
|
|
||||||
result = SecioConn.init(conn, conn.peerInfo, conn.observedAddr)
|
result = SecioConn.init(conn, conn.peerInfo, conn.observedAddr)
|
||||||
|
|
||||||
|
@ -423,9 +432,13 @@ method init(s: Secio) {.gcsafe.} =
|
||||||
s.codec = SecioCodec
|
s.codec = SecioCodec
|
||||||
|
|
||||||
proc newSecio*(rng: ref BrHmacDrbgContext, localPrivateKey: PrivateKey): Secio =
|
proc newSecio*(rng: ref BrHmacDrbgContext, localPrivateKey: PrivateKey): Secio =
|
||||||
|
let pkRes = localPrivateKey.getKey()
|
||||||
|
if pkRes.isErr:
|
||||||
|
raise newException(Defect, "Can't fetch local private key")
|
||||||
|
|
||||||
result = Secio(
|
result = Secio(
|
||||||
rng: rng,
|
rng: rng,
|
||||||
localPrivateKey: localPrivateKey,
|
localPrivateKey: localPrivateKey,
|
||||||
localPublicKey: localPrivateKey.getKey().tryGet(),
|
localPublicKey: localPrivateKey.getKey().get(),
|
||||||
)
|
)
|
||||||
result.init()
|
result.init()
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[options, strformat]
|
import std/[options, strformat]
|
||||||
import chronos, chronicles, bearssl
|
import chronos, chronicles, bearssl
|
||||||
import ../protocol,
|
import ../protocol,
|
||||||
|
@ -32,9 +34,13 @@ type
|
||||||
buf: StreamSeq
|
buf: StreamSeq
|
||||||
|
|
||||||
func shortLog*(conn: SecureConn): auto =
|
func shortLog*(conn: SecureConn): auto =
|
||||||
if conn.isNil: "SecureConn(nil)"
|
try:
|
||||||
elif conn.peerInfo.isNil: $conn.oid
|
if conn.isNil: "SecureConn(nil)"
|
||||||
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
elif conn.peerInfo.isNil: $conn.oid
|
||||||
|
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(SecureConn): shortLog(it)
|
chronicles.formatIt(SecureConn): shortLog(it)
|
||||||
|
|
||||||
proc init*(T: type SecureConn,
|
proc init*(T: type SecureConn,
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/strformat
|
import std/strformat
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import chronos, chronicles, metrics
|
import chronos, chronicles, metrics
|
||||||
|
@ -34,9 +36,13 @@ type
|
||||||
returnedEof*: bool # 0-byte readOnce has been completed
|
returnedEof*: bool # 0-byte readOnce has been completed
|
||||||
|
|
||||||
func shortLog*(s: BufferStream): auto =
|
func shortLog*(s: BufferStream): auto =
|
||||||
if s.isNil: "BufferStream(nil)"
|
try:
|
||||||
elif s.peerInfo.isNil: $s.oid
|
if s.isNil: "BufferStream(nil)"
|
||||||
else: &"{shortLog(s.peerInfo.peerId)}:{s.oid}"
|
elif s.peerInfo.isNil: $s.oid
|
||||||
|
else: &"{shortLog(s.peerInfo.peerId)}:{s.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(BufferStream): shortLog(it)
|
chronicles.formatIt(BufferStream): shortLog(it)
|
||||||
|
|
||||||
proc len*(s: BufferStream): int =
|
proc len*(s: BufferStream): int =
|
||||||
|
@ -190,14 +196,17 @@ method closeImpl*(s: BufferStream): Future[void] =
|
||||||
# ------------|----------|-------
|
# ------------|----------|-------
|
||||||
# Reading | Push Eof | Na
|
# Reading | Push Eof | Na
|
||||||
# Pushing | Na | Pop
|
# Pushing | Na | Pop
|
||||||
if not(s.reading and s.pushing):
|
try:
|
||||||
if s.reading:
|
if not(s.reading and s.pushing):
|
||||||
if s.readQueue.empty():
|
if s.reading:
|
||||||
# There is an active reader
|
if s.readQueue.empty():
|
||||||
s.readQueue.addLastNoWait(Eof)
|
# There is an active reader
|
||||||
elif s.pushing:
|
s.readQueue.addLastNoWait(Eof)
|
||||||
if not s.readQueue.empty():
|
elif s.pushing:
|
||||||
discard s.readQueue.popFirstNoWait()
|
if not s.readQueue.empty():
|
||||||
|
discard s.readQueue.popFirstNoWait()
|
||||||
|
except AsyncQueueFullError, AsyncQueueEmptyError:
|
||||||
|
raise newException(Defect, getCurrentExceptionMsg())
|
||||||
|
|
||||||
trace "Closed BufferStream", s
|
trace "Closed BufferStream", s
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[oids, strformat]
|
import std/[oids, strformat]
|
||||||
import chronos, chronicles, metrics
|
import chronos, chronicles, metrics
|
||||||
import connection
|
import connection
|
||||||
|
@ -31,10 +33,14 @@ when defined(libp2p_agents_metrics):
|
||||||
declareCounter(libp2p_peers_traffic_read, "incoming traffic", labels = ["agent"])
|
declareCounter(libp2p_peers_traffic_read, "incoming traffic", labels = ["agent"])
|
||||||
declareCounter(libp2p_peers_traffic_write, "outgoing traffic", labels = ["agent"])
|
declareCounter(libp2p_peers_traffic_write, "outgoing traffic", labels = ["agent"])
|
||||||
|
|
||||||
func shortLog*(conn: ChronosStream): string =
|
func shortLog*(conn: ChronosStream): auto =
|
||||||
if conn.isNil: "ChronosStream(nil)"
|
try:
|
||||||
elif conn.peerInfo.isNil: $conn.oid
|
if conn.isNil: "ChronosStream(nil)"
|
||||||
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
elif conn.peerInfo.isNil: $conn.oid
|
||||||
|
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(ChronosStream): shortLog(it)
|
chronicles.formatIt(ChronosStream): shortLog(it)
|
||||||
|
|
||||||
method initStream*(s: ChronosStream) =
|
method initStream*(s: ChronosStream) =
|
||||||
|
@ -126,10 +132,10 @@ method write*(s: ChronosStream, msg: seq[byte]) {.async.} =
|
||||||
if s.tracked:
|
if s.tracked:
|
||||||
libp2p_peers_traffic_write.inc(msg.len.int64, labelValues = [s.shortAgent])
|
libp2p_peers_traffic_write.inc(msg.len.int64, labelValues = [s.shortAgent])
|
||||||
|
|
||||||
method closed*(s: ChronosStream): bool {.raises: [Defect].} =
|
method closed*(s: ChronosStream): bool =
|
||||||
result = s.client.closed
|
result = s.client.closed
|
||||||
|
|
||||||
method atEof*(s: ChronosStream): bool {.raises: [Defect].} =
|
method atEof*(s: ChronosStream): bool =
|
||||||
s.client.atEof()
|
s.client.atEof()
|
||||||
|
|
||||||
method closeImpl*(s: ChronosStream) {.async.} =
|
method closeImpl*(s: ChronosStream) {.async.} =
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[hashes, oids, strformat]
|
import std/[hashes, oids, strformat]
|
||||||
import chronicles, chronos, metrics
|
import chronicles, chronos, metrics
|
||||||
import lpstream,
|
import lpstream,
|
||||||
|
@ -23,7 +25,7 @@ const
|
||||||
DefaultConnectionTimeout* = 5.minutes
|
DefaultConnectionTimeout* = 5.minutes
|
||||||
|
|
||||||
type
|
type
|
||||||
TimeoutHandler* = proc(): Future[void] {.gcsafe.}
|
TimeoutHandler* = proc(): Future[void] {.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
Connection* = ref object of LPStream
|
Connection* = ref object of LPStream
|
||||||
activity*: bool # reset every time data is sent or received
|
activity*: bool # reset every time data is sent or received
|
||||||
|
@ -54,9 +56,13 @@ proc onUpgrade*(s: Connection) {.async.} =
|
||||||
await s.upgraded
|
await s.upgraded
|
||||||
|
|
||||||
func shortLog*(conn: Connection): string =
|
func shortLog*(conn: Connection): string =
|
||||||
if conn.isNil: "Connection(nil)"
|
try:
|
||||||
elif conn.peerInfo.isNil: $conn.oid
|
if conn.isNil: "Connection(nil)"
|
||||||
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
elif conn.peerInfo.isNil: $conn.oid
|
||||||
|
else: &"{shortLog(conn.peerInfo.peerId)}:{conn.oid}"
|
||||||
|
except ValueError as exc:
|
||||||
|
raiseAssert(exc.msg)
|
||||||
|
|
||||||
chronicles.formatIt(Connection): shortLog(it)
|
chronicles.formatIt(Connection): shortLog(it)
|
||||||
|
|
||||||
method initStream*(s: Connection) =
|
method initStream*(s: Connection) =
|
||||||
|
|
|
@ -7,12 +7,15 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/oids
|
import std/oids
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import chronicles, chronos, metrics
|
import chronicles, chronos, metrics
|
||||||
import ../varint,
|
import ../varint,
|
||||||
../peerinfo,
|
../peerinfo,
|
||||||
../multiaddress
|
../multiaddress,
|
||||||
|
../errors
|
||||||
|
|
||||||
declareGauge(libp2p_open_streams,
|
declareGauge(libp2p_open_streams,
|
||||||
"open stream instances", labels = ["type", "dir"])
|
"open stream instances", labels = ["type", "dir"])
|
||||||
|
@ -39,7 +42,7 @@ type
|
||||||
dir*: Direction
|
dir*: Direction
|
||||||
closedWithEOF: bool # prevent concurrent calls
|
closedWithEOF: bool # prevent concurrent calls
|
||||||
|
|
||||||
LPStreamError* = object of CatchableError
|
LPStreamError* = object of LPError
|
||||||
LPStreamIncompleteError* = object of LPStreamError
|
LPStreamIncompleteError* = object of LPStreamError
|
||||||
LPStreamIncorrectDefect* = object of Defect
|
LPStreamIncorrectDefect* = object of Defect
|
||||||
LPStreamLimitError* = object of LPStreamError
|
LPStreamLimitError* = object of LPStreamError
|
||||||
|
@ -96,19 +99,19 @@ proc newLPStreamWriteError*(p: ref CatchableError): ref CatchableError =
|
||||||
w.par = p
|
w.par = p
|
||||||
result = w
|
result = w
|
||||||
|
|
||||||
proc newLPStreamIncompleteError*(): ref CatchableError =
|
proc newLPStreamIncompleteError*(): ref LPStreamIncompleteError =
|
||||||
result = newException(LPStreamIncompleteError, "Incomplete data received")
|
result = newException(LPStreamIncompleteError, "Incomplete data received")
|
||||||
|
|
||||||
proc newLPStreamLimitError*(): ref CatchableError =
|
proc newLPStreamLimitError*(): ref LPStreamLimitError =
|
||||||
result = newException(LPStreamLimitError, "Buffer limit reached")
|
result = newException(LPStreamLimitError, "Buffer limit reached")
|
||||||
|
|
||||||
proc newLPStreamIncorrectDefect*(m: string): ref Defect =
|
proc newLPStreamIncorrectDefect*(m: string): ref LPStreamIncorrectDefect =
|
||||||
result = newException(LPStreamIncorrectDefect, m)
|
result = newException(LPStreamIncorrectDefect, m)
|
||||||
|
|
||||||
proc newLPStreamEOFError*(): ref CatchableError =
|
proc newLPStreamEOFError*(): ref LPStreamEOFError =
|
||||||
result = newException(LPStreamEOFError, "Stream EOF!")
|
result = newException(LPStreamEOFError, "Stream EOF!")
|
||||||
|
|
||||||
proc newLPStreamClosedError*(): ref Exception =
|
proc newLPStreamClosedError*(): ref LPStreamClosedError =
|
||||||
result = newException(LPStreamClosedError, "Stream Closed!")
|
result = newException(LPStreamClosedError, "Stream Closed!")
|
||||||
|
|
||||||
func shortLog*(s: LPStream): auto =
|
func shortLog*(s: LPStream): auto =
|
||||||
|
@ -130,17 +133,17 @@ method initStream*(s: LPStream) {.base.} =
|
||||||
proc join*(s: LPStream): Future[void] =
|
proc join*(s: LPStream): Future[void] =
|
||||||
s.closeEvent.wait()
|
s.closeEvent.wait()
|
||||||
|
|
||||||
method closed*(s: LPStream): bool {.base, raises: [Defect].} =
|
method closed*(s: LPStream): bool {.base.} =
|
||||||
s.isClosed
|
s.isClosed
|
||||||
|
|
||||||
method atEof*(s: LPStream): bool {.base, raises: [Defect].} =
|
method atEof*(s: LPStream): bool {.base.} =
|
||||||
s.isEof
|
s.isEof
|
||||||
|
|
||||||
method readOnce*(s: LPStream,
|
method readOnce*(
|
||||||
pbytes: pointer,
|
s: LPStream,
|
||||||
nbytes: int):
|
pbytes: pointer,
|
||||||
Future[int]
|
nbytes: int):
|
||||||
{.base, async.} =
|
Future[int] {.base, async.} =
|
||||||
doAssert(false, "not implemented!")
|
doAssert(false, "not implemented!")
|
||||||
|
|
||||||
proc readExactly*(s: LPStream,
|
proc readExactly*(s: LPStream,
|
||||||
|
@ -236,7 +239,7 @@ proc readLp*(s: LPStream, maxSize: int): Future[seq[byte]] {.async, gcsafe.} =
|
||||||
await s.readExactly(addr res[0], res.len)
|
await s.readExactly(addr res[0], res.len)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
method write*(s: LPStream, msg: seq[byte]): Future[void] {.base, raises: [Defect].} =
|
method write*(s: LPStream, msg: seq[byte]): Future[void] {.base.} =
|
||||||
doAssert(false, "not implemented!")
|
doAssert(false, "not implemented!")
|
||||||
|
|
||||||
proc writeLp*(s: LPStream, msg: openArray[byte]): Future[void] =
|
proc writeLp*(s: LPStream, msg: openArray[byte]): Future[void] =
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import stew/bitops2
|
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
import stew/bitops2
|
||||||
|
|
||||||
type
|
type
|
||||||
StreamSeq* = object
|
StreamSeq* = object
|
||||||
# Seq adapted to the stream use case where we add data at the back and
|
# Seq adapted to the stream use case where we add data at the back and
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[tables,
|
import std/[tables,
|
||||||
options,
|
options,
|
||||||
sets,
|
sets,
|
||||||
|
@ -54,7 +56,7 @@ const
|
||||||
ConcurrentUpgrades* = 4
|
ConcurrentUpgrades* = 4
|
||||||
|
|
||||||
type
|
type
|
||||||
DialFailedError* = object of CatchableError
|
DialFailedError* = object of LPError
|
||||||
|
|
||||||
Switch* = ref object of RootObj
|
Switch* = ref object of RootObj
|
||||||
peerInfo*: PeerInfo
|
peerInfo*: PeerInfo
|
||||||
|
@ -276,7 +278,8 @@ proc dial*(s: Switch,
|
||||||
proto: string):
|
proto: string):
|
||||||
Future[Connection] = dial(s, peerId, addrs, @[proto])
|
Future[Connection] = dial(s, peerId, addrs, @[proto])
|
||||||
|
|
||||||
proc mount*[T: LPProtocol](s: Switch, proto: T, matcher: Matcher = nil) {.gcsafe.} =
|
proc mount*[T: LPProtocol](s: Switch, proto: T, matcher: Matcher = nil)
|
||||||
|
{.gcsafe, raises: [Defect, CatchableError].} =
|
||||||
if isNil(proto.handler):
|
if isNil(proto.handler):
|
||||||
raise newException(CatchableError,
|
raise newException(CatchableError,
|
||||||
"Protocol has to define a handle method or proc")
|
"Protocol has to define a handle method or proc")
|
||||||
|
@ -404,7 +407,9 @@ proc newSwitch*(peerInfo: PeerInfo,
|
||||||
maxConnections = MaxConnections,
|
maxConnections = MaxConnections,
|
||||||
maxIn = -1,
|
maxIn = -1,
|
||||||
maxOut = -1,
|
maxOut = -1,
|
||||||
maxConnsPerPeer = MaxConnectionsPerPeer): Switch =
|
maxConnsPerPeer = MaxConnectionsPerPeer): Switch
|
||||||
|
{.raises: [Defect, CatchableError].} =
|
||||||
|
|
||||||
if secureManagers.len == 0:
|
if secureManagers.len == 0:
|
||||||
raise (ref CatchableError)(msg: "Provide at least one secure manager")
|
raise (ref CatchableError)(msg: "Provide at least one secure manager")
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[oids, sequtils]
|
import std/[oids, sequtils]
|
||||||
import chronos, chronicles
|
import chronos, chronicles
|
||||||
import transport,
|
import transport,
|
||||||
|
@ -203,7 +205,9 @@ method dial*(t: TcpTransport,
|
||||||
|
|
||||||
method handles*(t: TcpTransport, address: MultiAddress): bool {.gcsafe.} =
|
method handles*(t: TcpTransport, address: MultiAddress): bool {.gcsafe.} =
|
||||||
if procCall Transport(t).handles(address):
|
if procCall Transport(t).handles(address):
|
||||||
return address.protocols
|
if address.protocols.isOk:
|
||||||
.tryGet()
|
return address.protocols
|
||||||
.filterIt( it == multiCodec("tcp") )
|
.get()
|
||||||
.len > 0
|
.filterIt(
|
||||||
|
it == multiCodec("tcp")
|
||||||
|
).len > 0
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
##
|
##
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import sequtils
|
import sequtils
|
||||||
import chronos, chronicles
|
import chronos, chronicles
|
||||||
import ../stream/connection,
|
import ../stream/connection,
|
||||||
|
@ -77,7 +79,8 @@ method handles*(t: Transport, address: MultiAddress): bool {.base, gcsafe.} =
|
||||||
|
|
||||||
# by default we skip circuit addresses to avoid
|
# by default we skip circuit addresses to avoid
|
||||||
# having to repeat the check in every transport
|
# having to repeat the check in every transport
|
||||||
address.protocols.tryGet().filterIt( it == multiCodec("p2p-circuit") ).len == 0
|
if address.protocols.isOk:
|
||||||
|
return address.protocols.get().filterIt( it == multiCodec("p2p-circuit") ).len == 0
|
||||||
|
|
||||||
method localAddress*(t: Transport): MultiAddress {.base, gcsafe.} =
|
method localAddress*(t: Transport): MultiAddress {.base, gcsafe.} =
|
||||||
## get the local address of the transport in case started with 0.0.0.0:0
|
## get the local address of the transport in case started with 0.0.0.0:0
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[tables, sequtils]
|
import std/[tables, sequtils]
|
||||||
import pkg/[chronos, chronicles, metrics]
|
import pkg/[chronos, chronicles, metrics]
|
||||||
|
|
||||||
|
@ -15,6 +17,9 @@ import ../upgrademngrs/upgrade,
|
||||||
|
|
||||||
export Upgrade
|
export Upgrade
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "libp2p muxedupgrade"
|
||||||
|
|
||||||
type
|
type
|
||||||
MuxedUpgrade* = ref object of Upgrade
|
MuxedUpgrade* = ref object of Upgrade
|
||||||
muxers*: Table[string, MuxerProvider]
|
muxers*: Table[string, MuxerProvider]
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import std/[options, sequtils]
|
import std/[options, sequtils]
|
||||||
import pkg/[chronos, chronicles, metrics]
|
import pkg/[chronos, chronicles, metrics]
|
||||||
|
|
||||||
|
@ -14,14 +16,18 @@ import ../stream/connection,
|
||||||
../protocols/secure/secure,
|
../protocols/secure/secure,
|
||||||
../protocols/identify,
|
../protocols/identify,
|
||||||
../multistream,
|
../multistream,
|
||||||
../connmanager
|
../connmanager,
|
||||||
|
../errors
|
||||||
|
|
||||||
export connmanager, connection, identify, secure, multistream
|
export connmanager, connection, identify, secure, multistream
|
||||||
|
|
||||||
declarePublicCounter(libp2p_failed_upgrade, "peers failed upgrade")
|
declarePublicCounter(libp2p_failed_upgrade, "peers failed upgrade")
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "libp2p upgrade"
|
||||||
|
|
||||||
type
|
type
|
||||||
UpgradeFailedError* = object of CatchableError
|
UpgradeFailedError* = object of LPError
|
||||||
|
|
||||||
Upgrade* = ref object of RootObj
|
Upgrade* = ref object of RootObj
|
||||||
ms*: MultistreamSelect
|
ms*: MultistreamSelect
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
import sequtils
|
import sequtils
|
||||||
import chronos, chronicles
|
import chronos, chronicles
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
## 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].}
|
||||||
|
|
||||||
## This module implements wire network connection procedures.
|
## This module implements wire network connection procedures.
|
||||||
import chronos, stew/endians2
|
import chronos, stew/endians2
|
||||||
import multiaddress, multicodec
|
import multiaddress, multicodec
|
||||||
|
@ -28,11 +30,13 @@ const
|
||||||
mapAnd(mapEq("unix"))
|
mapAnd(mapEq("unix"))
|
||||||
)
|
)
|
||||||
|
|
||||||
proc initTAddress*(ma: MultiAddress): MaResult[TransportAddress] {.
|
proc initTAddress*(ma: MultiAddress): MaResult[TransportAddress]
|
||||||
raises: [Defect, ResultError[string]] .} =
|
{.raises: [Defect, ResultError[string]].} =
|
||||||
## Initialize ``TransportAddress`` with MultiAddress ``ma``.
|
## Initialize ``TransportAddress`` with MultiAddress ``ma``.
|
||||||
##
|
##
|
||||||
## MultiAddress must be wire address, e.g. ``{IP4, IP6, UNIX}/{TCP, UDP}``.
|
## MultiAddress must be wire address, e.g. ``{IP4, IP6, UNIX}/{TCP, UDP}``.
|
||||||
|
##
|
||||||
|
|
||||||
if TRANSPMA.match(ma):
|
if TRANSPMA.match(ma):
|
||||||
var pbuf: array[2, byte]
|
var pbuf: array[2, byte]
|
||||||
let code = ma[0].tryGet().protoCode().tryGet()
|
let code = ma[0].tryGet().protoCode().tryGet()
|
||||||
|
@ -85,14 +89,25 @@ proc createStreamServer*[T](ma: MultiAddress,
|
||||||
backlog: int = 100,
|
backlog: int = 100,
|
||||||
bufferSize: int = DefaultStreamBufferSize,
|
bufferSize: int = DefaultStreamBufferSize,
|
||||||
child: StreamServer = nil,
|
child: StreamServer = nil,
|
||||||
init: TransportInitCallback = nil): StreamServer =
|
init: TransportInitCallback = nil): StreamServer
|
||||||
|
{.raises: [Defect, MaInvalidAddress].} =
|
||||||
## Create new TCP stream server which bounds to ``ma`` address.
|
## Create new TCP stream server which bounds to ``ma`` address.
|
||||||
if not(RTRANSPMA.match(ma)):
|
if not(RTRANSPMA.match(ma)):
|
||||||
raise newException(MaInvalidAddress, "Incorrect or unsupported address!")
|
raise newException(MaInvalidAddress, "Incorrect or unsupported address!")
|
||||||
|
|
||||||
let address = initTAddress(ma)
|
let address = try:
|
||||||
result = createStreamServer(address.tryGet(), cbproc, flags, udata, sock,
|
initTAddress(ma)
|
||||||
backlog, bufferSize, child, init)
|
except ResultError[string] as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
|
if address.isErr:
|
||||||
|
raise newException(MaInvalidAddress, address.error)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return createStreamServer(address.get(), cbproc, flags, udata, sock,
|
||||||
|
backlog, bufferSize, child, init)
|
||||||
|
except CatchableError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
proc createStreamServer*[T](ma: MultiAddress,
|
proc createStreamServer*[T](ma: MultiAddress,
|
||||||
flags: set[ServerFlags] = {},
|
flags: set[ServerFlags] = {},
|
||||||
|
@ -101,16 +116,27 @@ proc createStreamServer*[T](ma: MultiAddress,
|
||||||
backlog: int = 100,
|
backlog: int = 100,
|
||||||
bufferSize: int = DefaultStreamBufferSize,
|
bufferSize: int = DefaultStreamBufferSize,
|
||||||
child: StreamServer = nil,
|
child: StreamServer = nil,
|
||||||
init: TransportInitCallback = nil): StreamServer =
|
init: TransportInitCallback = nil): StreamServer
|
||||||
|
{.raises: [Defect, MaInvalidAddress].} =
|
||||||
## Create new TCP stream server which bounds to ``ma`` address.
|
## Create new TCP stream server which bounds to ``ma`` address.
|
||||||
|
##
|
||||||
|
|
||||||
if not(RTRANSPMA.match(ma)):
|
if not(RTRANSPMA.match(ma)):
|
||||||
raise newException(MaInvalidAddress, "Incorrect or unsupported address!")
|
raise newException(MaInvalidAddress, "Incorrect or unsupported address!")
|
||||||
|
|
||||||
let address = initTAddress(ma)
|
let address = try:
|
||||||
result = createStreamServer(address.tryGet(), flags, udata, sock, backlog,
|
initTAddress(ma)
|
||||||
bufferSize, child, init)
|
except ResultError[string] as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
proc createAsyncSocket*(ma: MultiAddress): AsyncFD =
|
try:
|
||||||
|
return createStreamServer(address.get(), flags, udata, sock, backlog,
|
||||||
|
bufferSize, child, init)
|
||||||
|
except CatchableError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
|
proc createAsyncSocket*(ma: MultiAddress): AsyncFD
|
||||||
|
{.raises: [Defect, ResultError[string]].} =
|
||||||
## Create new asynchronous socket using MultiAddress' ``ma`` socket type and
|
## Create new asynchronous socket using MultiAddress' ``ma`` socket type and
|
||||||
## protocol information.
|
## protocol information.
|
||||||
##
|
##
|
||||||
|
@ -126,7 +152,6 @@ proc createAsyncSocket*(ma: MultiAddress): AsyncFD =
|
||||||
return asyncInvalidSocket
|
return asyncInvalidSocket
|
||||||
|
|
||||||
let address = maddr.tryGet()
|
let address = maddr.tryGet()
|
||||||
|
|
||||||
if address.family in {AddressFamily.IPv4, AddressFamily.IPv6}:
|
if address.family in {AddressFamily.IPv4, AddressFamily.IPv6}:
|
||||||
if ma[1].tryGet().protoCode().tryGet() == multiCodec("udp"):
|
if ma[1].tryGet().protoCode().tryGet() == multiCodec("udp"):
|
||||||
socktype = SockType.SOCK_DGRAM
|
socktype = SockType.SOCK_DGRAM
|
||||||
|
@ -139,9 +164,14 @@ proc createAsyncSocket*(ma: MultiAddress): AsyncFD =
|
||||||
protocol = cast[Protocol](0)
|
protocol = cast[Protocol](0)
|
||||||
else:
|
else:
|
||||||
return asyncInvalidSocket
|
return asyncInvalidSocket
|
||||||
result = createAsyncSocket(address.getDomain(), socktype, protocol)
|
|
||||||
|
|
||||||
proc bindAsyncSocket*(sock: AsyncFD, ma: MultiAddress): bool =
|
try:
|
||||||
|
createAsyncSocket(address.getDomain(), socktype, protocol)
|
||||||
|
except CatchableError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
|
proc bindAsyncSocket*(sock: AsyncFD, ma: MultiAddress): bool
|
||||||
|
{.raises: [Defect, ResultError[string]].} =
|
||||||
## Bind socket ``sock`` to MultiAddress ``ma``.
|
## Bind socket ``sock`` to MultiAddress ``ma``.
|
||||||
##
|
##
|
||||||
## Note: This procedure only used in `go-libp2p-daemon` wrapper.
|
## Note: This procedure only used in `go-libp2p-daemon` wrapper.
|
||||||
|
@ -153,7 +183,7 @@ proc bindAsyncSocket*(sock: AsyncFD, ma: MultiAddress): bool =
|
||||||
if maddr.isErr():
|
if maddr.isErr():
|
||||||
return false
|
return false
|
||||||
|
|
||||||
let address = maddr.tryGet()
|
let address = maddr.get()
|
||||||
toSAddr(address, saddr, slen)
|
toSAddr(address, saddr, slen)
|
||||||
if bindSocket(SocketHandle(sock), cast[ptr SockAddr](addr saddr),
|
if bindSocket(SocketHandle(sock), cast[ptr SockAddr](addr saddr),
|
||||||
slen) == 0:
|
slen) == 0:
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import unittest2
|
||||||
|
|
||||||
|
export unittest2
|
||||||
|
|
||||||
|
template asyncTeardown*(body: untyped): untyped =
|
||||||
|
teardown:
|
||||||
|
waitFor((
|
||||||
|
proc() {.async, gcsafe.} =
|
||||||
|
body
|
||||||
|
)())
|
||||||
|
|
||||||
|
template asyncSetup*(body: untyped): untyped =
|
||||||
|
setup:
|
||||||
|
waitFor((
|
||||||
|
proc() {.async, gcsafe.} =
|
||||||
|
body
|
||||||
|
)())
|
||||||
|
|
||||||
|
template asyncTest*(name: string, body: untyped): untyped =
|
||||||
|
test name:
|
||||||
|
waitFor((
|
||||||
|
proc() {.async, gcsafe.} =
|
||||||
|
body
|
||||||
|
)())
|
|
@ -1,4 +1,4 @@
|
||||||
import std/unittest
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import chronos, bearssl
|
import chronos, bearssl
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ import ../libp2p/stream/lpstream
|
||||||
import ../libp2p/muxers/mplex/lpchannel
|
import ../libp2p/muxers/mplex/lpchannel
|
||||||
import ../libp2p/protocols/secure/secure
|
import ../libp2p/protocols/secure/secure
|
||||||
|
|
||||||
export unittest
|
import ./asyncunit
|
||||||
|
export asyncunit
|
||||||
|
|
||||||
const
|
const
|
||||||
StreamTransportTrackerName = "stream.transport"
|
StreamTransportTrackerName = "stream.transport"
|
||||||
|
@ -48,27 +49,6 @@ template checkTrackers*() =
|
||||||
# Also test the GC is not fooling with us
|
# Also test the GC is not fooling with us
|
||||||
GC_fullCollect()
|
GC_fullCollect()
|
||||||
|
|
||||||
template asyncTeardown*(body: untyped): untyped =
|
|
||||||
teardown:
|
|
||||||
waitFor((
|
|
||||||
proc() {.async, gcsafe.} =
|
|
||||||
body
|
|
||||||
)())
|
|
||||||
|
|
||||||
template asyncSetup*(body: untyped): untyped =
|
|
||||||
setup:
|
|
||||||
waitFor((
|
|
||||||
proc() {.async, gcsafe.} =
|
|
||||||
body
|
|
||||||
)())
|
|
||||||
|
|
||||||
template asyncTest*(name: string, body: untyped): untyped =
|
|
||||||
test name:
|
|
||||||
waitFor((
|
|
||||||
proc() {.async, gcsafe.} =
|
|
||||||
body
|
|
||||||
)())
|
|
||||||
|
|
||||||
type RngWrap = object
|
type RngWrap = object
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref BrHmacDrbgContext
|
||||||
|
|
||||||
|
@ -99,7 +79,7 @@ proc newBufferStream*(writeHandler: WriteHandler): TestBufferStream =
|
||||||
result.writeHandler = writeHandler
|
result.writeHandler = writeHandler
|
||||||
result.initStream()
|
result.initStream()
|
||||||
|
|
||||||
proc checkExpiringInternal(cond: proc(): bool): Future[bool] {.async, gcsafe.} =
|
proc checkExpiringInternal(cond: proc(): bool {.raises: [Defect].} ): Future[bool] {.async, gcsafe.} =
|
||||||
{.gcsafe.}:
|
{.gcsafe.}:
|
||||||
let start = Moment.now()
|
let start = Moment.now()
|
||||||
while true:
|
while true:
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, sequtils, options, tables, sets
|
import sequtils, options, tables, sets
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import utils,
|
import utils,
|
||||||
../../libp2p/[errors,
|
../../libp2p/[errors,
|
||||||
|
|
|
@ -3,7 +3,7 @@ include ../../libp2p/protocols/pubsub/gossipsub
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import options
|
import options
|
||||||
import unittest, bearssl
|
import bearssl
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import ../../libp2p/builders
|
import ../../libp2p/builders
|
||||||
import ../../libp2p/errors
|
import ../../libp2p/errors
|
||||||
|
@ -34,7 +34,10 @@ proc getPubSubPeer(p: TestGossipSub, peerId: PeerID): PubSubPeer =
|
||||||
pubSubPeer
|
pubSubPeer
|
||||||
|
|
||||||
proc randomPeerInfo(): PeerInfo =
|
proc randomPeerInfo(): PeerInfo =
|
||||||
PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
|
try:
|
||||||
|
PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
|
||||||
|
except CatchableError as exc:
|
||||||
|
raise newException(Defect, exc.msg)
|
||||||
|
|
||||||
suite "GossipSub internal":
|
suite "GossipSub internal":
|
||||||
teardown:
|
teardown:
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, sequtils, options, tables, sets
|
import sequtils, options, tables, sets
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import chronicles
|
import chronicles
|
||||||
import utils, ../../libp2p/[errors,
|
import utils, ../../libp2p/[errors,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, sequtils, options, tables, sets
|
import sequtils, options, tables, sets
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import chronicles
|
import chronicles
|
||||||
import utils, ../../libp2p/[errors,
|
import utils, ../../libp2p/[errors,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, options, sets, sequtils, bearssl
|
import unittest2, options, sets, sequtils, bearssl
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import ../../libp2p/[peerid,
|
import ../../libp2p/[peerid,
|
||||||
crypto/crypto,
|
crypto/crypto,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest
|
import unittest2
|
||||||
|
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import testgossipinternal,
|
import testfloodsub,
|
||||||
testfloodsub,
|
|
||||||
testgossipsub,
|
testgossipsub,
|
||||||
testgossipsub2,
|
testgossipsub2,
|
||||||
testmcache,
|
testmcache,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import std/unittest
|
import unittest2
|
||||||
import chronos/timer
|
import chronos/timer
|
||||||
import ../../libp2p/protocols/pubsub/timedcache
|
import ../../libp2p/protocols/pubsub/timedcache
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import unittest
|
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import ../libp2p/stream/bufferstream,
|
import ../libp2p/stream/bufferstream,
|
||||||
../libp2p/stream/lpstream,
|
../libp2p/stream/lpstream,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/[cid, multihash, multicodec]
|
import ../libp2p/[cid, multihash, multicodec]
|
||||||
|
|
||||||
when defined(nimHasUsed): {.used.}
|
when defined(nimHasUsed): {.used.}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import unittest
|
|
||||||
import chronos, nimcrypto/utils
|
import chronos, nimcrypto/utils
|
||||||
import ../libp2p/[stream/connection,
|
import ../libp2p/[stream/connection,
|
||||||
stream/bufferstream]
|
stream/bufferstream]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest, sequtils
|
import sequtils
|
||||||
import chronos
|
import chronos
|
||||||
import ../libp2p/[connmanager,
|
import ../libp2p/[connmanager,
|
||||||
stream/connection,
|
stream/connection,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## Test vectors was made using Go implementation
|
## Test vectors was made using Go implementation
|
||||||
## https://github.com/libp2p/go-libp2p-crypto/blob/master/key.go
|
## https://github.com/libp2p/go-libp2p-crypto/blob/master/key.go
|
||||||
import unittest
|
import unittest2
|
||||||
import nimcrypto/[utils, sysrand]
|
import nimcrypto/[utils, sysrand]
|
||||||
import ../libp2p/crypto/[crypto, chacha20poly1305, curve25519, hkdf]
|
import ../libp2p/crypto/[crypto, chacha20poly1305, curve25519, hkdf]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import unittest
|
import chronos, unittest2
|
||||||
import chronos
|
|
||||||
import ../libp2p/daemon/daemonapi, ../libp2p/multiaddress, ../libp2p/multicodec,
|
import ../libp2p/daemon/daemonapi, ../libp2p/multiaddress, ../libp2p/multicodec,
|
||||||
../libp2p/cid, ../libp2p/multihash, ../libp2p/peerid
|
../libp2p/cid, ../libp2p/multihash, ../libp2p/peerid
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
## at your option.
|
## at your option.
|
||||||
## 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.
|
||||||
import unittest
|
import unittest2
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import ../libp2p/crypto/[crypto, ecnist]
|
import ../libp2p/crypto/[crypto, ecnist]
|
||||||
import stew/results
|
import stew/results
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
|
|
||||||
## Test vectors are from RFC 8032 (https://tools.ietf.org/html/rfc8032)
|
## Test vectors are from RFC 8032 (https://tools.ietf.org/html/rfc8032)
|
||||||
import unittest
|
import unittest2
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import ../libp2p/crypto/crypto
|
import ../libp2p/crypto/crypto
|
||||||
import ../libp2p/crypto/ed25519/ed25519
|
import ../libp2p/crypto/ed25519/ed25519
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest, options, bearssl
|
import options, bearssl
|
||||||
import chronos, strutils
|
import chronos, strutils
|
||||||
import ../libp2p/[protocols/identify,
|
import ../libp2p/[protocols/identify,
|
||||||
multiaddress,
|
multiaddress,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import options, tables
|
import options, tables
|
||||||
import unittest
|
|
||||||
import chronos, chronicles, stew/byteutils
|
import chronos, chronicles, stew/byteutils
|
||||||
import helpers
|
import helpers
|
||||||
import ../libp2p/[daemon/daemonapi,
|
import ../libp2p/[daemon/daemonapi,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
## at your option.
|
## at your option.
|
||||||
## 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.
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/crypto/minasn1
|
import ../libp2p/crypto/minasn1
|
||||||
import nimcrypto/utils as ncrutils
|
import nimcrypto/utils as ncrutils
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,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.
|
||||||
|
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/protobuf/minprotobuf
|
import ../libp2p/protobuf/minprotobuf
|
||||||
import stew/byteutils, strutils
|
import stew/byteutils, strutils
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest, strformat, strformat, random, oids, sequtils
|
import strformat, strformat, random, oids, sequtils
|
||||||
import chronos, nimcrypto/utils, chronicles, stew/byteutils
|
import chronos, nimcrypto/utils, chronicles, stew/byteutils
|
||||||
import ../libp2p/[errors,
|
import ../libp2p/[errors,
|
||||||
stream/connection,
|
stream/connection,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/[multicodec, multiaddress]
|
import ../libp2p/[multicodec, multiaddress]
|
||||||
|
|
||||||
when defined(nimHasUsed): {.used.}
|
when defined(nimHasUsed): {.used.}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/multibase
|
import ../libp2p/multibase
|
||||||
import stew/results
|
import stew/results
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest
|
import unittest2
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import ../libp2p/multihash
|
import ../libp2p/multihash
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest, strutils, strformat, stew/byteutils
|
import strutils, strformat, stew/byteutils
|
||||||
import chronos
|
import chronos
|
||||||
import ../libp2p/errors,
|
import ../libp2p/errors,
|
||||||
../libp2p/multistream,
|
../libp2p/multistream,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, tables, bearssl
|
import tables, bearssl
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import chronicles
|
import chronicles
|
||||||
import ../libp2p/crypto/crypto
|
import ../libp2p/crypto/crypto
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## Test vectors was made using Go implementation
|
## Test vectors was made using Go implementation
|
||||||
## https://github.com/libp2p/go-libp2p-peer
|
## https://github.com/libp2p/go-libp2p-peer
|
||||||
import unittest
|
import unittest2
|
||||||
import nimcrypto/utils, stew/base58
|
import nimcrypto/utils, stew/base58
|
||||||
import ../libp2p/crypto/crypto, ../libp2p/peerid
|
import ../libp2p/crypto/crypto, ../libp2p/peerid
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, options, bearssl
|
import options, bearssl
|
||||||
import chronos
|
import chronos
|
||||||
import ../libp2p/crypto/crypto,
|
import ../libp2p/crypto/crypto,
|
||||||
../libp2p/peerinfo,
|
../libp2p/peerinfo,
|
||||||
|
@ -35,7 +35,11 @@ suite "PeerInfo":
|
||||||
check seckey.getKey.get() == peerInfo.publicKey.get()
|
check seckey.getKey.get() == peerInfo.publicKey.get()
|
||||||
|
|
||||||
test "Should init from CIDv0 string":
|
test "Should init from CIDv0 string":
|
||||||
var peerInfo = PeerInfo.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
|
var peerInfo: PeerInfo
|
||||||
|
try:
|
||||||
|
peerInfo = PeerInfo.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
|
||||||
|
except CatchableError:
|
||||||
|
check false
|
||||||
|
|
||||||
check:
|
check:
|
||||||
PeerID.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N").get() == peerInfo.peerId
|
PeerID.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N").get() == peerInfo.peerId
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import
|
import
|
||||||
std/[unittest, tables, sequtils, sets],
|
std/[unittest2, tables, sequtils, sets],
|
||||||
../libp2p/crypto/crypto,
|
../libp2p/crypto/crypto,
|
||||||
../libp2p/multiaddress,
|
../libp2p/multiaddress,
|
||||||
../libp2p/peerid,
|
../libp2p/peerid,
|
||||||
|
@ -21,12 +21,12 @@ suite "PeerStore":
|
||||||
multiaddrStr2 = "/ip4/0.0.0.0/tcp/1234/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC"
|
multiaddrStr2 = "/ip4/0.0.0.0/tcp/1234/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC"
|
||||||
multiaddr2 = MultiAddress.init(multiaddrStr2).get()
|
multiaddr2 = MultiAddress.init(multiaddrStr2).get()
|
||||||
testcodec2 = "/nim/libp2p/test/0.0.2-beta1"
|
testcodec2 = "/nim/libp2p/test/0.0.2-beta1"
|
||||||
|
|
||||||
test "PeerStore API":
|
test "PeerStore API":
|
||||||
# Set up peer store
|
# Set up peer store
|
||||||
var
|
var
|
||||||
peerStore = PeerStore.new()
|
peerStore = PeerStore.new()
|
||||||
|
|
||||||
peerStore.addressBook.add(peerId1, multiaddr1)
|
peerStore.addressBook.add(peerId1, multiaddr1)
|
||||||
peerStore.addressBook.add(peerId2, multiaddr2)
|
peerStore.addressBook.add(peerId2, multiaddr2)
|
||||||
peerStore.protoBook.add(peerId1, testcodec1)
|
peerStore.protoBook.add(peerId1, testcodec1)
|
||||||
|
@ -47,7 +47,7 @@ suite "PeerStore":
|
||||||
peer2Stored.addrs == toHashSet([multiaddr2])
|
peer2Stored.addrs == toHashSet([multiaddr2])
|
||||||
peer2Stored.protos == toHashSet([testcodec2])
|
peer2Stored.protos == toHashSet([testcodec2])
|
||||||
peer2Stored.publicKey == keyPair2.pubkey
|
peer2Stored.publicKey == keyPair2.pubkey
|
||||||
|
|
||||||
# Test PeerStore::peers
|
# Test PeerStore::peers
|
||||||
let peers = peerStore.peers()
|
let peers = peerStore.peers()
|
||||||
check:
|
check:
|
||||||
|
@ -69,7 +69,7 @@ suite "PeerStore":
|
||||||
|
|
||||||
# Now try and delete it again
|
# Now try and delete it again
|
||||||
peerStore.delete(peerId1) == false
|
peerStore.delete(peerId1) == false
|
||||||
|
|
||||||
test "PeerStore listeners":
|
test "PeerStore listeners":
|
||||||
# Set up peer store with listener
|
# Set up peer store with listener
|
||||||
var
|
var
|
||||||
|
@ -77,13 +77,13 @@ suite "PeerStore":
|
||||||
addrChanged = false
|
addrChanged = false
|
||||||
protoChanged = false
|
protoChanged = false
|
||||||
keyChanged = false
|
keyChanged = false
|
||||||
|
|
||||||
proc addrChange(peerId: PeerID, addrs: HashSet[MultiAddress]) =
|
proc addrChange(peerId: PeerID, addrs: HashSet[MultiAddress]) =
|
||||||
addrChanged = true
|
addrChanged = true
|
||||||
|
|
||||||
proc protoChange(peerId: PeerID, protos: HashSet[string]) =
|
proc protoChange(peerId: PeerID, protos: HashSet[string]) =
|
||||||
protoChanged = true
|
protoChanged = true
|
||||||
|
|
||||||
proc keyChange(peerId: PeerID, publicKey: PublicKey) =
|
proc keyChange(peerId: PeerID, publicKey: PublicKey) =
|
||||||
keyChanged = true
|
keyChanged = true
|
||||||
|
|
||||||
|
@ -95,32 +95,32 @@ suite "PeerStore":
|
||||||
peerStore.addressBook.add(peerId1, multiaddr1)
|
peerStore.addressBook.add(peerId1, multiaddr1)
|
||||||
check:
|
check:
|
||||||
addrChanged == true
|
addrChanged == true
|
||||||
|
|
||||||
# Test listener triggered on setting addresses
|
# Test listener triggered on setting addresses
|
||||||
addrChanged = false
|
addrChanged = false
|
||||||
peerStore.addressBook.set(peerId2,
|
peerStore.addressBook.set(peerId2,
|
||||||
toHashSet([multiaddr1, multiaddr2]))
|
toHashSet([multiaddr1, multiaddr2]))
|
||||||
check:
|
check:
|
||||||
addrChanged == true
|
addrChanged == true
|
||||||
|
|
||||||
# Test listener triggered on adding proto
|
# Test listener triggered on adding proto
|
||||||
peerStore.protoBook.add(peerId1, testcodec1)
|
peerStore.protoBook.add(peerId1, testcodec1)
|
||||||
check:
|
check:
|
||||||
protoChanged == true
|
protoChanged == true
|
||||||
|
|
||||||
# Test listener triggered on setting protos
|
# Test listener triggered on setting protos
|
||||||
protoChanged = false
|
protoChanged = false
|
||||||
peerStore.protoBook.set(peerId2,
|
peerStore.protoBook.set(peerId2,
|
||||||
toHashSet([testcodec1, testcodec2]))
|
toHashSet([testcodec1, testcodec2]))
|
||||||
check:
|
check:
|
||||||
protoChanged == true
|
protoChanged == true
|
||||||
|
|
||||||
# Test listener triggered on setting public key
|
# Test listener triggered on setting public key
|
||||||
peerStore.keyBook.set(peerId1,
|
peerStore.keyBook.set(peerId1,
|
||||||
keyPair1.pubkey)
|
keyPair1.pubkey)
|
||||||
check:
|
check:
|
||||||
keyChanged == true
|
keyChanged == true
|
||||||
|
|
||||||
# Test listener triggered on changing public key
|
# Test listener triggered on changing public key
|
||||||
keyChanged = false
|
keyChanged = false
|
||||||
peerStore.keyBook.set(peerId1,
|
peerStore.keyBook.set(peerId1,
|
||||||
|
@ -132,18 +132,18 @@ suite "PeerStore":
|
||||||
# Set up address book
|
# Set up address book
|
||||||
var
|
var
|
||||||
addressBook = PeerStore.new().addressBook
|
addressBook = PeerStore.new().addressBook
|
||||||
|
|
||||||
# Test AddressBook::add
|
# Test AddressBook::add
|
||||||
addressBook.add(peerId1, multiaddr1)
|
addressBook.add(peerId1, multiaddr1)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
toSeq(keys(addressBook.book))[0] == peerId1
|
toSeq(keys(addressBook.book))[0] == peerId1
|
||||||
toSeq(values(addressBook.book))[0] == toHashSet([multiaddr1])
|
toSeq(values(addressBook.book))[0] == toHashSet([multiaddr1])
|
||||||
|
|
||||||
# Test AddressBook::get
|
# Test AddressBook::get
|
||||||
check:
|
check:
|
||||||
addressBook.get(peerId1) == toHashSet([multiaddr1])
|
addressBook.get(peerId1) == toHashSet([multiaddr1])
|
||||||
|
|
||||||
# Test AddressBook::delete
|
# Test AddressBook::delete
|
||||||
check:
|
check:
|
||||||
# Try to delete peerId that doesn't exist
|
# Try to delete peerId that doesn't exist
|
||||||
|
@ -153,7 +153,7 @@ suite "PeerStore":
|
||||||
addressBook.book.len == 1 # sanity
|
addressBook.book.len == 1 # sanity
|
||||||
addressBook.delete(peerId1) == true
|
addressBook.delete(peerId1) == true
|
||||||
addressBook.book.len == 0
|
addressBook.book.len == 0
|
||||||
|
|
||||||
# Test AddressBook::set
|
# Test AddressBook::set
|
||||||
# Set peerId2 with multiple multiaddrs
|
# Set peerId2 with multiple multiaddrs
|
||||||
addressBook.set(peerId2,
|
addressBook.set(peerId2,
|
||||||
|
@ -161,23 +161,23 @@ suite "PeerStore":
|
||||||
check:
|
check:
|
||||||
toSeq(keys(addressBook.book))[0] == peerId2
|
toSeq(keys(addressBook.book))[0] == peerId2
|
||||||
toSeq(values(addressBook.book))[0] == toHashSet([multiaddr1, multiaddr2])
|
toSeq(values(addressBook.book))[0] == toHashSet([multiaddr1, multiaddr2])
|
||||||
|
|
||||||
test "ProtoBook API":
|
test "ProtoBook API":
|
||||||
# Set up protocol book
|
# Set up protocol book
|
||||||
var
|
var
|
||||||
protoBook = PeerStore.new().protoBook
|
protoBook = PeerStore.new().protoBook
|
||||||
|
|
||||||
# Test ProtoBook::add
|
# Test ProtoBook::add
|
||||||
protoBook.add(peerId1, testcodec1)
|
protoBook.add(peerId1, testcodec1)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
toSeq(keys(protoBook.book))[0] == peerId1
|
toSeq(keys(protoBook.book))[0] == peerId1
|
||||||
toSeq(values(protoBook.book))[0] == toHashSet([testcodec1])
|
toSeq(values(protoBook.book))[0] == toHashSet([testcodec1])
|
||||||
|
|
||||||
# Test ProtoBook::get
|
# Test ProtoBook::get
|
||||||
check:
|
check:
|
||||||
protoBook.get(peerId1) == toHashSet([testcodec1])
|
protoBook.get(peerId1) == toHashSet([testcodec1])
|
||||||
|
|
||||||
# Test ProtoBook::delete
|
# Test ProtoBook::delete
|
||||||
check:
|
check:
|
||||||
# Try to delete peerId that doesn't exist
|
# Try to delete peerId that doesn't exist
|
||||||
|
@ -187,7 +187,7 @@ suite "PeerStore":
|
||||||
protoBook.book.len == 1 # sanity
|
protoBook.book.len == 1 # sanity
|
||||||
protoBook.delete(peerId1) == true
|
protoBook.delete(peerId1) == true
|
||||||
protoBook.book.len == 0
|
protoBook.book.len == 0
|
||||||
|
|
||||||
# Test ProtoBook::set
|
# Test ProtoBook::set
|
||||||
# Set peerId2 with multiple protocols
|
# Set peerId2 with multiple protocols
|
||||||
protoBook.set(peerId2,
|
protoBook.set(peerId2,
|
||||||
|
@ -200,18 +200,18 @@ suite "PeerStore":
|
||||||
# Set up key book
|
# Set up key book
|
||||||
var
|
var
|
||||||
keyBook = PeerStore.new().keyBook
|
keyBook = PeerStore.new().keyBook
|
||||||
|
|
||||||
# Test KeyBook::set
|
# Test KeyBook::set
|
||||||
keyBook.set(peerId1,
|
keyBook.set(peerId1,
|
||||||
keyPair1.pubkey)
|
keyPair1.pubkey)
|
||||||
check:
|
check:
|
||||||
toSeq(keys(keyBook.book))[0] == peerId1
|
toSeq(keys(keyBook.book))[0] == peerId1
|
||||||
toSeq(values(keyBook.book))[0] == keyPair1.pubkey
|
toSeq(values(keyBook.book))[0] == keyPair1.pubkey
|
||||||
|
|
||||||
# Test KeyBook::get
|
# Test KeyBook::get
|
||||||
check:
|
check:
|
||||||
keyBook.get(peerId1) == keyPair1.pubkey
|
keyBook.get(peerId1) == keyPair1.pubkey
|
||||||
|
|
||||||
# Test KeyBook::delete
|
# Test KeyBook::delete
|
||||||
check:
|
check:
|
||||||
# Try to delete peerId that doesn't exist
|
# Try to delete peerId that doesn't exist
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
when defined(nimHasUsed): {.used.}
|
when defined(nimHasUsed): {.used.}
|
||||||
|
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/crypto/crypto
|
import ../libp2p/crypto/crypto
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
## at your option.
|
## at your option.
|
||||||
## 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.
|
||||||
import unittest
|
import unittest2
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import ../libp2p/crypto/[crypto, rsa]
|
import ../libp2p/crypto/[crypto, rsa]
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
## at your option.
|
## at your option.
|
||||||
## 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.
|
||||||
import unittest, bearssl
|
import unittest2, bearssl
|
||||||
import ../libp2p/crypto/[crypto, secp]
|
import ../libp2p/crypto/[crypto, secp]
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest
|
import unittest2
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import ../libp2p/stream/streamseq
|
import ../libp2p/stream/streamseq
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, options, sequtils
|
import options, sequtils
|
||||||
import chronos
|
import chronos
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import nimcrypto/sysrand
|
import nimcrypto/sysrand
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest, sequtils
|
import sequtils
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import ../libp2p/[stream/connection,
|
import ../libp2p/[stream/connection,
|
||||||
transports/transport,
|
transports/transport,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import unittest
|
import unittest2
|
||||||
import ../libp2p/varint
|
import ../libp2p/varint
|
||||||
|
|
||||||
when defined(nimHasUsed): {.used.}
|
when defined(nimHasUsed): {.used.}
|
||||||
|
|
Loading…
Reference in New Issue