Merge branch 'unstable' (#674)
This commit is contained in:
commit
123bf290c3
|
@ -176,7 +176,7 @@ jobs:
|
|||
|
||||
- name: Run nim-libp2p tests
|
||||
run: |
|
||||
nimble install -y --depsOnly
|
||||
nimble install_pinned
|
||||
nimble test
|
||||
|
||||
bumpNBC-stable:
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
curl -O -L -s -S https://raw.githubusercontent.com/status-im/nimbus-build-system/master/scripts/build_nim.sh
|
||||
env MAKE="make -j${NPROC}" bash build_nim.sh Nim csources dist/nimble NimBinaries
|
||||
export PATH="$PATH:$PWD/Nim/bin"
|
||||
nimble install -y --depsOnly
|
||||
nimble install_pinned
|
||||
export NIM_OPTIONS="--opt:speed -d:debug --verbosity:0 --hints:off --lineDir:on -d:chronicles_log_level=INFO --warning[CaseTransition]:off --warning[ObservableStores]:off --warning[LockLevel]:off --nimcache:nimcache --passC:-fprofile-arcs --passC:-ftest-coverage --passL:-fprofile-arcs --passL:-ftest-coverage ${{ matrix.nim-options }}"
|
||||
nim c $NIM_OPTIONS -r ${{ matrix.test-program }}
|
||||
cd nimcache; rm *.c; cd ..
|
||||
|
@ -71,8 +71,8 @@ jobs:
|
|||
curl -O -L -s -S https://raw.githubusercontent.com/status-im/nimbus-build-system/master/scripts/build_nim.sh
|
||||
env MAKE="make -j${NPROC}" bash build_nim.sh Nim csources dist/nimble NimBinaries
|
||||
export PATH="$PATH:$PWD/Nim/bin"
|
||||
nimble install -y --depsOnly
|
||||
export NIM_OPTIONS="--opt:speed -d:debug --verbosity:0 --hints:off --lineDir:on -d:chronicles_log_level=INFO --warning[CaseTransition]:off --warning[ObservableStores]:off --warning[LockLevel]:off --nimcache:nimcache --passC:-fprofile-arcs --passC:-ftest-coverage --passL:-fprofile-arcs --passL:-ftest-coverage ${{ matrix.nim-options }}"
|
||||
nimble install_pinned
|
||||
export NIM_OPTIONS="--opt:speed -d:debug --verbosity:0 --hints:off --lineDir:on -d:chronicles_log_level=INFO --warning[CaseTransition]:off --warning[ObservableStores]:off --warning[LockLevel]:off --nimcache:nimcache --passC:-fprofile-arcs --passC:-ftest-coverage --passL:-fprofile-arcs --passL:-ftest-coverage ${{ matrix.nim-options }} --clearNimblePath --NimblePath:nimbledeps/pkgs"
|
||||
nim c $NIM_OPTIONS -r ${{ matrix.test-program }}
|
||||
cd nimcache; rm *.c; cd ..
|
||||
lcov --capture --directory nimcache --output-file coverage/coverage.info
|
||||
|
@ -112,7 +112,7 @@ jobs:
|
|||
curl -O -L -s -S https://raw.githubusercontent.com/status-im/nimbus-build-system/master/scripts/build_nim.sh
|
||||
env MAKE="make -j${NPROC}" bash build_nim.sh Nim csources dist/nimble NimBinaries
|
||||
export PATH="$PATH:$PWD/Nim/bin"
|
||||
nimble install -y --depsOnly
|
||||
nimble install_pinned
|
||||
export NIM_OPTIONS="--opt:speed -d:debug --verbosity:0 --hints:off --lineDir:on -d:chronicles_log_level=INFO --warning[CaseTransition]:off --warning[ObservableStores]:off --warning[LockLevel]:off --nimcache:nimcache --passC:-fprofile-arcs --passC:-ftest-coverage --passL:-fprofile-arcs --passL:-ftest-coverage ${{ matrix.nim-options }}"
|
||||
nim c $NIM_OPTIONS -r ${{ matrix.test-program }}
|
||||
cd nimcache; rm *.c; cd ..
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
nimcache/
|
||||
nimbledeps/
|
||||
|
||||
# Executables shall be put in an ignored build/ directory
|
||||
# Ignore dynamic, static libs and libtool archive files
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
asynctest;https://github.com/markspanbroek/asynctest@#3882ed64ed3159578f796bc5ae0c6b13837fe798
|
||||
bearssl;https://github.com/status-im/nim-bearssl@#ba80e2a0d7ae8aab666cee013e38ff8d33a3e5e7
|
||||
chronicles;https://github.com/status-im/nim-chronicles@#2a2681b60289aaf7895b7056f22616081eb1a882
|
||||
chronos;https://github.com/status-im/nim-chronos@#7dc58d42b6905a7fd7531875fa76060f8f744e4e
|
||||
dnsclient;https://github.com/ba0f3/dnsclient.nim@#536cc6b7933e5f86590bb27083c0ffeab31255f9
|
||||
faststreams;https://github.com/status-im/nim-faststreams@#c653d05f277dca0f374732c5b9b80f2368faea33
|
||||
httputils;https://github.com/status-im/nim-http-utils@#507bfb7dcb6244d76ce2567df7bf3756cbe88775
|
||||
json_serialization;https://github.com/status-im/nim-json-serialization@#010aa238cf6afddf1fbe4cbcd27ab3be3f443841
|
||||
metrics;https://github.com/status-im/nim-metrics@#2c0c486c65f980e8387f86bed0b43d53161c8286
|
||||
nimcrypto;https://github.com/cheatfate/nimcrypto@#a5742a9a214ac33f91615f3862c7b099aec43b00
|
||||
secp256k1;https://github.com/status-im/nim-secp256k1@#d790c42206fab4b8008eaa91181ca8c8c68a0105
|
||||
serialization;https://github.com/status-im/nim-serialization@#11a8aa64d27d4fa92e266b9488500461da193c24
|
||||
stew;https://github.com/status-im/nim-stew@#2f9c61f485e1de6d7e163294008276c455d39da2
|
||||
testutils;https://github.com/status-im/nim-testutils@#aa6e5216f4b4ab5aa971cdcdd70e1ec1203cedf2
|
||||
unittest2;https://github.com/status-im/nim-unittest2@#b9b61cfe4a4b238de7175287b7481c35a798a582
|
||||
websock;https://github.com/status-im/nim-websock@#c2aae352f7fad7a8d333327c37e966969d3ee542
|
||||
zlib;https://github.com/status-im/nim-zlib@#d4e716d071eba1b5e0ffdf7949d983959e2b95dd
|
|
@ -0,0 +1,3 @@
|
|||
# to allow locking
|
||||
if dirExists("nimbledeps/pkgs"):
|
||||
switch("NimblePath", "nimbledeps/pkgs")
|
|
@ -56,7 +56,7 @@ proc dialPeer(p: ChatProto, address: string) {.async.} =
|
|||
.tryGet()
|
||||
.protoAddress()
|
||||
.tryGet()
|
||||
remotePeer = PeerID.init(peerIdBytes).tryGet()
|
||||
remotePeer = PeerId.init(peerIdBytes).tryGet()
|
||||
# split the wire address
|
||||
ip4Addr = multiAddr[multiCodec("ip4")].tryGet()
|
||||
tcpAddr = multiAddr[multiCodec("tcp")].tryGet()
|
||||
|
@ -182,7 +182,7 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} =
|
|||
chatProto.started = true
|
||||
|
||||
let id = $switch.peerInfo.peerId
|
||||
echo "PeerID: " & id
|
||||
echo "PeerId: " & id
|
||||
echo "listening on: "
|
||||
for a in switch.peerInfo.addrs:
|
||||
echo &"{a}/p2p/{id}"
|
||||
|
|
|
@ -79,7 +79,9 @@ proc handlePeer(c: Chat, conn: Connection) {.async.} =
|
|||
c.writeStdout $conn.peerId & ": " & $str
|
||||
|
||||
except LPStreamEOFError:
|
||||
c.writeStdout $conn.peerId & " disconnected"
|
||||
defer: c.writeStdout $conn.peerId & " disconnected"
|
||||
await c.conn.close()
|
||||
c.connected = false
|
||||
|
||||
proc dialPeer(c: Chat, address: string) {.async.} =
|
||||
# Parse and dial address
|
||||
|
@ -90,7 +92,7 @@ proc dialPeer(c: Chat, address: string) {.async.} =
|
|||
.tryGet()
|
||||
.protoAddress()
|
||||
.tryGet()
|
||||
remotePeer = PeerID.init(peerIdBytes).tryGet()
|
||||
remotePeer = PeerId.init(peerIdBytes).tryGet()
|
||||
# split the wire address
|
||||
ip4Addr = multiAddr[multiCodec("ip4")].tryGet()
|
||||
tcpAddr = multiAddr[multiCodec("tcp")].tryGet()
|
||||
|
@ -130,7 +132,7 @@ proc readLoop(c: Chat) {.async.} =
|
|||
|
||||
await c.switch.stop()
|
||||
c.writeStdout "quitting..."
|
||||
quit(0)
|
||||
return
|
||||
else:
|
||||
if c.connected:
|
||||
await c.conn.writeLp(line)
|
||||
|
@ -179,15 +181,15 @@ proc main() {.async.} =
|
|||
|
||||
switch.mount(ChatProto.new(chat))
|
||||
|
||||
let libp2pFuts = await switch.start()
|
||||
await switch.start()
|
||||
|
||||
let id = $switch.peerInfo.peerId
|
||||
echo "PeerID: " & id
|
||||
echo "PeerId: " & id
|
||||
echo "listening on: "
|
||||
for a in switch.peerInfo.addrs:
|
||||
echo &"{a}/p2p/{id}"
|
||||
|
||||
await chat.readLoop()
|
||||
await allFuturesThrowing(libp2pFuts)
|
||||
quit(0)
|
||||
|
||||
waitFor(main())
|
||||
|
|
|
@ -41,7 +41,7 @@ proc serveThread(udata: CustomData) {.async.} =
|
|||
if line.startsWith("/connect"):
|
||||
var parts = line.split(" ")
|
||||
if len(parts) == 2:
|
||||
var peerId = PeerID.init(parts[1])
|
||||
var peerId = PeerId.init(parts[1])
|
||||
var address = MultiAddress.init(multiCodec("p2p-circuit"))
|
||||
address &= MultiAddress.init(multiCodec("p2p"), peerId)
|
||||
echo "= Searching for peer ", peerId.pretty()
|
||||
|
@ -59,7 +59,7 @@ proc serveThread(udata: CustomData) {.async.} =
|
|||
elif line.startsWith("/search"):
|
||||
var parts = line.split(" ")
|
||||
if len(parts) == 2:
|
||||
var peerId = PeerID.init(parts[1])
|
||||
var peerId = PeerId.init(parts[1])
|
||||
echo "= Searching for peer ", peerId.pretty()
|
||||
var id = await udata.api.dhtFindPeer(peerId)
|
||||
echo "= Peer " & parts[1] & " found at addresses:"
|
||||
|
@ -68,7 +68,7 @@ proc serveThread(udata: CustomData) {.async.} =
|
|||
elif line.startsWith("/consearch"):
|
||||
var parts = line.split(" ")
|
||||
if len(parts) == 2:
|
||||
var peerId = PeerID.init(parts[1])
|
||||
var peerId = PeerId.init(parts[1])
|
||||
echo "= Searching for peers connected to peer ", parts[1]
|
||||
var peers = await udata.api.dhtFindPeersConnectedToPeer(peerId)
|
||||
echo "= Found ", len(peers), " connected to peer ", parts[1]
|
||||
|
@ -127,7 +127,7 @@ proc main() {.async.} =
|
|||
echo ">> ", line
|
||||
|
||||
await data.api.addHandler(ServerProtocols, streamHandler)
|
||||
echo "= Your PeerID is ", id.peer.pretty()
|
||||
echo "= Your PeerId is ", id.peer.pretty()
|
||||
await data.serveFut
|
||||
|
||||
when isMainModule:
|
||||
|
|
|
@ -45,10 +45,10 @@ proc main() {.async, gcsafe.} =
|
|||
let
|
||||
rng = newRng() # Single random number source for the whole application
|
||||
# port 0 will take a random available port
|
||||
# `tryGet` will throw an exception if the Multiaddress failed
|
||||
# `tryGet` will throw an exception if the MultiAddress failed
|
||||
# (for instance, if the address is not well formatted)
|
||||
ma1 = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
ma2 = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
ma1 = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
ma2 = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
|
||||
# setup the custom proto
|
||||
let testProto = TestProto.new()
|
||||
|
@ -65,9 +65,8 @@ proc main() {.async, gcsafe.} =
|
|||
|
||||
# Start the nodes. This will start the transports
|
||||
# and listen on each local addresses
|
||||
let
|
||||
switch1Fut = await switch1.start()
|
||||
switch2Fut = await switch2.start()
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
# the node addrs is populated with it's
|
||||
# actual port during the start
|
||||
|
@ -87,6 +86,5 @@ proc main() {.async, gcsafe.} =
|
|||
await conn.close()
|
||||
|
||||
await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports
|
||||
await allFutures(switch1Fut & switch2Fut) # wait for all transports to shutdown
|
||||
|
||||
waitFor(main())
|
||||
|
|
|
@ -71,8 +71,8 @@ proc dumpHex*(pbytes: pointer, nbytes: int, items = 1, ascii = true): string =
|
|||
result = result & asciiText
|
||||
result = result & "\n"
|
||||
|
||||
proc dumpHex*[T](v: openarray[T], items: int = 0, ascii = true): string =
|
||||
## Return hexadecimal memory dump representation of openarray[T] ``v``.
|
||||
proc dumpHex*[T](v: openArray[T], items: int = 0, ascii = true): string =
|
||||
## Return hexadecimal memory dump representation of openArray[T] ``v``.
|
||||
## ``items`` - number of bytes in group (supported ``items`` count is
|
||||
## 0, 1, 2, 4, 8). If ``items`` is ``0`` group size will depend on
|
||||
## ``sizeof(T)``.
|
||||
|
|
|
@ -73,9 +73,8 @@ We can now create our two switches:
|
|||
|
||||
switch1.mount(pingProtocol)
|
||||
|
||||
let
|
||||
switch1Fut = await switch1.start()
|
||||
switch2Fut = await switch2.start()
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
```
|
||||
We've **mounted** the `pingProtocol` on our first switch. This means that the first switch will actually listen for any ping requests coming in, and handle them accordingly.
|
||||
|
||||
|
@ -98,7 +97,6 @@ We now have a `Ping` connection setup between the second and the first switch, w
|
|||
And that's it! Just a little bit of cleanup: shutting down the switches, waiting for them to stop, and we'll call our `main` procedure:
|
||||
```nim
|
||||
await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports
|
||||
await allFutures(switch1Fut & switch2Fut) # wait for all transports to shutdown
|
||||
|
||||
waitFor(main())
|
||||
```
|
||||
|
|
|
@ -57,11 +57,10 @@ proc main() {.async, gcsafe.} =
|
|||
|
||||
switch1.mount(testProto)
|
||||
|
||||
let
|
||||
switch1Fut = await switch1.start()
|
||||
switch2Fut = await switch2.start()
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
||||
await testProto.hello(conn)
|
||||
|
||||
|
@ -69,7 +68,6 @@ proc main() {.async, gcsafe.} =
|
|||
await conn.close()
|
||||
|
||||
await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports
|
||||
await allFutures(switch1Fut & switch2Fut) # wait for all transports to shutdown
|
||||
```
|
||||
|
||||
This is very similar to the first tutorial's `main`, the only noteworthy difference is that we use `newStandardSwitch`, which is similar to `createSwitch` but is bundled directly in libp2p
|
||||
|
|
|
@ -11,8 +11,8 @@ requires "nim >= 1.2.0",
|
|||
"nimcrypto >= 0.4.1",
|
||||
"https://github.com/ba0f3/dnsclient.nim == 0.1.0",
|
||||
"bearssl >= 0.1.4",
|
||||
"chronicles#ba2817f1",
|
||||
"chronos >= 2.5.2",
|
||||
"chronicles >= 0.10.2",
|
||||
"chronos >= 3.0.6",
|
||||
"metrics",
|
||||
"secp256k1",
|
||||
"stew#head",
|
||||
|
@ -21,7 +21,7 @@ requires "nim >= 1.2.0",
|
|||
proc runTest(filename: string, verify: bool = true, sign: bool = true,
|
||||
moreoptions: string = "") =
|
||||
let env_nimflags = getEnv("NIMFLAGS")
|
||||
var excstr = "nim c --opt:speed -d:debug -d:libp2p_agents_metrics -d:libp2p_protobuf_metrics -d:libp2p_network_protocols_metrics --verbosity:0 --hints:off " & env_nimflags
|
||||
var excstr = "nim c --opt:speed -d:debug -d:libp2p_agents_metrics -d:libp2p_protobuf_metrics -d:libp2p_network_protocols_metrics --verbosity:0 --hints:off --styleCheck:usages --styleCheck:hint " & env_nimflags
|
||||
excstr.add(" --warning[CaseTransition]:off --warning[ObservableStores]:off --warning[LockLevel]:off")
|
||||
excstr.add(" -d:libp2p_pubsub_sign=" & $sign)
|
||||
excstr.add(" -d:libp2p_pubsub_verify=" & $verify)
|
||||
|
@ -34,7 +34,7 @@ proc runTest(filename: string, verify: bool = true, sign: bool = true,
|
|||
rmFile "tests/" & filename.toExe
|
||||
|
||||
proc buildSample(filename: string, run = false) =
|
||||
var excstr = "nim c --opt:speed --threads:on -d:debug --verbosity:0 --hints:off"
|
||||
var excstr = "nim c --opt:speed --threads:on -d:debug --verbosity:0 --hints:off "
|
||||
excstr.add(" --warning[CaseTransition]:off --warning[ObservableStores]:off --warning[LockLevel]:off")
|
||||
excstr.add(" examples/" & filename)
|
||||
exec excstr
|
||||
|
@ -94,3 +94,34 @@ task examples_build, "Build the samples":
|
|||
buildSample("helloworld", true)
|
||||
buildTutorial("examples/tutorial_1_connect.md")
|
||||
buildTutorial("examples/tutorial_2_customproto.md")
|
||||
|
||||
# pin system
|
||||
# while nimble lockfile
|
||||
# isn't available
|
||||
|
||||
const PinFile = ".pinned"
|
||||
task pin, "Create a lockfile":
|
||||
# pinner.nim was originally here
|
||||
# but you can't read output from
|
||||
# a command in a nimscript
|
||||
exec "nim c -r tools/pinner.nim"
|
||||
|
||||
import sequtils
|
||||
import os
|
||||
task install_pinned, "Reads the lockfile":
|
||||
let toInstall = readFile(PinFile).splitWhitespace().mapIt((it.split(";", 1)[0], it.split(";", 1)[1]))
|
||||
# [('packageName', 'packageFullUri')]
|
||||
|
||||
rmDir("nimbledeps")
|
||||
mkDir("nimbledeps")
|
||||
exec "nimble install -y " & toInstall.mapIt(it[1]).join(" ")
|
||||
|
||||
# Remove the automatically installed deps
|
||||
# (inefficient you say?)
|
||||
let allowedDirectories = toInstall.mapIt(it[0] & "-" & it[1].split('@')[1])
|
||||
for dependency in listDirs("nimbledeps/pkgs"):
|
||||
if dependency.extractFilename notin allowedDirectories:
|
||||
rmDir(dependency)
|
||||
|
||||
task unpin, "Restore global package use":
|
||||
rmDir("nimbledeps")
|
||||
|
|
|
@ -197,8 +197,8 @@ proc build*(b: SwitchBuilder): Switch
|
|||
|
||||
proc newStandardSwitch*(
|
||||
privKey = none(PrivateKey),
|
||||
address = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
||||
secureManagers: openarray[SecureProtocol] = [
|
||||
addrs: MultiAddress | seq[MultiAddress] = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
||||
secureManagers: openArray[SecureProtocol] = [
|
||||
SecureProtocol.Noise,
|
||||
],
|
||||
transportFlags: set[ServerFlags] = {},
|
||||
|
@ -214,9 +214,10 @@ proc newStandardSwitch*(
|
|||
if SecureProtocol.Secio in secureManagers:
|
||||
quit("Secio is deprecated!") # use of secio is unsafe
|
||||
|
||||
let addrs = when addrs is MultiAddress: @[addrs] else: addrs
|
||||
var b = SwitchBuilder
|
||||
.new()
|
||||
.withAddress(address)
|
||||
.withAddresses(addrs)
|
||||
.withRng(rng)
|
||||
.withMaxConnections(maxConnections)
|
||||
.withMaxIn(maxIn)
|
||||
|
|
|
@ -71,7 +71,7 @@ const
|
|||
template orError*(exp: untyped, err: untyped): untyped =
|
||||
(exp.mapErr do (_: auto) -> auto: err)
|
||||
|
||||
proc decode(data: openarray[byte]): Result[Cid, CidError] =
|
||||
proc decode(data: openArray[byte]): Result[Cid, CidError] =
|
||||
if len(data) == 34 and data[0] == 0x12'u8 and data[1] == 0x20'u8:
|
||||
ok(Cid(
|
||||
cidver: CIDv0,
|
||||
|
@ -114,7 +114,7 @@ proc decode(data: openarray[byte]): Result[Cid, CidError] =
|
|||
hpos: offset,
|
||||
data: vb))
|
||||
|
||||
proc decode(data: openarray[char]): Result[Cid, CidError] =
|
||||
proc decode(data: openArray[char]): Result[Cid, CidError] =
|
||||
var buffer: seq[byte]
|
||||
var plen = 0
|
||||
if len(data) < 2:
|
||||
|
@ -137,7 +137,7 @@ proc decode(data: openarray[char]): Result[Cid, CidError] =
|
|||
return err(CidError.Incorrect)
|
||||
decode(buffer)
|
||||
|
||||
proc validate*(ctype: typedesc[Cid], data: openarray[byte]): bool =
|
||||
proc validate*(ctype: typedesc[Cid], data: openArray[byte]): bool =
|
||||
## Returns ``true`` is data has valid binary CID representation.
|
||||
var version, codec: uint64
|
||||
var res: VarintResult[void]
|
||||
|
@ -185,7 +185,7 @@ proc version*(cid: Cid): CidVersion =
|
|||
## Returns CID version
|
||||
result = cid.cidver
|
||||
|
||||
proc init*[T: char|byte](ctype: typedesc[Cid], data: openarray[T]): Result[Cid, CidError] =
|
||||
proc init*[T: char|byte](ctype: typedesc[Cid], data: openArray[T]): Result[Cid, CidError] =
|
||||
## Create new content identifier using array of bytes or string ``data``.
|
||||
decode(data)
|
||||
|
||||
|
@ -275,7 +275,7 @@ proc `$`*(cid: Cid): string =
|
|||
if cid.cidver == CIDv0:
|
||||
BTCBase58.encode(cid.data.buffer)
|
||||
elif cid.cidver == CIDv1:
|
||||
let res = Multibase.encode("base58btc", cid.data.buffer)
|
||||
let res = MultiBase.encode("base58btc", cid.data.buffer)
|
||||
if res.isOk():
|
||||
res.get()
|
||||
else:
|
||||
|
|
|
@ -75,7 +75,7 @@ type
|
|||
maxConnsPerPeer: int
|
||||
inSema*: AsyncSemaphore
|
||||
outSema*: AsyncSemaphore
|
||||
conns: Table[PeerID, HashSet[Connection]]
|
||||
conns: Table[PeerId, HashSet[Connection]]
|
||||
muxed: Table[Connection, MuxerHolder]
|
||||
connEvents: array[ConnEventKind, OrderedSet[ConnEventHandler]]
|
||||
peerEvents: array[PeerEventKind, OrderedSet[PeerEventHandler]]
|
||||
|
@ -103,7 +103,7 @@ proc new*(C: type ConnManager,
|
|||
inSema: inSema,
|
||||
outSema: outSema)
|
||||
|
||||
proc connCount*(c: ConnManager, peerId: PeerID): int =
|
||||
proc connCount*(c: ConnManager, peerId: PeerId): int =
|
||||
c.conns.getOrDefault(peerId).len
|
||||
|
||||
proc addConnEventHandler*(c: ConnManager,
|
||||
|
@ -219,7 +219,7 @@ proc contains*(c: ConnManager, conn: Connection): bool =
|
|||
|
||||
return conn in c.conns.getOrDefault(conn.peerId)
|
||||
|
||||
proc contains*(c: ConnManager, peerId: PeerID): bool =
|
||||
proc contains*(c: ConnManager, peerId: PeerId): bool =
|
||||
peerId in c.conns
|
||||
|
||||
proc contains*(c: ConnManager, muxer: Muxer): bool =
|
||||
|
@ -334,7 +334,7 @@ proc onClose(c: ConnManager, conn: Connection) {.async.} =
|
|||
asyncSpawn c.peerCleanup(conn)
|
||||
|
||||
proc selectConn*(c: ConnManager,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
dir: Direction): Connection =
|
||||
## Select a connection for the provided peer and direction
|
||||
##
|
||||
|
@ -345,7 +345,7 @@ proc selectConn*(c: ConnManager,
|
|||
if conns.len > 0:
|
||||
return conns[0]
|
||||
|
||||
proc selectConn*(c: ConnManager, peerId: PeerID): Connection =
|
||||
proc selectConn*(c: ConnManager, peerId: PeerId): Connection =
|
||||
## Select a connection for the provided giving priority
|
||||
## to outgoing connections
|
||||
##
|
||||
|
@ -506,7 +506,7 @@ proc storeMuxer*(c: ConnManager,
|
|||
asyncSpawn c.onConnUpgraded(muxer.connection)
|
||||
|
||||
proc getStream*(c: ConnManager,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
dir: Direction): Future[Connection] {.async, gcsafe.} =
|
||||
## get a muxed stream for the provided peer
|
||||
## with the given direction
|
||||
|
@ -517,7 +517,7 @@ proc getStream*(c: ConnManager,
|
|||
return await muxer.newStream()
|
||||
|
||||
proc getStream*(c: ConnManager,
|
||||
peerId: PeerID): Future[Connection] {.async, gcsafe.} =
|
||||
peerId: PeerId): Future[Connection] {.async, gcsafe.} =
|
||||
## get a muxed stream for the passed peer from any connection
|
||||
##
|
||||
|
||||
|
@ -534,7 +534,7 @@ proc getStream*(c: ConnManager,
|
|||
if not(isNil(muxer)):
|
||||
return await muxer.newStream()
|
||||
|
||||
proc dropPeer*(c: ConnManager, peerId: PeerID) {.async.} =
|
||||
proc dropPeer*(c: ConnManager, peerId: PeerId) {.async.} =
|
||||
## drop connections and cleanup resources for peer
|
||||
##
|
||||
trace "Dropping peer", peerId
|
||||
|
|
|
@ -37,17 +37,17 @@ type
|
|||
ChaChaPolyNonce* = array[ChaChaPolyNonceSize, byte]
|
||||
ChaChaPolyTag* = array[ChaChaPolyTagSize, byte]
|
||||
|
||||
proc intoChaChaPolyKey*(s: openarray[byte]): ChaChaPolyKey =
|
||||
proc intoChaChaPolyKey*(s: openArray[byte]): ChaChaPolyKey =
|
||||
assert s.len == ChaChaPolyKeySize
|
||||
copyMem(addr result[0], unsafeaddr s[0], ChaChaPolyKeySize)
|
||||
copyMem(addr result[0], unsafeAddr s[0], ChaChaPolyKeySize)
|
||||
|
||||
proc intoChaChaPolyNonce*(s: openarray[byte]): ChaChaPolyNonce =
|
||||
proc intoChaChaPolyNonce*(s: openArray[byte]): ChaChaPolyNonce =
|
||||
assert s.len == ChaChaPolyNonceSize
|
||||
copyMem(addr result[0], unsafeaddr s[0], ChaChaPolyNonceSize)
|
||||
copyMem(addr result[0], unsafeAddr s[0], ChaChaPolyNonceSize)
|
||||
|
||||
proc intoChaChaPolyTag*(s: openarray[byte]): ChaChaPolyTag =
|
||||
proc intoChaChaPolyTag*(s: openArray[byte]): ChaChaPolyTag =
|
||||
assert s.len == ChaChaPolyTagSize
|
||||
copyMem(addr result[0], unsafeaddr s[0], ChaChaPolyTagSize)
|
||||
copyMem(addr result[0], unsafeAddr s[0], ChaChaPolyTagSize)
|
||||
|
||||
# bearssl allows us to use optimized versions
|
||||
# this is reconciled at runtime
|
||||
|
@ -57,17 +57,17 @@ proc encrypt*(_: type[ChaChaPoly],
|
|||
key: ChaChaPolyKey,
|
||||
nonce: ChaChaPolyNonce,
|
||||
tag: var ChaChaPolyTag,
|
||||
data: var openarray[byte],
|
||||
aad: openarray[byte]) =
|
||||
data: var openArray[byte],
|
||||
aad: openArray[byte]) =
|
||||
let
|
||||
ad = if aad.len > 0:
|
||||
unsafeaddr aad[0]
|
||||
unsafeAddr aad[0]
|
||||
else:
|
||||
nil
|
||||
|
||||
ourPoly1305CtmulRun(
|
||||
unsafeaddr key[0],
|
||||
unsafeaddr nonce[0],
|
||||
unsafeAddr key[0],
|
||||
unsafeAddr nonce[0],
|
||||
addr data[0],
|
||||
data.len,
|
||||
ad,
|
||||
|
@ -80,17 +80,17 @@ proc decrypt*(_: type[ChaChaPoly],
|
|||
key: ChaChaPolyKey,
|
||||
nonce: ChaChaPolyNonce,
|
||||
tag: var ChaChaPolyTag,
|
||||
data: var openarray[byte],
|
||||
aad: openarray[byte]) =
|
||||
data: var openArray[byte],
|
||||
aad: openArray[byte]) =
|
||||
let
|
||||
ad = if aad.len > 0:
|
||||
unsafeaddr aad[0]
|
||||
unsafeAddr aad[0]
|
||||
else:
|
||||
nil
|
||||
|
||||
ourPoly1305CtmulRun(
|
||||
unsafeaddr key[0],
|
||||
unsafeaddr nonce[0],
|
||||
unsafeAddr key[0],
|
||||
unsafeAddr nonce[0],
|
||||
addr data[0],
|
||||
data.len,
|
||||
ad,
|
||||
|
|
|
@ -130,8 +130,8 @@ type
|
|||
skkey*: SkPrivateKey
|
||||
else:
|
||||
discard
|
||||
of PKSCheme.ECDSA:
|
||||
when supported(PKSCheme.ECDSA):
|
||||
of PKScheme.ECDSA:
|
||||
when supported(PKScheme.ECDSA):
|
||||
eckey*: ecnist.EcPrivateKey
|
||||
else:
|
||||
discard
|
||||
|
@ -345,7 +345,7 @@ proc getPublicKey*(key: PrivateKey): CryptoResult[PublicKey] =
|
|||
err(SchemeError)
|
||||
|
||||
proc toRawBytes*(key: PrivateKey | PublicKey,
|
||||
data: var openarray[byte]): CryptoResult[int] =
|
||||
data: var openArray[byte]): CryptoResult[int] =
|
||||
## Serialize private key ``key`` (using scheme's own serialization) and store
|
||||
## it to ``data``.
|
||||
##
|
||||
|
@ -397,7 +397,7 @@ proc getRawBytes*(key: PrivateKey | PublicKey): CryptoResult[seq[byte]] =
|
|||
else:
|
||||
err(SchemeError)
|
||||
|
||||
proc toBytes*(key: PrivateKey, data: var openarray[byte]): CryptoResult[int] =
|
||||
proc toBytes*(key: PrivateKey, data: var openArray[byte]): CryptoResult[int] =
|
||||
## Serialize private key ``key`` (using libp2p protobuf scheme) and store
|
||||
## it to ``data``.
|
||||
##
|
||||
|
@ -411,7 +411,7 @@ proc toBytes*(key: PrivateKey, data: var openarray[byte]): CryptoResult[int] =
|
|||
copyMem(addr data[0], addr msg.buffer[0], blen)
|
||||
ok(blen)
|
||||
|
||||
proc toBytes*(key: PublicKey, data: var openarray[byte]): CryptoResult[int] =
|
||||
proc toBytes*(key: PublicKey, data: var openArray[byte]): CryptoResult[int] =
|
||||
## Serialize public key ``key`` (using libp2p protobuf scheme) and store
|
||||
## it to ``data``.
|
||||
##
|
||||
|
@ -425,7 +425,7 @@ proc toBytes*(key: PublicKey, data: var openarray[byte]): CryptoResult[int] =
|
|||
copyMem(addr data[0], addr msg.buffer[0], blen)
|
||||
ok(blen)
|
||||
|
||||
proc toBytes*(sig: Signature, data: var openarray[byte]): int =
|
||||
proc toBytes*(sig: Signature, data: var openArray[byte]): int =
|
||||
## Serialize signature ``sig`` and store it to ``data``.
|
||||
##
|
||||
## Returns number of bytes (octets) needed to store signature ``sig``.
|
||||
|
@ -455,7 +455,7 @@ proc getBytes*(sig: Signature): seq[byte] =
|
|||
## Return signature ``sig`` in binary form.
|
||||
result = sig.data
|
||||
|
||||
proc init*[T: PrivateKey|PublicKey](key: var T, data: openarray[byte]): bool =
|
||||
proc init*[T: PrivateKey|PublicKey](key: var T, data: openArray[byte]): bool =
|
||||
## Initialize private key ``key`` from libp2p's protobuf serialized raw
|
||||
## binary form.
|
||||
##
|
||||
|
@ -517,7 +517,7 @@ proc init*[T: PrivateKey|PublicKey](key: var T, data: openarray[byte]): bool =
|
|||
else:
|
||||
false
|
||||
|
||||
proc init*(sig: var Signature, data: openarray[byte]): bool =
|
||||
proc init*(sig: var Signature, data: openArray[byte]): bool =
|
||||
## Initialize signature ``sig`` from raw binary form.
|
||||
##
|
||||
## Returns ``true`` on success.
|
||||
|
@ -540,7 +540,7 @@ proc init*(sig: var Signature, data: string): bool =
|
|||
sig.init(ncrutils.fromHex(data))
|
||||
|
||||
proc init*(t: typedesc[PrivateKey],
|
||||
data: openarray[byte]): CryptoResult[PrivateKey] =
|
||||
data: openArray[byte]): CryptoResult[PrivateKey] =
|
||||
## Create new private key from libp2p's protobuf serialized binary form.
|
||||
var res: t
|
||||
if not res.init(data):
|
||||
|
@ -549,7 +549,7 @@ proc init*(t: typedesc[PrivateKey],
|
|||
ok(res)
|
||||
|
||||
proc init*(t: typedesc[PublicKey],
|
||||
data: openarray[byte]): CryptoResult[PublicKey] =
|
||||
data: openArray[byte]): CryptoResult[PublicKey] =
|
||||
## Create new public key from libp2p's protobuf serialized binary form.
|
||||
var res: t
|
||||
if not res.init(data):
|
||||
|
@ -558,7 +558,7 @@ proc init*(t: typedesc[PublicKey],
|
|||
ok(res)
|
||||
|
||||
proc init*(t: typedesc[Signature],
|
||||
data: openarray[byte]): CryptoResult[Signature] =
|
||||
data: openArray[byte]): CryptoResult[Signature] =
|
||||
## Create new public key from libp2p's protobuf serialized binary form.
|
||||
var res: t
|
||||
if not res.init(data):
|
||||
|
@ -713,7 +713,7 @@ proc `$`*(sig: Signature): string =
|
|||
result = ncrutils.toHex(sig.data)
|
||||
|
||||
proc sign*(key: PrivateKey,
|
||||
data: openarray[byte]): CryptoResult[Signature] {.gcsafe.} =
|
||||
data: openArray[byte]): CryptoResult[Signature] {.gcsafe.} =
|
||||
## Sign message ``data`` using private key ``key`` and return generated
|
||||
## signature in raw binary form.
|
||||
var res: Signature
|
||||
|
@ -747,7 +747,7 @@ proc sign*(key: PrivateKey,
|
|||
else:
|
||||
err(SchemeError)
|
||||
|
||||
proc verify*(sig: Signature, message: openarray[byte], key: PublicKey): bool =
|
||||
proc verify*(sig: Signature, message: openArray[byte], key: PublicKey): bool =
|
||||
## Verify signature ``sig`` using message ``message`` and public key ``key``.
|
||||
## Return ``true`` if message signature is valid.
|
||||
case key.scheme:
|
||||
|
@ -898,8 +898,8 @@ proc ephemeral*(
|
|||
else:
|
||||
ephemeral(Secp521r1, rng)
|
||||
|
||||
proc getOrder*(remotePubkey, localNonce: openarray[byte],
|
||||
localPubkey, remoteNonce: openarray[byte]): CryptoResult[int] =
|
||||
proc getOrder*(remotePubkey, localNonce: openArray[byte],
|
||||
localPubkey, remoteNonce: openArray[byte]): CryptoResult[int] =
|
||||
## Compare values and calculate `order` parameter.
|
||||
var ctx: sha256
|
||||
ctx.init()
|
||||
|
@ -943,7 +943,7 @@ proc selectBest*(order: int, p1, p2: string): string =
|
|||
if felement == selement:
|
||||
return felement
|
||||
|
||||
proc createProposal*(nonce, pubkey: openarray[byte],
|
||||
proc createProposal*(nonce, pubkey: openArray[byte],
|
||||
exchanges, ciphers, hashes: string): seq[byte] =
|
||||
## Create SecIO proposal message using random ``nonce``, local public key
|
||||
## ``pubkey``, comma-delimieted list of supported exchange schemes
|
||||
|
@ -977,7 +977,7 @@ proc decodeProposal*(message: seq[byte], nonce, pubkey: var seq[byte],
|
|||
r3.isOk() and r3.get() and r4.isOk() and r4.get() and
|
||||
r5.isOk() and r5.get()
|
||||
|
||||
proc createExchange*(epubkey, signature: openarray[byte]): seq[byte] =
|
||||
proc createExchange*(epubkey, signature: openArray[byte]): seq[byte] =
|
||||
## Create SecIO exchange message using ephemeral public key ``epubkey`` and
|
||||
## signature of proposal blocks ``signature``.
|
||||
var msg = initProtoBuffer({WithUint32BeLength})
|
||||
|
|
|
@ -31,9 +31,9 @@ type
|
|||
Curve25519Error* = enum
|
||||
Curver25519GenError
|
||||
|
||||
proc intoCurve25519Key*(s: openarray[byte]): Curve25519Key =
|
||||
proc intoCurve25519Key*(s: openArray[byte]): Curve25519Key =
|
||||
assert s.len == Curve25519KeySize
|
||||
copyMem(addr result[0], unsafeaddr s[0], Curve25519KeySize)
|
||||
copyMem(addr result[0], unsafeAddr s[0], Curve25519KeySize)
|
||||
|
||||
proc getBytes*(key: Curve25519Key): seq[byte] = @key
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ proc NEQ(x, y: uint32): uint32 {.inline.} =
|
|||
proc LT0(x: int32): uint32 {.inline.} =
|
||||
result = cast[uint32](x) shr 31
|
||||
|
||||
proc checkScalar(scalar: openarray[byte], curve: cint): uint32 =
|
||||
proc checkScalar(scalar: openArray[byte], curve: cint): uint32 =
|
||||
## Return ``1`` if all of the following hold:
|
||||
## - len(``scalar``) <= ``orderlen``
|
||||
## - ``scalar`` != 0
|
||||
|
@ -116,7 +116,7 @@ proc checkScalar(scalar: openarray[byte], curve: cint): uint32 =
|
|||
c = -1
|
||||
result = NEQ(z, 0'u32) and LT0(c)
|
||||
|
||||
proc checkPublic(key: openarray[byte], curve: cint): uint32 =
|
||||
proc checkPublic(key: openArray[byte], curve: cint): uint32 =
|
||||
## Return ``1`` if public key ``key`` is on curve.
|
||||
var ckey = @key
|
||||
var x = [0x00'u8, 0x01'u8]
|
||||
|
@ -315,7 +315,7 @@ proc `$`*(sig: EcSignature): string =
|
|||
else:
|
||||
result = ncrutils.toHex(sig.buffer)
|
||||
|
||||
proc toRawBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
|
||||
proc toRawBytes*(seckey: EcPrivateKey, data: var openArray[byte]): EcResult[int] =
|
||||
## Serialize EC private key ``seckey`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -331,7 +331,7 @@ proc toRawBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int]
|
|||
else:
|
||||
err(EcKeyIncorrectError)
|
||||
|
||||
proc toRawBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
|
||||
proc toRawBytes*(pubkey: EcPublicKey, data: var openArray[byte]): EcResult[int] =
|
||||
## Serialize EC public key ``pubkey`` to uncompressed form specified in
|
||||
## section 4.3.6 of ANSI X9.62.
|
||||
##
|
||||
|
@ -347,7 +347,7 @@ proc toRawBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int]
|
|||
else:
|
||||
err(EcKeyIncorrectError)
|
||||
|
||||
proc toRawBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
||||
proc toRawBytes*(sig: EcSignature, data: var openArray[byte]): int =
|
||||
## Serialize EC signature ``sig`` to raw binary form and store it to ``data``.
|
||||
##
|
||||
## Returns number of bytes (octets) needed to store EC signature, or `0`
|
||||
|
@ -358,7 +358,7 @@ proc toRawBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
|||
if len(sig.buffer) > 0:
|
||||
copyMem(addr data[0], unsafeAddr sig.buffer[0], len(sig.buffer))
|
||||
|
||||
proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
|
||||
proc toBytes*(seckey: EcPrivateKey, data: var openArray[byte]): EcResult[int] =
|
||||
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -381,11 +381,15 @@ proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
|
|||
c0.write(Asn1Tag.Oid, Asn1OidSecp521r1)
|
||||
c0.finish()
|
||||
offset = pubkey.getOffset()
|
||||
if offset < 0:
|
||||
return err(EcKeyIncorrectError)
|
||||
length = pubkey.key.qlen
|
||||
c1.write(Asn1Tag.BitString,
|
||||
pubkey.buffer.toOpenArray(offset, offset + length - 1))
|
||||
c1.finish()
|
||||
offset = seckey.getOffset()
|
||||
if offset < 0:
|
||||
return err(EcKeyIncorrectError)
|
||||
length = seckey.key.xlen
|
||||
p.write(1'u64)
|
||||
p.write(Asn1Tag.OctetString,
|
||||
|
@ -404,7 +408,7 @@ proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
|
|||
err(EcKeyIncorrectError)
|
||||
|
||||
|
||||
proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
|
||||
proc toBytes*(pubkey: EcPublicKey, data: var openArray[byte]): EcResult[int] =
|
||||
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -426,6 +430,8 @@ proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
|
|||
c.finish()
|
||||
p.write(c)
|
||||
let offset = getOffset(pubkey)
|
||||
if offset < 0:
|
||||
return err(EcKeyIncorrectError)
|
||||
let length = pubkey.key.qlen
|
||||
p.write(Asn1Tag.BitString,
|
||||
pubkey.buffer.toOpenArray(offset, offset + length - 1))
|
||||
|
@ -439,7 +445,7 @@ proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
|
|||
else:
|
||||
err(EcKeyIncorrectError)
|
||||
|
||||
proc toBytes*(sig: EcSignature, data: var openarray[byte]): EcResult[int] =
|
||||
proc toBytes*(sig: EcSignature, data: var openArray[byte]): EcResult[int] =
|
||||
## Serialize EC signature ``sig`` to ASN.1 DER binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -586,7 +592,7 @@ proc `==`*(a, b: EcSignature): bool =
|
|||
else:
|
||||
CT.isEqual(a.buffer, b.buffer)
|
||||
|
||||
proc init*(key: var EcPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
|
||||
proc init*(key: var EcPrivateKey, data: openArray[byte]): Result[void, Asn1Error] =
|
||||
## Initialize EC `private key` or `signature` ``key`` from ASN.1 DER binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -639,7 +645,7 @@ proc init*(key: var EcPrivateKey, data: openarray[byte]): Result[void, Asn1Error
|
|||
else:
|
||||
err(Asn1Error.Incorrect)
|
||||
|
||||
proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Result[void, Asn1Error] =
|
||||
proc init*(pubkey: var EcPublicKey, data: openArray[byte]): Result[void, Asn1Error] =
|
||||
## Initialize EC public key ``pubkey`` from ASN.1 DER binary representation
|
||||
## ``data``.
|
||||
##
|
||||
|
@ -698,7 +704,7 @@ proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Result[void, Asn1Err
|
|||
else:
|
||||
err(Asn1Error.Incorrect)
|
||||
|
||||
proc init*(sig: var EcSignature, data: openarray[byte]): Result[void, Asn1Error] =
|
||||
proc init*(sig: var EcSignature, data: openArray[byte]): Result[void, Asn1Error] =
|
||||
## Initialize EC signature ``sig`` from raw binary representation ``data``.
|
||||
##
|
||||
## Procedure returns ``Result[void, Asn1Error]``.
|
||||
|
@ -718,7 +724,7 @@ proc init*[T: EcPKI](sospk: var T,
|
|||
sospk.init(ncrutils.fromHex(data))
|
||||
|
||||
proc init*(t: typedesc[EcPrivateKey],
|
||||
data: openarray[byte]): EcResult[EcPrivateKey] =
|
||||
data: openArray[byte]): EcResult[EcPrivateKey] =
|
||||
## Initialize EC private key from ASN.1 DER binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var key: EcPrivateKey
|
||||
|
@ -729,7 +735,7 @@ proc init*(t: typedesc[EcPrivateKey],
|
|||
ok(key)
|
||||
|
||||
proc init*(t: typedesc[EcPublicKey],
|
||||
data: openarray[byte]): EcResult[EcPublicKey] =
|
||||
data: openArray[byte]): EcResult[EcPublicKey] =
|
||||
## Initialize EC public key from ASN.1 DER binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var key: EcPublicKey
|
||||
|
@ -740,7 +746,7 @@ proc init*(t: typedesc[EcPublicKey],
|
|||
ok(key)
|
||||
|
||||
proc init*(t: typedesc[EcSignature],
|
||||
data: openarray[byte]): EcResult[EcSignature] =
|
||||
data: openArray[byte]): EcResult[EcSignature] =
|
||||
## Initialize EC signature from raw binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var sig: EcSignature
|
||||
|
@ -755,7 +761,7 @@ proc init*[T: EcPKI](t: typedesc[T], data: string): EcResult[T] =
|
|||
## string representation ``data`` and return constructed object.
|
||||
t.init(ncrutils.fromHex(data))
|
||||
|
||||
proc initRaw*(key: var EcPrivateKey, data: openarray[byte]): bool =
|
||||
proc initRaw*(key: var EcPrivateKey, data: openArray[byte]): bool =
|
||||
## Initialize EC `private key` or `scalar` ``key`` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -784,7 +790,7 @@ proc initRaw*(key: var EcPrivateKey, data: openarray[byte]): bool =
|
|||
key.key.curve = curve
|
||||
result = true
|
||||
|
||||
proc initRaw*(pubkey: var EcPublicKey, data: openarray[byte]): bool =
|
||||
proc initRaw*(pubkey: var EcPublicKey, data: openArray[byte]): bool =
|
||||
## Initialize EC public key ``pubkey`` from raw binary representation
|
||||
## ``data``.
|
||||
##
|
||||
|
@ -815,7 +821,7 @@ proc initRaw*(pubkey: var EcPublicKey, data: openarray[byte]): bool =
|
|||
pubkey.key.curve = curve
|
||||
result = true
|
||||
|
||||
proc initRaw*(sig: var EcSignature, data: openarray[byte]): bool =
|
||||
proc initRaw*(sig: var EcSignature, data: openArray[byte]): bool =
|
||||
## Initialize EC signature ``sig`` from raw binary representation ``data``.
|
||||
##
|
||||
## Length of ``data`` array must be ``Sig256Length``, ``Sig384Length``
|
||||
|
@ -838,7 +844,7 @@ proc initRaw*[T: EcPKI](sospk: var T, data: string): bool {.inline.} =
|
|||
result = sospk.initRaw(ncrutils.fromHex(data))
|
||||
|
||||
proc initRaw*(t: typedesc[EcPrivateKey],
|
||||
data: openarray[byte]): EcResult[EcPrivateKey] =
|
||||
data: openArray[byte]): EcResult[EcPrivateKey] =
|
||||
## Initialize EC private key from raw binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var res: EcPrivateKey
|
||||
|
@ -848,7 +854,7 @@ proc initRaw*(t: typedesc[EcPrivateKey],
|
|||
ok(res)
|
||||
|
||||
proc initRaw*(t: typedesc[EcPublicKey],
|
||||
data: openarray[byte]): EcResult[EcPublicKey] =
|
||||
data: openArray[byte]): EcResult[EcPublicKey] =
|
||||
## Initialize EC public key from raw binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var res: EcPublicKey
|
||||
|
@ -858,7 +864,7 @@ proc initRaw*(t: typedesc[EcPublicKey],
|
|||
ok(res)
|
||||
|
||||
proc initRaw*(t: typedesc[EcSignature],
|
||||
data: openarray[byte]): EcResult[EcSignature] =
|
||||
data: openArray[byte]): EcResult[EcSignature] =
|
||||
## Initialize EC signature from raw binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var res: EcSignature
|
||||
|
@ -894,7 +900,7 @@ proc scalarMul*(pub: EcPublicKey, sec: EcPrivateKey): EcPublicKey =
|
|||
result = key
|
||||
|
||||
proc toSecret*(pubkey: EcPublicKey, seckey: EcPrivateKey,
|
||||
data: var openarray[byte]): int =
|
||||
data: var openArray[byte]): int =
|
||||
## Calculate ECDHE shared secret using Go's elliptic/curve approach, using
|
||||
## remote public key ``pubkey`` and local private key ``seckey`` and store
|
||||
## shared secret to ``data``.
|
||||
|
@ -931,7 +937,7 @@ proc getSecret*(pubkey: EcPublicKey, seckey: EcPrivateKey): seq[byte] =
|
|||
copyMem(addr result[0], addr data[0], res)
|
||||
|
||||
proc sign*[T: byte|char](seckey: EcPrivateKey,
|
||||
message: openarray[T]): EcResult[EcSignature] {.gcsafe.} =
|
||||
message: openArray[T]): EcResult[EcSignature] {.gcsafe.} =
|
||||
## Get ECDSA signature of data ``message`` using private key ``seckey``.
|
||||
if isNil(seckey):
|
||||
return err(EcKeyIncorrectError)
|
||||
|
@ -960,7 +966,7 @@ proc sign*[T: byte|char](seckey: EcPrivateKey,
|
|||
else:
|
||||
err(EcKeyIncorrectError)
|
||||
|
||||
proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
|
||||
proc verify*[T: byte|char](sig: EcSignature, message: openArray[T],
|
||||
pubkey: EcPublicKey): bool {.inline.} =
|
||||
## Verify ECDSA signature ``sig`` using public key ``pubkey`` and data
|
||||
## ``message``.
|
||||
|
|
|
@ -165,30 +165,30 @@ proc feCopy(h: var Fe, f: Fe) =
|
|||
h[8] = f8
|
||||
h[9] = f9
|
||||
|
||||
proc load3(inp: openarray[byte]): uint64 =
|
||||
proc load_3(inp: openArray[byte]): uint64 =
|
||||
result = cast[uint64](inp[0])
|
||||
result = result or (cast[uint64](inp[1]) shl 8)
|
||||
result = result or (cast[uint64](inp[2]) shl 16)
|
||||
|
||||
proc load4(inp: openarray[byte]): uint64 =
|
||||
proc load_4(inp: openArray[byte]): uint64 =
|
||||
result = cast[uint64](inp[0])
|
||||
result = result or (cast[uint64](inp[1]) shl 8)
|
||||
result = result or (cast[uint64](inp[2]) shl 16)
|
||||
result = result or (cast[uint64](inp[3]) shl 24)
|
||||
|
||||
proc feFromBytes(h: var Fe, s: openarray[byte]) =
|
||||
proc feFromBytes(h: var Fe, s: openArray[byte]) =
|
||||
var c0, c1, c2, c3, c4, c5, c6, c7, c8, c9: int64
|
||||
|
||||
var h0 = cast[int64](load4(s.toOpenArray(0, 3)))
|
||||
var h1 = cast[int64](load3(s.toOpenArray(4, 6))) shl 6
|
||||
var h2 = cast[int64](load3(s.toOpenArray(7, 9))) shl 5
|
||||
var h3 = cast[int64](load3(s.toOpenArray(10, 12))) shl 3
|
||||
var h4 = cast[int64](load3(s.toOpenArray(13, 15))) shl 2
|
||||
var h5 = cast[int64](load4(s.toOpenArray(16, 19)))
|
||||
var h6 = cast[int64](load3(s.toOpenArray(20, 22))) shl 7
|
||||
var h7 = cast[int64](load3(s.toOpenArray(23, 25))) shl 5
|
||||
var h8 = cast[int64](load3(s.toOpenArray(26, 28))) shl 4
|
||||
var h9 = (cast[int64](load3(s.toOpenArray(29, 31))) and 8388607'i32) shl 2
|
||||
var h0 = cast[int64](load_4(s.toOpenArray(0, 3)))
|
||||
var h1 = cast[int64](load_3(s.toOpenArray(4, 6))) shl 6
|
||||
var h2 = cast[int64](load_3(s.toOpenArray(7, 9))) shl 5
|
||||
var h3 = cast[int64](load_3(s.toOpenArray(10, 12))) shl 3
|
||||
var h4 = cast[int64](load_3(s.toOpenArray(13, 15))) shl 2
|
||||
var h5 = cast[int64](load_4(s.toOpenArray(16, 19)))
|
||||
var h6 = cast[int64](load_3(s.toOpenArray(20, 22))) shl 7
|
||||
var h7 = cast[int64](load_3(s.toOpenArray(23, 25))) shl 5
|
||||
var h8 = cast[int64](load_3(s.toOpenArray(26, 28))) shl 4
|
||||
var h9 = (cast[int64](load_3(s.toOpenArray(29, 31))) and 8388607'i32) shl 2
|
||||
|
||||
c9 = ashr((h9 + (1'i64 shl 24)), 25); h0 = h0 + (c9 * 19); h9 -= (c9 shl 25)
|
||||
c1 = ashr((h1 + (1'i64 shl 24)), 25); h2 = h2 + c1; h1 -= (c1 shl 25)
|
||||
|
@ -213,7 +213,7 @@ proc feFromBytes(h: var Fe, s: openarray[byte]) =
|
|||
h[8] = cast[int32](h8)
|
||||
h[9] = cast[int32](h9)
|
||||
|
||||
proc feToBytes(s: var openarray[byte], h: Fe) =
|
||||
proc feToBytes(s: var openArray[byte], h: Fe) =
|
||||
var h0 = h[0]; var h1 = h[1]; var h2 = h[2]; var h3 = h[3]; var h4 = h[4]
|
||||
var h5 = h[5]; var h6 = h[6]; var h7 = h[7]; var h8 = h[8]; var h9 = h[9]
|
||||
var q, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9: int32
|
||||
|
@ -450,7 +450,7 @@ proc feNeg(h: var Fe, f: Fe) =
|
|||
h[0] = h0; h[1] = h1; h[2] = h2; h[3] = h3; h[4] = h4
|
||||
h[5] = h5; h[6] = h6; h[7] = h7; h[8] = h8; h[9] = h9
|
||||
|
||||
proc verify32(x: openarray[byte], y: openarray[byte]): int32 =
|
||||
proc verify32(x: openArray[byte], y: openArray[byte]): int32 =
|
||||
var d = 0'u32
|
||||
d = d or (x[0] xor y[0])
|
||||
d = d or (x[1] xor y[1])
|
||||
|
@ -800,7 +800,7 @@ proc geAdd(r: var GeP1P1, p: GeP3, q: GeCached) =
|
|||
feAdd(r.z, t0, r.t)
|
||||
feSub(r.t, t0, r.t)
|
||||
|
||||
proc geFromBytesNegateVartime(h: var GeP3, s: openarray[byte]): int32 =
|
||||
proc geFromBytesNegateVartime(h: var GeP3, s: openArray[byte]): int32 =
|
||||
var u, v, v3, vxx, check: Fe
|
||||
|
||||
feFromBytes(h.y, s)
|
||||
|
@ -876,12 +876,12 @@ proc geSub(r: var GeP1P1, p: GeP3, q: GeCached) =
|
|||
feSub(r.z, t0, r.t)
|
||||
feAdd(r.t, t0, r.t)
|
||||
|
||||
proc geToBytes(s: var openarray[byte], h: GeP2) =
|
||||
proc geToBytes(s: var openArray[byte], h: GeP2) =
|
||||
var recip, x, y: Fe
|
||||
feInvert(recip, h.z)
|
||||
feMul(x, h.x, recip)
|
||||
feMul(y, h.y, recip)
|
||||
feTobytes(s, y)
|
||||
feToBytes(s, y)
|
||||
s[31] = s[31] xor cast[byte](feIsNegative(x) shl 7)
|
||||
|
||||
proc geP1P1toP2(r: var GeP2, p: GeP1P1) =
|
||||
|
@ -925,10 +925,10 @@ proc geP3toP2(r: var GeP2, p: GeP3) =
|
|||
|
||||
proc geP3dbl(r: var GeP1P1, p: GeP3) =
|
||||
var q: GeP2
|
||||
geP3ToP2(q, p)
|
||||
geP3toP2(q, p)
|
||||
geP2dbl(r, q)
|
||||
|
||||
proc geP3ToBytes(s: var openarray[byte], h: GeP3) =
|
||||
proc geP3ToBytes(s: var openArray[byte], h: GeP3) =
|
||||
var recip, x, y: Fe
|
||||
|
||||
feInvert(recip, h.z);
|
||||
|
@ -985,7 +985,7 @@ proc select(t: var GePrecomp, pos: int, b: int8) =
|
|||
feNeg(minust.xy2d, t.xy2d)
|
||||
cmov(t, minust, bnegative)
|
||||
|
||||
proc geScalarMultBase(h: var GeP3, a: openarray[byte]) =
|
||||
proc geScalarMultBase(h: var GeP3, a: openArray[byte]) =
|
||||
var e: array[64, int8]
|
||||
var carry: int8
|
||||
var r: GeP1P1
|
||||
|
@ -1010,8 +1010,8 @@ proc geScalarMultBase(h: var GeP3, a: openarray[byte]) =
|
|||
geMadd(r, h, t)
|
||||
geP1P1toP3(h, r)
|
||||
|
||||
geP3dbl(r, h); geP1P1ToP2(s, r)
|
||||
geP2dbl(r, s); geP1P1ToP2(s, r)
|
||||
geP3dbl(r, h); geP1P1toP2(s, r)
|
||||
geP2dbl(r, s); geP1P1toP2(s, r)
|
||||
geP2dbl(r, s); geP1P1toP2(s, r)
|
||||
geP2dbl(r, s); geP1P1toP3(h, r)
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ proc geScalarMultBase(h: var GeP3, a: openarray[byte]) =
|
|||
geMadd(r, h, t)
|
||||
geP1P1toP3(h, r)
|
||||
|
||||
proc scMulAdd(s: var openarray[byte], a, b, c: openarray[byte]) =
|
||||
proc scMulAdd(s: var openArray[byte], a, b, c: openArray[byte]) =
|
||||
var a0 = 2097151'i64 and cast[int64](load_3(a.toOpenArray(0, 2)))
|
||||
var a1 = 2097151'i64 and cast[int64](load_4(a.toOpenArray(2, 5)) shr 5)
|
||||
var a2 = 2097151'i64 and cast[int64](load_3(a.toOpenArray(5, 7)) shr 2)
|
||||
|
@ -1320,7 +1320,7 @@ proc scMulAdd(s: var openarray[byte], a, b, c: openarray[byte]) =
|
|||
s[30] = cast[uint8](ashr(s11, 9))
|
||||
s[31] = cast[uint8](ashr(s11, 17))
|
||||
|
||||
proc scReduce(s: var openarray[byte]) =
|
||||
proc scReduce(s: var openArray[byte]) =
|
||||
var s0 = 2097151'i64 and cast[int64](load_3(s.toOpenArray(0, 2)));
|
||||
var s1 = 2097151'i64 and cast[int64](load_4(s.toOpenArray(2, 5)) shr 5)
|
||||
var s2 = 2097151'i64 and cast[int64](load_3(s.toOpenArray(5, 7)) shr 2)
|
||||
|
@ -1546,7 +1546,7 @@ proc scReduce(s: var openarray[byte]) =
|
|||
s[30] = cast[byte](ashr(s11, 9))
|
||||
s[31] = cast[byte](ashr(s11, 17))
|
||||
|
||||
proc slide(r: var openarray[int8], a: openarray[byte]) =
|
||||
proc slide(r: var openArray[int8], a: openArray[byte]) =
|
||||
for i in 0..<256:
|
||||
r[i] = cast[int8](1'u8 and (a[i shr 3] shr (i and 7)))
|
||||
for i in 0..<256:
|
||||
|
@ -1567,8 +1567,8 @@ proc slide(r: var openarray[int8], a: openarray[byte]) =
|
|||
break
|
||||
inc(b)
|
||||
|
||||
proc geDoubleScalarMultVartime(r: var GeP2, a: openarray[byte], A: GeP3,
|
||||
b: openarray[byte]) =
|
||||
proc geDoubleScalarMultVartime(r: var GeP2, a: openArray[byte], A: GeP3,
|
||||
b: openArray[byte]) =
|
||||
var
|
||||
aslide: array[256, int8]
|
||||
bslide: array[256, int8]
|
||||
|
@ -1632,7 +1632,7 @@ proc NEQ(x, y: uint32): uint32 {.inline.} =
|
|||
proc LT0(x: int32): uint32 {.inline.} =
|
||||
result = cast[uint32](x) shr 31
|
||||
|
||||
proc checkScalar*(scalar: openarray[byte]): uint32 =
|
||||
proc checkScalar*(scalar: openArray[byte]): uint32 =
|
||||
var z = 0'u32
|
||||
var c = 0'i32
|
||||
for u in scalar:
|
||||
|
@ -1686,7 +1686,7 @@ proc getPublicKey*(key: EdPrivateKey): EdPublicKey =
|
|||
## Calculate and return ED25519 public key from private key ``key``.
|
||||
copyMem(addr result.data[0], unsafeAddr key.data[32], 32)
|
||||
|
||||
proc toBytes*(key: EdPrivateKey, data: var openarray[byte]): int =
|
||||
proc toBytes*(key: EdPrivateKey, data: var openArray[byte]): int =
|
||||
## Serialize ED25519 `private key` ``key`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -1696,7 +1696,7 @@ proc toBytes*(key: EdPrivateKey, data: var openarray[byte]): int =
|
|||
if len(data) >= result:
|
||||
copyMem(addr data[0], unsafeAddr key.data[0], len(key.data))
|
||||
|
||||
proc toBytes*(key: EdPublicKey, data: var openarray[byte]): int =
|
||||
proc toBytes*(key: EdPublicKey, data: var openArray[byte]): int =
|
||||
## Serialize ED25519 `public key` ``key`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -1706,7 +1706,7 @@ proc toBytes*(key: EdPublicKey, data: var openarray[byte]): int =
|
|||
if len(data) >= result:
|
||||
copyMem(addr data[0], unsafeAddr key.data[0], len(key.data))
|
||||
|
||||
proc toBytes*(sig: EdSignature, data: var openarray[byte]): int =
|
||||
proc toBytes*(sig: EdSignature, data: var openArray[byte]): int =
|
||||
## Serialize ED25519 `signature` ``sig`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -1749,7 +1749,7 @@ proc `$`*(sig: EdSignature): string =
|
|||
## Return string representation of ED25519 `signature`.
|
||||
ncrutils.toHex(sig.data)
|
||||
|
||||
proc init*(key: var EdPrivateKey, data: openarray[byte]): bool =
|
||||
proc init*(key: var EdPrivateKey, data: openArray[byte]): bool =
|
||||
## Initialize ED25519 `private key` ``key`` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -1759,7 +1759,7 @@ proc init*(key: var EdPrivateKey, data: openarray[byte]): bool =
|
|||
copyMem(addr key.data[0], unsafeAddr data[0], length)
|
||||
result = true
|
||||
|
||||
proc init*(key: var EdPublicKey, data: openarray[byte]): bool =
|
||||
proc init*(key: var EdPublicKey, data: openArray[byte]): bool =
|
||||
## Initialize ED25519 `public key` ``key`` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -1769,7 +1769,7 @@ proc init*(key: var EdPublicKey, data: openarray[byte]): bool =
|
|||
copyMem(addr key.data[0], unsafeAddr data[0], length)
|
||||
result = true
|
||||
|
||||
proc init*(sig: var EdSignature, data: openarray[byte]): bool =
|
||||
proc init*(sig: var EdSignature, data: openArray[byte]): bool =
|
||||
## Initialize ED25519 `signature` ``sig`` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -1801,7 +1801,7 @@ proc init*(sig: var EdSignature, data: string): bool =
|
|||
init(sig, ncrutils.fromHex(data))
|
||||
|
||||
proc init*(t: typedesc[EdPrivateKey],
|
||||
data: openarray[byte]): Result[EdPrivateKey, EdError] =
|
||||
data: openArray[byte]): Result[EdPrivateKey, EdError] =
|
||||
## Initialize ED25519 `private key` from raw binary representation ``data``
|
||||
## and return constructed object.
|
||||
var res: t
|
||||
|
@ -1811,7 +1811,7 @@ proc init*(t: typedesc[EdPrivateKey],
|
|||
ok(res)
|
||||
|
||||
proc init*(t: typedesc[EdPublicKey],
|
||||
data: openarray[byte]): Result[EdPublicKey, EdError] =
|
||||
data: openArray[byte]): Result[EdPublicKey, EdError] =
|
||||
## Initialize ED25519 `public key` from raw binary representation ``data``
|
||||
## and return constructed object.
|
||||
var res: t
|
||||
|
@ -1821,7 +1821,7 @@ proc init*(t: typedesc[EdPublicKey],
|
|||
ok(res)
|
||||
|
||||
proc init*(t: typedesc[EdSignature],
|
||||
data: openarray[byte]): Result[EdSignature, EdError] =
|
||||
data: openArray[byte]): Result[EdSignature, EdError] =
|
||||
## Initialize ED25519 `signature` from raw binary representation ``data``
|
||||
## and return constructed object.
|
||||
var res: t
|
||||
|
@ -1878,7 +1878,7 @@ proc clear*(pair: var EdKeyPair) =
|
|||
burnMem(pair.pubkey.data)
|
||||
|
||||
proc sign*[T: byte|char](key: EdPrivateKey,
|
||||
message: openarray[T]): EdSignature {.gcsafe, noinit.} =
|
||||
message: openArray[T]): EdSignature {.gcsafe, noinit.} =
|
||||
## Create ED25519 signature of data ``message`` using private key ``key``.
|
||||
var ctx: sha512
|
||||
var r: GeP3
|
||||
|
@ -1911,7 +1911,7 @@ proc sign*[T: byte|char](key: EdPrivateKey,
|
|||
scMulAdd(result.data.toOpenArray(32, 63), hram.data.toOpenArray(0, 31),
|
||||
hash.data.toOpenArray(0, 31), nonce.data.toOpenArray(0, 31))
|
||||
|
||||
proc verify*[T: byte|char](sig: EdSignature, message: openarray[T],
|
||||
proc verify*[T: byte|char](sig: EdSignature, message: openArray[T],
|
||||
key: EdPublicKey): bool =
|
||||
## Verify ED25519 signature ``sig`` using public key ``key`` and data
|
||||
## ``message``.
|
||||
|
|
|
@ -23,18 +23,18 @@ proc br_hkdf_inject(ctx: ptr BearHKDFContext; ikm: pointer; len: csize_t) {.impo
|
|||
proc br_hkdf_flip(ctx: ptr BearHKDFContext) {.importc: "br_hkdf_flip", header: "bearssl_kdf.h", raises: [].}
|
||||
proc br_hkdf_produce(ctx: ptr BearHKDFContext; info: pointer; infoLen: csize_t; output: pointer; outputLen: csize_t) {.importc: "br_hkdf_produce", header: "bearssl_kdf.h", raises: [].}
|
||||
|
||||
proc hkdf*[T: sha256; len: static int](_: type[T]; salt, ikm, info: openarray[byte]; outputs: var openarray[HKDFResult[len]]) =
|
||||
proc hkdf*[T: sha256; len: static int](_: type[T]; salt, ikm, info: openArray[byte]; outputs: var openArray[HKDFResult[len]]) =
|
||||
var
|
||||
ctx: BearHKDFContext
|
||||
br_hkdf_init(
|
||||
addr ctx, addr sha256Vtable,
|
||||
if salt.len > 0: unsafeaddr salt[0] else: nil, csize_t(salt.len))
|
||||
if salt.len > 0: unsafeAddr salt[0] else: nil, csize_t(salt.len))
|
||||
br_hkdf_inject(
|
||||
addr ctx, if ikm.len > 0: unsafeaddr ikm[0] else: nil, csize_t(ikm.len))
|
||||
addr ctx, if ikm.len > 0: unsafeAddr ikm[0] else: nil, csize_t(ikm.len))
|
||||
br_hkdf_flip(addr ctx)
|
||||
for i in 0..outputs.high:
|
||||
br_hkdf_produce(
|
||||
addr ctx,
|
||||
if info.len > 0: unsafeaddr info[0]
|
||||
if info.len > 0: unsafeAddr info[0]
|
||||
else: nil, csize_t(info.len),
|
||||
addr outputs[i][0], csize_t(outputs[i].len))
|
||||
|
|
|
@ -154,7 +154,7 @@ proc code*(tag: Asn1Tag): byte {.inline.} =
|
|||
of Asn1Tag.Context:
|
||||
0xA0'u8
|
||||
|
||||
proc asn1EncodeLength*(dest: var openarray[byte], length: uint64): int =
|
||||
proc asn1EncodeLength*(dest: var openArray[byte], length: uint64): int =
|
||||
## Encode ASN.1 DER length part of TLV triple and return number of bytes
|
||||
## (octets) used.
|
||||
##
|
||||
|
@ -181,8 +181,8 @@ proc asn1EncodeLength*(dest: var openarray[byte], length: uint64): int =
|
|||
# then 9, so it is safe to convert it to `int`.
|
||||
int(res)
|
||||
|
||||
proc asn1EncodeInteger*(dest: var openarray[byte],
|
||||
value: openarray[byte]): int =
|
||||
proc asn1EncodeInteger*(dest: var openArray[byte],
|
||||
value: openArray[byte]): int =
|
||||
## Encode big-endian binary representation of integer as ASN.1 DER `INTEGER`
|
||||
## and return number of bytes (octets) used.
|
||||
##
|
||||
|
@ -228,7 +228,7 @@ proc asn1EncodeInteger*(dest: var openarray[byte],
|
|||
len(value) - offset)
|
||||
destlen
|
||||
|
||||
proc asn1EncodeInteger*[T: SomeUnsignedInt](dest: var openarray[byte],
|
||||
proc asn1EncodeInteger*[T: SomeUnsignedInt](dest: var openArray[byte],
|
||||
value: T): int =
|
||||
## Encode Nim's unsigned integer as ASN.1 DER `INTEGER` and return number of
|
||||
## bytes (octets) used.
|
||||
|
@ -238,7 +238,7 @@ proc asn1EncodeInteger*[T: SomeUnsignedInt](dest: var openarray[byte],
|
|||
## but number of bytes (octets) required will be returned.
|
||||
dest.asn1EncodeInteger(value.toBytesBE())
|
||||
|
||||
proc asn1EncodeBoolean*(dest: var openarray[byte], value: bool): int =
|
||||
proc asn1EncodeBoolean*(dest: var openArray[byte], value: bool): int =
|
||||
## Encode Nim's boolean as ASN.1 DER `BOOLEAN` and return number of bytes
|
||||
## (octets) used.
|
||||
##
|
||||
|
@ -252,7 +252,7 @@ proc asn1EncodeBoolean*(dest: var openarray[byte], value: bool): int =
|
|||
dest[2] = if value: 0xFF'u8 else: 0x00'u8
|
||||
res
|
||||
|
||||
proc asn1EncodeNull*(dest: var openarray[byte]): int =
|
||||
proc asn1EncodeNull*(dest: var openArray[byte]): int =
|
||||
## Encode ASN.1 DER `NULL` and return number of bytes (octets) used.
|
||||
##
|
||||
## If length of ``dest`` is less then number of required bytes to encode
|
||||
|
@ -264,8 +264,8 @@ proc asn1EncodeNull*(dest: var openarray[byte]): int =
|
|||
dest[1] = 0x00'u8
|
||||
res
|
||||
|
||||
proc asn1EncodeOctetString*(dest: var openarray[byte],
|
||||
value: openarray[byte]): int =
|
||||
proc asn1EncodeOctetString*(dest: var openArray[byte],
|
||||
value: openArray[byte]): int =
|
||||
## Encode array of bytes as ASN.1 DER `OCTET STRING` and return number of
|
||||
## bytes (octets) used.
|
||||
##
|
||||
|
@ -282,8 +282,8 @@ proc asn1EncodeOctetString*(dest: var openarray[byte],
|
|||
copyMem(addr dest[1 + lenlen], unsafeAddr value[0], len(value))
|
||||
res
|
||||
|
||||
proc asn1EncodeBitString*(dest: var openarray[byte],
|
||||
value: openarray[byte], bits = 0): int =
|
||||
proc asn1EncodeBitString*(dest: var openArray[byte],
|
||||
value: openArray[byte], bits = 0): int =
|
||||
## Encode array of bytes as ASN.1 DER `BIT STRING` and return number of bytes
|
||||
## (octets) used.
|
||||
##
|
||||
|
@ -318,7 +318,7 @@ proc asn1EncodeBitString*(dest: var openarray[byte],
|
|||
dest[2 + lenlen + bytelen - 1] = lastbyte and mask
|
||||
res
|
||||
|
||||
proc asn1EncodeTag[T: SomeUnsignedInt](dest: var openarray[byte],
|
||||
proc asn1EncodeTag[T: SomeUnsignedInt](dest: var openArray[byte],
|
||||
value: T): int =
|
||||
var v = value
|
||||
if value <= cast[T](0x7F):
|
||||
|
@ -341,7 +341,7 @@ proc asn1EncodeTag[T: SomeUnsignedInt](dest: var openarray[byte],
|
|||
dest[k - 1] = dest[k - 1] and 0x7F'u8
|
||||
res
|
||||
|
||||
proc asn1EncodeOid*(dest: var openarray[byte], value: openarray[int]): int =
|
||||
proc asn1EncodeOid*(dest: var openArray[byte], value: openArray[int]): int =
|
||||
## Encode array of integers ``value`` as ASN.1 DER `OBJECT IDENTIFIER` and
|
||||
## return number of bytes (octets) used.
|
||||
##
|
||||
|
@ -367,7 +367,7 @@ proc asn1EncodeOid*(dest: var openarray[byte], value: openarray[int]): int =
|
|||
cast[uint64](value[i]))
|
||||
res
|
||||
|
||||
proc asn1EncodeOid*(dest: var openarray[byte], value: openarray[byte]): int =
|
||||
proc asn1EncodeOid*(dest: var openArray[byte], value: openArray[byte]): int =
|
||||
## Encode array of bytes ``value`` as ASN.1 DER `OBJECT IDENTIFIER` and return
|
||||
## number of bytes (octets) used.
|
||||
##
|
||||
|
@ -386,8 +386,8 @@ proc asn1EncodeOid*(dest: var openarray[byte], value: openarray[byte]): int =
|
|||
copyMem(addr dest[1 + lenlen], unsafeAddr value[0], len(value))
|
||||
res
|
||||
|
||||
proc asn1EncodeSequence*(dest: var openarray[byte],
|
||||
value: openarray[byte]): int =
|
||||
proc asn1EncodeSequence*(dest: var openArray[byte],
|
||||
value: openArray[byte]): int =
|
||||
## Encode ``value`` as ASN.1 DER `SEQUENCE` and return number of bytes
|
||||
## (octets) used.
|
||||
##
|
||||
|
@ -403,7 +403,7 @@ proc asn1EncodeSequence*(dest: var openarray[byte],
|
|||
copyMem(addr dest[1 + lenlen], unsafeAddr value[0], len(value))
|
||||
res
|
||||
|
||||
proc asn1EncodeComposite*(dest: var openarray[byte],
|
||||
proc asn1EncodeComposite*(dest: var openArray[byte],
|
||||
value: Asn1Composite): int =
|
||||
## Encode composite value and return number of bytes (octets) used.
|
||||
##
|
||||
|
@ -420,7 +420,7 @@ proc asn1EncodeComposite*(dest: var openarray[byte],
|
|||
len(value.buffer))
|
||||
res
|
||||
|
||||
proc asn1EncodeContextTag*(dest: var openarray[byte], value: openarray[byte],
|
||||
proc asn1EncodeContextTag*(dest: var openArray[byte], value: openArray[byte],
|
||||
tag: int): int =
|
||||
## Encode ASN.1 DER `CONTEXT SPECIFIC TAG` ``tag`` for value ``value`` and
|
||||
## return number of bytes (octets) used.
|
||||
|
@ -692,7 +692,7 @@ proc getBuffer*(field: Asn1Field): Asn1Buffer {.inline.} =
|
|||
## Return ``field`` as Asn1Buffer to enter composite types.
|
||||
Asn1Buffer(buffer: field.buffer, offset: field.offset, length: field.length)
|
||||
|
||||
proc `==`*(field: Asn1Field, data: openarray[byte]): bool =
|
||||
proc `==`*(field: Asn1Field, data: openArray[byte]): bool =
|
||||
## Compares field ``field`` data with ``data`` and returns ``true`` if both
|
||||
## buffers are equal.
|
||||
let length = len(field.buffer)
|
||||
|
@ -710,7 +710,7 @@ proc `==`*(field: Asn1Field, data: openarray[byte]): bool =
|
|||
else:
|
||||
false
|
||||
|
||||
proc init*(t: typedesc[Asn1Buffer], data: openarray[byte]): Asn1Buffer =
|
||||
proc init*(t: typedesc[Asn1Buffer], data: openArray[byte]): Asn1Buffer =
|
||||
## Initialize ``Asn1Buffer`` from array of bytes ``data``.
|
||||
Asn1Buffer(buffer: @data)
|
||||
|
||||
|
@ -825,7 +825,7 @@ proc write*[T: Asn1Buffer|Asn1Composite](abc: var T, value: bool) =
|
|||
abc.offset += length
|
||||
|
||||
proc write*[T: Asn1Buffer|Asn1Composite](abc: var T, tag: Asn1Tag,
|
||||
value: openarray[byte], bits = 0) =
|
||||
value: openArray[byte], bits = 0) =
|
||||
## Write array ``value`` using ``tag``.
|
||||
##
|
||||
## This procedure is used to write ASN.1 `INTEGER`, `OCTET STRING`,
|
||||
|
|
|
@ -279,7 +279,7 @@ proc clear*[T: RsaPKI|RsaKeyPair](pki: var T) =
|
|||
burnMem(pki.buffer)
|
||||
pki.buffer.setLen(0)
|
||||
|
||||
proc toBytes*(key: RsaPrivateKey, data: var openarray[byte]): RsaResult[int] =
|
||||
proc toBytes*(key: RsaPrivateKey, data: var openArray[byte]): RsaResult[int] =
|
||||
## Serialize RSA private key ``key`` to ASN.1 DER binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -316,7 +316,7 @@ proc toBytes*(key: RsaPrivateKey, data: var openarray[byte]): RsaResult[int] =
|
|||
else:
|
||||
err(RsaKeyIncorrectError)
|
||||
|
||||
proc toBytes*(key: RsaPublicKey, data: var openarray[byte]): RsaResult[int] =
|
||||
proc toBytes*(key: RsaPublicKey, data: var openArray[byte]): RsaResult[int] =
|
||||
## Serialize RSA public key ``key`` to ASN.1 DER binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -350,7 +350,7 @@ proc toBytes*(key: RsaPublicKey, data: var openarray[byte]): RsaResult[int] =
|
|||
else:
|
||||
err(RsaKeyIncorrectError)
|
||||
|
||||
proc toBytes*(sig: RsaSignature, data: var openarray[byte]): RSaResult[int] =
|
||||
proc toBytes*(sig: RsaSignature, data: var openArray[byte]): RsaResult[int] =
|
||||
## Serialize RSA signature ``sig`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -402,7 +402,7 @@ proc getBytes*(sig: RsaSignature): RsaResult[seq[byte]] =
|
|||
else:
|
||||
err(RsaSignatureError)
|
||||
|
||||
proc init*(key: var RsaPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
|
||||
proc init*(key: var RsaPrivateKey, data: openArray[byte]): Result[void, Asn1Error] =
|
||||
## Initialize RSA private key ``key`` from ASN.1 DER binary representation
|
||||
## ``data``.
|
||||
##
|
||||
|
@ -493,7 +493,7 @@ proc init*(key: var RsaPrivateKey, data: openarray[byte]): Result[void, Asn1Erro
|
|||
else:
|
||||
err(Asn1Error.Incorrect)
|
||||
|
||||
proc init*(key: var RsaPublicKey, data: openarray[byte]): Result[void, Asn1Error] =
|
||||
proc init*(key: var RsaPublicKey, data: openArray[byte]): Result[void, Asn1Error] =
|
||||
## Initialize RSA public key ``key`` from ASN.1 DER binary representation
|
||||
## ``data``.
|
||||
##
|
||||
|
@ -562,7 +562,7 @@ proc init*(key: var RsaPublicKey, data: openarray[byte]): Result[void, Asn1Error
|
|||
else:
|
||||
err(Asn1Error.Incorrect)
|
||||
|
||||
proc init*(sig: var RsaSignature, data: openarray[byte]): Result[void, Asn1Error] =
|
||||
proc init*(sig: var RsaSignature, data: openArray[byte]): Result[void, Asn1Error] =
|
||||
## Initialize RSA signature ``sig`` from ASN.1 DER binary representation
|
||||
## ``data``.
|
||||
##
|
||||
|
@ -583,7 +583,7 @@ proc init*[T: RsaPKI](sospk: var T,
|
|||
sospk.init(ncrutils.fromHex(data))
|
||||
|
||||
proc init*(t: typedesc[RsaPrivateKey],
|
||||
data: openarray[byte]): RsaResult[RsaPrivateKey] =
|
||||
data: openArray[byte]): RsaResult[RsaPrivateKey] =
|
||||
## Initialize RSA private key from ASN.1 DER binary representation ``data``
|
||||
## and return constructed object.
|
||||
var res: RsaPrivateKey
|
||||
|
@ -593,7 +593,7 @@ proc init*(t: typedesc[RsaPrivateKey],
|
|||
ok(res)
|
||||
|
||||
proc init*(t: typedesc[RsaPublicKey],
|
||||
data: openarray[byte]): RsaResult[RsaPublicKey] =
|
||||
data: openArray[byte]): RsaResult[RsaPublicKey] =
|
||||
## Initialize RSA public key from ASN.1 DER binary representation ``data``
|
||||
## and return constructed object.
|
||||
var res: RsaPublicKey
|
||||
|
@ -603,7 +603,7 @@ proc init*(t: typedesc[RsaPublicKey],
|
|||
ok(res)
|
||||
|
||||
proc init*(t: typedesc[RsaSignature],
|
||||
data: openarray[byte]): RsaResult[RsaSignature] =
|
||||
data: openArray[byte]): RsaResult[RsaSignature] =
|
||||
## Initialize RSA signature from raw binary representation ``data`` and
|
||||
## return constructed object.
|
||||
var res: RsaSignature
|
||||
|
@ -743,7 +743,7 @@ proc `==`*(a, b: RsaPublicKey): bool =
|
|||
(r1 and r2)
|
||||
|
||||
proc sign*[T: byte|char](key: RsaPrivateKey,
|
||||
message: openarray[T]): RsaResult[RsaSignature] {.gcsafe.} =
|
||||
message: openArray[T]): RsaResult[RsaSignature] {.gcsafe.} =
|
||||
## Get RSA PKCS1.5 signature of data ``message`` using SHA256 and private
|
||||
## key ``key``.
|
||||
if isNil(key):
|
||||
|
@ -770,7 +770,7 @@ proc sign*[T: byte|char](key: RsaPrivateKey,
|
|||
else:
|
||||
ok(res)
|
||||
|
||||
proc verify*[T: byte|char](sig: RsaSignature, message: openarray[T],
|
||||
proc verify*[T: byte|char](sig: RsaSignature, message: openArray[T],
|
||||
pubkey: RsaPublicKey): bool {.inline.} =
|
||||
## Verify RSA signature ``sig`` using public key ``pubkey`` and data
|
||||
## ``message``.
|
||||
|
|
|
@ -54,7 +54,7 @@ template seckey*(v: SkKeyPair): SkPrivateKey =
|
|||
template pubkey*(v: SkKeyPair): SkPublicKey =
|
||||
SkPublicKey(secp256k1.SkKeyPair(v).pubkey)
|
||||
|
||||
proc init*(key: var SkPrivateKey, data: openarray[byte]): SkResult[void] =
|
||||
proc init*(key: var SkPrivateKey, data: openArray[byte]): SkResult[void] =
|
||||
## Initialize Secp256k1 `private key` ``key`` from raw binary
|
||||
## representation ``data``.
|
||||
key = SkPrivateKey(? secp256k1.SkSecretKey.fromRaw(data))
|
||||
|
@ -66,7 +66,7 @@ proc init*(key: var SkPrivateKey, data: string): SkResult[void] =
|
|||
key = SkPrivateKey(? secp256k1.SkSecretKey.fromHex(data))
|
||||
ok()
|
||||
|
||||
proc init*(key: var SkPublicKey, data: openarray[byte]): SkResult[void] =
|
||||
proc init*(key: var SkPublicKey, data: openArray[byte]): SkResult[void] =
|
||||
## Initialize Secp256k1 `public key` ``key`` from raw binary
|
||||
## representation ``data``.
|
||||
key = SkPublicKey(? secp256k1.SkPublicKey.fromRaw(data))
|
||||
|
@ -78,7 +78,7 @@ proc init*(key: var SkPublicKey, data: string): SkResult[void] =
|
|||
key = SkPublicKey(? secp256k1.SkPublicKey.fromHex(data))
|
||||
ok()
|
||||
|
||||
proc init*(sig: var SkSignature, data: openarray[byte]): SkResult[void] =
|
||||
proc init*(sig: var SkSignature, data: openArray[byte]): SkResult[void] =
|
||||
## Initialize Secp256k1 `signature` ``sig`` from raw binary
|
||||
## representation ``data``.
|
||||
sig = SkSignature(? secp256k1.SkSignature.fromDer(data))
|
||||
|
@ -95,7 +95,7 @@ proc init*(sig: var SkSignature, data: string): SkResult[void] =
|
|||
return err("secp: Hex to bytes failed")
|
||||
init(sig, buffer)
|
||||
|
||||
proc init*(t: typedesc[SkPrivateKey], data: openarray[byte]): SkResult[SkPrivateKey] =
|
||||
proc init*(t: typedesc[SkPrivateKey], data: openArray[byte]): SkResult[SkPrivateKey] =
|
||||
## Initialize Secp256k1 `private key` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -109,7 +109,7 @@ proc init*(t: typedesc[SkPrivateKey], data: string): SkResult[SkPrivateKey] =
|
|||
## Procedure returns `private key` on success.
|
||||
SkSecretKey.fromHex(data).mapConvert(SkPrivateKey)
|
||||
|
||||
proc init*(t: typedesc[SkPublicKey], data: openarray[byte]): SkResult[SkPublicKey] =
|
||||
proc init*(t: typedesc[SkPublicKey], data: openArray[byte]): SkResult[SkPublicKey] =
|
||||
## Initialize Secp256k1 `public key` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -125,7 +125,7 @@ proc init*(t: typedesc[SkPublicKey], data: string): SkResult[SkPublicKey] =
|
|||
var key: SkPublicKey
|
||||
key.init(data) and ok(key)
|
||||
|
||||
proc init*(t: typedesc[SkSignature], data: openarray[byte]): SkResult[SkSignature] =
|
||||
proc init*(t: typedesc[SkSignature], data: openArray[byte]): SkResult[SkSignature] =
|
||||
## Initialize Secp256k1 `signature` from raw binary
|
||||
## representation ``data``.
|
||||
##
|
||||
|
@ -145,7 +145,7 @@ proc getPublicKey*(key: SkPrivateKey): SkPublicKey =
|
|||
## Calculate and return Secp256k1 `public key` from `private key` ``key``.
|
||||
SkPublicKey(SkSecretKey(key).toPublicKey())
|
||||
|
||||
proc toBytes*(key: SkPrivateKey, data: var openarray[byte]): SkResult[int] =
|
||||
proc toBytes*(key: SkPrivateKey, data: var openArray[byte]): SkResult[int] =
|
||||
## Serialize Secp256k1 `private key` ``key`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -157,7 +157,7 @@ proc toBytes*(key: SkPrivateKey, data: var openarray[byte]): SkResult[int] =
|
|||
else:
|
||||
err("secp: Not enough bytes")
|
||||
|
||||
proc toBytes*(key: SkPublicKey, data: var openarray[byte]): SkResult[int] =
|
||||
proc toBytes*(key: SkPublicKey, data: var openArray[byte]): SkResult[int] =
|
||||
## Serialize Secp256k1 `public key` ``key`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -169,7 +169,7 @@ proc toBytes*(key: SkPublicKey, data: var openarray[byte]): SkResult[int] =
|
|||
else:
|
||||
err("secp: Not enough bytes")
|
||||
|
||||
proc toBytes*(sig: SkSignature, data: var openarray[byte]): int =
|
||||
proc toBytes*(sig: SkSignature, data: var openArray[byte]): int =
|
||||
## Serialize Secp256k1 `signature` ``sig`` to raw binary form and store it
|
||||
## to ``data``.
|
||||
##
|
||||
|
@ -191,12 +191,12 @@ proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
|
|||
let length = toBytes(sig, result)
|
||||
result.setLen(length)
|
||||
|
||||
proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkSignature =
|
||||
proc sign*[T: byte|char](key: SkPrivateKey, msg: openArray[T]): SkSignature =
|
||||
## Sign message `msg` using private key `key` and return signature object.
|
||||
let h = sha256.digest(msg)
|
||||
SkSignature(sign(SkSecretKey(key), SkMessage(h.data)))
|
||||
|
||||
proc verify*[T: byte|char](sig: SkSignature, msg: openarray[T],
|
||||
proc verify*[T: byte|char](sig: SkSignature, msg: openArray[T],
|
||||
key: SkPublicKey): bool =
|
||||
let h = sha256.digest(msg)
|
||||
verify(secp256k1.SkSignature(sig), SkMessage(h.data), secp256k1.SkPublicKey(key))
|
||||
|
|
|
@ -107,12 +107,12 @@ type
|
|||
RelayActive, ## Enables active mode for relay.
|
||||
RelayDiscovery,## Enables passive discovery for relay.
|
||||
RelayHop, ## Enables hop for relay.
|
||||
NoInlinePeerID,## Disable inlining of peer ID (not yet in #master).
|
||||
NoInlinePeerId,## Disable inlining of peer ID (not yet in #master).
|
||||
NoProcessCtrl ## Process was not spawned.
|
||||
|
||||
P2PStream* = ref object
|
||||
flags*: set[P2PStreamFlags]
|
||||
peer*: PeerID
|
||||
peer*: PeerId
|
||||
raddress*: MultiAddress
|
||||
protocol*: string
|
||||
transp*: StreamTransport
|
||||
|
@ -133,7 +133,7 @@ type
|
|||
userData*: RootRef
|
||||
|
||||
PeerInfo* = object
|
||||
peer*: PeerID
|
||||
peer*: PeerId
|
||||
addresses*: seq[MultiAddress]
|
||||
|
||||
PubsubTicket* = ref object
|
||||
|
@ -142,7 +142,7 @@ type
|
|||
transp*: StreamTransport
|
||||
|
||||
PubSubMessage* = object
|
||||
peer*: PeerID
|
||||
peer*: PeerId
|
||||
data*: seq[byte]
|
||||
seqno*: seq[byte]
|
||||
topics*: seq[string]
|
||||
|
@ -170,8 +170,8 @@ proc requestIdentity(): ProtoBuffer =
|
|||
result.write(1, cast[uint](RequestType.IDENTIFY))
|
||||
result.finish()
|
||||
|
||||
proc requestConnect(peerid: PeerID,
|
||||
addresses: openarray[MultiAddress],
|
||||
proc requestConnect(peerid: PeerId,
|
||||
addresses: openArray[MultiAddress],
|
||||
timeout = 0): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/conn.go
|
||||
## Processing function `doConnect(req *pb.Request)`.
|
||||
|
@ -186,7 +186,7 @@ proc requestConnect(peerid: PeerID,
|
|||
result.write(2, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestDisconnect(peerid: PeerID): ProtoBuffer =
|
||||
proc requestDisconnect(peerid: PeerId): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/conn.go
|
||||
## Processing function `doDisconnect(req *pb.Request)`.
|
||||
result = initProtoBuffer({WithVarintLength})
|
||||
|
@ -196,8 +196,8 @@ proc requestDisconnect(peerid: PeerID): ProtoBuffer =
|
|||
result.write(7, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestStreamOpen(peerid: PeerID,
|
||||
protocols: openarray[string],
|
||||
proc requestStreamOpen(peerid: PeerId,
|
||||
protocols: openArray[string],
|
||||
timeout = 0): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/conn.go
|
||||
## Processing function `doStreamOpen(req *pb.Request)`.
|
||||
|
@ -213,7 +213,7 @@ proc requestStreamOpen(peerid: PeerID,
|
|||
result.finish()
|
||||
|
||||
proc requestStreamHandler(address: MultiAddress,
|
||||
protocols: openarray[MultiProtocol]): ProtoBuffer =
|
||||
protocols: openArray[MultiProtocol]): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/conn.go
|
||||
## Processing function `doStreamHandler(req *pb.Request)`.
|
||||
result = initProtoBuffer({WithVarintLength})
|
||||
|
@ -232,7 +232,7 @@ proc requestListPeers(): ProtoBuffer =
|
|||
result.write(1, cast[uint](RequestType.LIST_PEERS))
|
||||
result.finish()
|
||||
|
||||
proc requestDHTFindPeer(peer: PeerID, timeout = 0): ProtoBuffer =
|
||||
proc requestDHTFindPeer(peer: PeerId, timeout = 0): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/dht.go
|
||||
## Processing function `doDHTFindPeer(req *pb.DHTRequest)`.
|
||||
let msgid = cast[uint](DHTRequestType.FIND_PEER)
|
||||
|
@ -247,7 +247,7 @@ proc requestDHTFindPeer(peer: PeerID, timeout = 0): ProtoBuffer =
|
|||
result.write(5, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestDHTFindPeersConnectedToPeer(peer: PeerID,
|
||||
proc requestDHTFindPeersConnectedToPeer(peer: PeerId,
|
||||
timeout = 0): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/dht.go
|
||||
## Processing function `doDHTFindPeersConnectedToPeer(req *pb.DHTRequest)`.
|
||||
|
@ -295,7 +295,7 @@ proc requestDHTGetClosestPeers(key: string, timeout = 0): ProtoBuffer =
|
|||
result.write(5, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestDHTGetPublicKey(peer: PeerID, timeout = 0): ProtoBuffer =
|
||||
proc requestDHTGetPublicKey(peer: PeerId, timeout = 0): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/dht.go
|
||||
## Processing function `doDHTGetPublicKey(req *pb.DHTRequest)`.
|
||||
let msgid = cast[uint](DHTRequestType.GET_PUBLIC_KEY)
|
||||
|
@ -340,7 +340,7 @@ proc requestDHTSearchValue(key: string, timeout = 0): ProtoBuffer =
|
|||
result.write(5, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestDHTPutValue(key: string, value: openarray[byte],
|
||||
proc requestDHTPutValue(key: string, value: openArray[byte],
|
||||
timeout = 0): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/dht.go
|
||||
## Processing function `doDHTPutValue(req *pb.DHTRequest)`.
|
||||
|
@ -372,7 +372,7 @@ proc requestDHTProvide(cid: Cid, timeout = 0): ProtoBuffer =
|
|||
result.write(5, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestCMTagPeer(peer: PeerID, tag: string, weight: int): ProtoBuffer =
|
||||
proc requestCMTagPeer(peer: PeerId, tag: string, weight: int): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/connmgr.go#L18
|
||||
let msgid = cast[uint](ConnManagerRequestType.TAG_PEER)
|
||||
result = initProtoBuffer({WithVarintLength})
|
||||
|
@ -386,7 +386,7 @@ proc requestCMTagPeer(peer: PeerID, tag: string, weight: int): ProtoBuffer =
|
|||
result.write(6, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestCMUntagPeer(peer: PeerID, tag: string): ProtoBuffer =
|
||||
proc requestCMUntagPeer(peer: PeerId, tag: string): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/connmgr.go#L33
|
||||
let msgid = cast[uint](ConnManagerRequestType.UNTAG_PEER)
|
||||
result = initProtoBuffer({WithVarintLength})
|
||||
|
@ -435,7 +435,7 @@ proc requestPSListPeers(topic: string): ProtoBuffer =
|
|||
result.write(8, msg)
|
||||
result.finish()
|
||||
|
||||
proc requestPSPublish(topic: string, data: openarray[byte]): ProtoBuffer =
|
||||
proc requestPSPublish(topic: string, data: openArray[byte]): ProtoBuffer =
|
||||
## https://github.com/libp2p/go-libp2p-daemon/blob/master/pubsub.go
|
||||
## Processing function `doPubsubPublish(req *pb.PSRequest)`.
|
||||
let msgid = cast[uint](PSRequestType.PUBLISH)
|
||||
|
@ -725,8 +725,8 @@ proc newDaemonApi*(flags: set[P2PDaemonFlags] = {},
|
|||
args.add("-relayDiscovery=true")
|
||||
if RelayHop in api.flags:
|
||||
args.add("-relayHop=true")
|
||||
if NoInlinePeerID in api.flags:
|
||||
args.add("-noInlinePeerID=true")
|
||||
if NoInlinePeerId in api.flags:
|
||||
args.add("-noInlinePeerId=true")
|
||||
if len(bootstrapNodes) > 0:
|
||||
args.add("-bootstrapPeers=" & bootstrapNodes.join(","))
|
||||
if len(id) != 0:
|
||||
|
@ -853,7 +853,7 @@ proc identity*(api: DaemonAPI): Future[PeerInfo] {.async.} =
|
|||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc connect*(api: DaemonAPI, peer: PeerID,
|
||||
proc connect*(api: DaemonAPI, peer: PeerId,
|
||||
addresses: seq[MultiAddress],
|
||||
timeout = 0) {.async.} =
|
||||
## Connect to remote peer with id ``peer`` and addresses ``addresses``.
|
||||
|
@ -866,7 +866,7 @@ proc connect*(api: DaemonAPI, peer: PeerID,
|
|||
except:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc disconnect*(api: DaemonAPI, peer: PeerID) {.async.} =
|
||||
proc disconnect*(api: DaemonAPI, peer: PeerId) {.async.} =
|
||||
## Disconnect from remote peer with id ``peer``.
|
||||
var transp = await api.newConnection()
|
||||
try:
|
||||
|
@ -876,7 +876,7 @@ proc disconnect*(api: DaemonAPI, peer: PeerID) {.async.} =
|
|||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc openStream*(api: DaemonAPI, peer: PeerID,
|
||||
proc openStream*(api: DaemonAPI, peer: PeerId,
|
||||
protocols: seq[string],
|
||||
timeout = 0): Future[P2PStream] {.async.} =
|
||||
## Open new stream to peer ``peer`` using one of the protocols in
|
||||
|
@ -961,7 +961,7 @@ proc listPeers*(api: DaemonAPI): Future[seq[PeerInfo]] {.async.} =
|
|||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc cmTagPeer*(api: DaemonAPI, peer: PeerID, tag: string,
|
||||
proc cmTagPeer*(api: DaemonAPI, peer: PeerId, tag: string,
|
||||
weight: int) {.async.} =
|
||||
## Tag peer with id ``peer`` using ``tag`` and ``weight``.
|
||||
var transp = await api.newConnection()
|
||||
|
@ -972,7 +972,7 @@ proc cmTagPeer*(api: DaemonAPI, peer: PeerID, tag: string,
|
|||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc cmUntagPeer*(api: DaemonAPI, peer: PeerID, tag: string) {.async.} =
|
||||
proc cmUntagPeer*(api: DaemonAPI, peer: PeerId, tag: string) {.async.} =
|
||||
## Remove tag ``tag`` from peer with id ``peer``.
|
||||
var transp = await api.newConnection()
|
||||
try:
|
||||
|
@ -1011,7 +1011,7 @@ proc dhtGetSinglePublicKey(pb: ProtoBuffer): PublicKey
|
|||
if pb.getRequiredField(3, result).isErr():
|
||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||
|
||||
proc dhtGetSinglePeerID(pb: ProtoBuffer): PeerID
|
||||
proc dhtGetSinglePeerId(pb: ProtoBuffer): PeerId
|
||||
{.raises: [Defect, DaemonLocalError].} =
|
||||
if pb.getRequiredField(3, result).isErr():
|
||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||
|
@ -1055,7 +1055,7 @@ proc getDhtMessageType(pb: ProtoBuffer): DHTResponseType
|
|||
else:
|
||||
raise newException(DaemonLocalError, "Wrong DHT answer type!")
|
||||
|
||||
proc dhtFindPeer*(api: DaemonAPI, peer: PeerID,
|
||||
proc dhtFindPeer*(api: DaemonAPI, peer: PeerId,
|
||||
timeout = 0): Future[PeerInfo] {.async.} =
|
||||
## Find peer with id ``peer`` and return peer information ``PeerInfo``.
|
||||
##
|
||||
|
@ -1069,7 +1069,7 @@ proc dhtFindPeer*(api: DaemonAPI, peer: PeerID,
|
|||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc dhtGetPublicKey*(api: DaemonAPI, peer: PeerID,
|
||||
proc dhtGetPublicKey*(api: DaemonAPI, peer: PeerId,
|
||||
timeout = 0): Future[PublicKey] {.async.} =
|
||||
## Get peer's public key from peer with id ``peer``.
|
||||
##
|
||||
|
@ -1125,7 +1125,7 @@ proc dhtProvide*(api: DaemonAPI, cid: Cid, timeout = 0) {.async.} =
|
|||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
||||
proc dhtFindPeersConnectedToPeer*(api: DaemonAPI, peer: PeerID,
|
||||
proc dhtFindPeersConnectedToPeer*(api: DaemonAPI, peer: PeerId,
|
||||
timeout = 0): Future[seq[PeerInfo]] {.async.} =
|
||||
## Find peers which are connected to peer with id ``peer``.
|
||||
##
|
||||
|
@ -1151,13 +1151,13 @@ proc dhtFindPeersConnectedToPeer*(api: DaemonAPI, peer: PeerID,
|
|||
await api.closeConnection(transp)
|
||||
|
||||
proc dhtGetClosestPeers*(api: DaemonAPI, key: string,
|
||||
timeout = 0): Future[seq[PeerID]] {.async.} =
|
||||
timeout = 0): Future[seq[PeerId]] {.async.} =
|
||||
## Get closest peers for ``key``.
|
||||
##
|
||||
## You can specify timeout for DHT request with ``timeout`` value. ``0`` value
|
||||
## means no timeout.
|
||||
var transp = await api.newConnection()
|
||||
var list = newSeq[PeerID]()
|
||||
var list = newSeq[PeerId]()
|
||||
try:
|
||||
let spb = requestDHTGetClosestPeers(key, timeout)
|
||||
var pb = await transp.transactMessage(spb)
|
||||
|
@ -1170,7 +1170,7 @@ proc dhtGetClosestPeers*(api: DaemonAPI, key: string,
|
|||
var cpb = initProtoBuffer(message)
|
||||
if cpb.getDhtMessageType() == DHTResponseType.END:
|
||||
break
|
||||
list.add(cpb.dhtGetSinglePeerID())
|
||||
list.add(cpb.dhtGetSinglePeerId())
|
||||
result = list
|
||||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
@ -1238,14 +1238,14 @@ proc pubsubGetTopics*(api: DaemonAPI): Future[seq[string]] {.async.} =
|
|||
await api.closeConnection(transp)
|
||||
|
||||
proc pubsubListPeers*(api: DaemonAPI,
|
||||
topic: string): Future[seq[PeerID]] {.async.} =
|
||||
topic: string): Future[seq[PeerId]] {.async.} =
|
||||
## Get list of peers we are connected to and which also subscribed to topic
|
||||
## ``topic``.
|
||||
var transp = await api.newConnection()
|
||||
try:
|
||||
var pb = await transp.transactMessage(requestPSListPeers(topic))
|
||||
withMessage(pb) do:
|
||||
var peer: PeerID
|
||||
var peer: PeerId
|
||||
let innerPb = pb.enterPsMessage()
|
||||
var peers = newSeq[seq[byte]]()
|
||||
discard innerPb.getRepeatedField(2, peers)
|
||||
|
@ -1308,7 +1308,7 @@ proc pubsubSubscribe*(api: DaemonAPI, topic: string,
|
|||
proc shortLog*(pinfo: PeerInfo): string =
|
||||
## Get string representation of ``PeerInfo`` object.
|
||||
result = newStringOfCap(128)
|
||||
result.add("{PeerID: '")
|
||||
result.add("{PeerId: '")
|
||||
result.add($pinfo.peer.shortLog())
|
||||
result.add("' Addresses: [")
|
||||
let length = len(pinfo.addresses)
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
## option enabled ``nim-libp2p`` will create dumps of unencrypted messages for
|
||||
## every peer libp2p communicates.
|
||||
##
|
||||
## Every file is created with name "<PeerID>.pbcap". One file represents
|
||||
## all the communication with peer which identified by ``PeerID``.
|
||||
## Every file is created with name "<PeerId>.pbcap". One file represents
|
||||
## all the communication with peer which identified by ``PeerId``.
|
||||
##
|
||||
## File can have multiple protobuf encoded messages of this format:
|
||||
##
|
||||
|
@ -170,7 +170,7 @@ iterator messages*(data: seq[byte]): Option[ProtoMessage] =
|
|||
else:
|
||||
break
|
||||
|
||||
proc dumpHex*(pbytes: openarray[byte], groupBy = 1, ascii = true): string =
|
||||
proc dumpHex*(pbytes: openArray[byte], groupBy = 1, ascii = true): string =
|
||||
## Get hexadecimal dump of memory for array ``pbytes``.
|
||||
var res = ""
|
||||
var offset = 0
|
||||
|
|
|
@ -18,7 +18,7 @@ type
|
|||
|
||||
method connect*(
|
||||
self: Dial,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress]) {.async, base.} =
|
||||
## connect remote peer without negotiating
|
||||
## a protocol
|
||||
|
@ -28,7 +28,7 @@ method connect*(
|
|||
|
||||
method dial*(
|
||||
self: Dial,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
protos: seq[string]): Future[Connection] {.async, base.} =
|
||||
## create a protocol stream over an
|
||||
## existing connection
|
||||
|
@ -38,7 +38,7 @@ method dial*(
|
|||
|
||||
method dial*(
|
||||
self: Dial,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress],
|
||||
protos: seq[string]): Future[Connection] {.async, base.} =
|
||||
## create a protocol stream and establish
|
||||
|
|
|
@ -40,13 +40,13 @@ type
|
|||
localPeerId*: PeerId
|
||||
ms: MultistreamSelect
|
||||
connManager: ConnManager
|
||||
dialLock: Table[PeerID, AsyncLock]
|
||||
dialLock: Table[PeerId, AsyncLock]
|
||||
transports: seq[Transport]
|
||||
nameResolver: NameResolver
|
||||
|
||||
proc dialAndUpgrade(
|
||||
self: Dialer,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress]):
|
||||
Future[Connection] {.async.} =
|
||||
debug "Dialing peer", peerId
|
||||
|
@ -111,7 +111,7 @@ proc dialAndUpgrade(
|
|||
|
||||
proc internalConnect(
|
||||
self: Dialer,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress]):
|
||||
Future[Connection] {.async.} =
|
||||
if self.localPeerId == peerId:
|
||||
|
@ -158,7 +158,7 @@ proc internalConnect(
|
|||
|
||||
method connect*(
|
||||
self: Dialer,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress]) {.async.} =
|
||||
## connect remote peer without negotiating
|
||||
## a protocol
|
||||
|
@ -183,7 +183,7 @@ proc negotiateStream(
|
|||
|
||||
method dial*(
|
||||
self: Dialer,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
protos: seq[string]): Future[Connection] {.async.} =
|
||||
## create a protocol stream over an
|
||||
## existing connection
|
||||
|
@ -198,7 +198,7 @@ method dial*(
|
|||
|
||||
method dial*(
|
||||
self: Dialer,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress],
|
||||
protos: seq[string]): Future[Connection] {.async.} =
|
||||
## create a protocol stream and establish
|
||||
|
|
|
@ -498,7 +498,7 @@ proc protoName*(ma: MultiAddress): MaResult[string] =
|
|||
ok($(proto.mcodec))
|
||||
|
||||
proc protoArgument*(ma: MultiAddress,
|
||||
value: var openarray[byte]): MaResult[int] =
|
||||
value: var openArray[byte]): MaResult[int] =
|
||||
## Returns MultiAddress ``ma`` protocol argument value.
|
||||
##
|
||||
## If current MultiAddress do not have argument value, then result will be
|
||||
|
@ -723,7 +723,7 @@ proc validate*(ma: MultiAddress): bool =
|
|||
|
||||
proc init*(
|
||||
mtype: typedesc[MultiAddress], protocol: MultiCodec,
|
||||
value: openarray[byte] = []): MaResult[MultiAddress] =
|
||||
value: openArray[byte] = []): MaResult[MultiAddress] =
|
||||
## Initialize MultiAddress object from protocol id ``protocol`` and array
|
||||
## of bytes ``value``.
|
||||
let proto = CodeAddresses.getOrDefault(protocol)
|
||||
|
@ -754,7 +754,7 @@ proc init*(
|
|||
raiseAssert "None checked above"
|
||||
|
||||
proc init*(mtype: typedesc[MultiAddress], protocol: MultiCodec,
|
||||
value: PeerID): MaResult[MultiAddress] {.inline.} =
|
||||
value: PeerId): MaResult[MultiAddress] {.inline.} =
|
||||
## Initialize MultiAddress object from protocol id ``protocol`` and peer id
|
||||
## ``value``.
|
||||
init(mtype, protocol, value.data)
|
||||
|
@ -832,7 +832,7 @@ proc init*(mtype: typedesc[MultiAddress],
|
|||
ok(res)
|
||||
|
||||
proc init*(mtype: typedesc[MultiAddress],
|
||||
data: openarray[byte]): MaResult[MultiAddress] =
|
||||
data: openArray[byte]): MaResult[MultiAddress] =
|
||||
## Initialize MultiAddress with array of bytes ``data``.
|
||||
if len(data) == 0:
|
||||
err("multiaddress: Address could not be empty!")
|
||||
|
@ -1005,7 +1005,7 @@ proc `$`*(pat: MaPattern): string =
|
|||
proc write*(pb: var ProtoBuffer, field: int, value: MultiAddress) {.inline.} =
|
||||
write(pb, field, value.data.buffer)
|
||||
|
||||
proc getField*(pb: var ProtoBuffer, field: int,
|
||||
proc getField*(pb: ProtoBuffer, field: int,
|
||||
value: var MultiAddress): ProtoResult[bool] {.
|
||||
inline.} =
|
||||
var buffer: seq[byte]
|
||||
|
|
|
@ -19,7 +19,7 @@ import tables
|
|||
import stew/[base32, base58, base64, results]
|
||||
|
||||
type
|
||||
MultibaseStatus* {.pure.} = enum
|
||||
MultiBaseStatus* {.pure.} = enum
|
||||
Error, Success, Overrun, Incorrect, BadCodec, NotSupported
|
||||
|
||||
MultiBase* = object
|
||||
|
@ -29,169 +29,169 @@ type
|
|||
MBCodec = object
|
||||
code: char
|
||||
name: string
|
||||
encr: proc(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus {.nimcall, gcsafe, noSideEffect, raises: [Defect].}
|
||||
decr: proc(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus {.nimcall, gcsafe, noSideEffect, raises: [Defect].}
|
||||
encr: proc(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus {.nimcall, gcsafe, noSideEffect, raises: [Defect].}
|
||||
decr: proc(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus {.nimcall, gcsafe, noSideEffect, raises: [Defect].}
|
||||
encl: MBCodeSize
|
||||
decl: MBCodeSize
|
||||
|
||||
proc idd(inbytes: openarray[char], outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc idd(inbytes: openArray[char], outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
let length = len(inbytes)
|
||||
if length > len(outbytes):
|
||||
outlen = length
|
||||
result = MultibaseStatus.Overrun
|
||||
result = MultiBaseStatus.Overrun
|
||||
else:
|
||||
copyMem(addr outbytes[0], unsafeAddr inbytes[0], length)
|
||||
outlen = length
|
||||
result = MultibaseStatus.Success
|
||||
result = MultiBaseStatus.Success
|
||||
|
||||
proc ide(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc ide(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
let length = len(inbytes)
|
||||
if length > len(outbytes):
|
||||
outlen = length
|
||||
result = MultibaseStatus.Overrun
|
||||
result = MultiBaseStatus.Overrun
|
||||
else:
|
||||
copyMem(addr outbytes[0], unsafeAddr inbytes[0], length)
|
||||
outlen = length
|
||||
result = MultibaseStatus.Success
|
||||
result = MultiBaseStatus.Success
|
||||
|
||||
proc idel(length: int): int = length
|
||||
proc iddl(length: int): int = length
|
||||
|
||||
proc b16d(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b16d(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
discard
|
||||
|
||||
proc b16e(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b16e(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
discard
|
||||
|
||||
proc b16ud(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b16ud(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
discard
|
||||
|
||||
proc b16ue(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b16ue(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
discard
|
||||
|
||||
proc b16el(length: int): int = length shl 1
|
||||
proc b16dl(length: int): int = (length + 1) div 2
|
||||
|
||||
proc b32ce(r: Base32Status): MultibaseStatus {.inline.} =
|
||||
result = MultibaseStatus.Error
|
||||
proc b32ce(r: Base32Status): MultiBaseStatus {.inline.} =
|
||||
result = MultiBaseStatus.Error
|
||||
if r == Base32Status.Incorrect:
|
||||
result = MultibaseStatus.Incorrect
|
||||
result = MultiBaseStatus.Incorrect
|
||||
elif r == Base32Status.Overrun:
|
||||
result = MultibaseStatus.Overrun
|
||||
result = MultiBaseStatus.Overrun
|
||||
elif r == Base32Status.Success:
|
||||
result = MultibaseStatus.Success
|
||||
result = MultiBaseStatus.Success
|
||||
|
||||
proc b58ce(r: Base58Status): MultibaseStatus {.inline.} =
|
||||
result = MultibaseStatus.Error
|
||||
proc b58ce(r: Base58Status): MultiBaseStatus {.inline.} =
|
||||
result = MultiBaseStatus.Error
|
||||
if r == Base58Status.Incorrect:
|
||||
result = MultibaseStatus.Incorrect
|
||||
result = MultiBaseStatus.Incorrect
|
||||
elif r == Base58Status.Overrun:
|
||||
result = MultibaseStatus.Overrun
|
||||
result = MultiBaseStatus.Overrun
|
||||
elif r == Base58Status.Success:
|
||||
result = MultibaseStatus.Success
|
||||
result = MultiBaseStatus.Success
|
||||
|
||||
proc b64ce(r: Base64Status): MultibaseStatus {.inline.} =
|
||||
proc b64ce(r: Base64Status): MultiBaseStatus {.inline.} =
|
||||
result = MultiBaseStatus.Error
|
||||
if r == Base64Status.Incorrect:
|
||||
result = MultibaseStatus.Incorrect
|
||||
result = MultiBaseStatus.Incorrect
|
||||
elif r == Base64Status.Overrun:
|
||||
result = MultiBaseStatus.Overrun
|
||||
elif r == Base64Status.Success:
|
||||
result = MultibaseStatus.Success
|
||||
result = MultiBaseStatus.Success
|
||||
|
||||
proc b32hd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32Lower.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32he(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32he(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32Lower.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32hud(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hud(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32Upper.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32hue(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hue(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32Upper.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32hpd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hpd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32LowerPad.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32hpe(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hpe(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32LowerPad.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32hpud(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hpud(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32UpperPad.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32hpue(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32hpue(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(HexBase32UpperPad.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32d(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32d(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32Lower.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32e(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32e(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32Lower.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32ud(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32ud(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32Upper.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32ue(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32ue(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32Upper.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32pd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32pd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32LowerPad.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32pe(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32pe(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32LowerPad.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32pud(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32pud(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32UpperPad.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32pue(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b32pue(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b32ce(Base32UpperPad.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b32el(length: int): int = Base32Lower.encodedLength(length)
|
||||
|
@ -199,24 +199,24 @@ proc b32dl(length: int): int = Base32Lower.decodedLength(length)
|
|||
proc b32pel(length: int): int = Base32LowerPad.encodedLength(length)
|
||||
proc b32pdl(length: int): int = Base32LowerPad.decodedLength(length)
|
||||
|
||||
proc b58fd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b58fd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b58ce(FLCBase58.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b58fe(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b58fe(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b58ce(FLCBase58.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b58bd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b58bd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b58ce(BTCBase58.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b58be(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b58be(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b58ce(BTCBase58.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b58el(length: int): int = Base58.encodedLength(length)
|
||||
|
@ -227,48 +227,48 @@ proc b64dl(length: int): int = Base64.decodedLength(length)
|
|||
proc b64pel(length: int): int = Base64Pad.encodedLength(length)
|
||||
proc b64pdl(length: int): int = Base64Pad.decodedLength(length)
|
||||
|
||||
proc b64e(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64e(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64d(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64d(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64pe(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64pe(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64Pad.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64pd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64pd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64Pad.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64ue(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64ue(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64Url.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64ud(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64ud(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64Url.decode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64upe(inbytes: openarray[byte],
|
||||
outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64upe(inbytes: openArray[byte],
|
||||
outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64UrlPad.encode(inbytes, outbytes, outlen))
|
||||
|
||||
proc b64upd(inbytes: openarray[char],
|
||||
outbytes: var openarray[byte],
|
||||
outlen: var int): MultibaseStatus =
|
||||
proc b64upd(inbytes: openArray[char],
|
||||
outbytes: var openArray[byte],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
result = b64ce(Base64UrlPad.decode(inbytes, outbytes, outlen))
|
||||
|
||||
const
|
||||
MultibaseCodecs = [
|
||||
MultiBaseCodecs = [
|
||||
MBCodec(name: "identity", code: chr(0x00),
|
||||
decr: idd, encr: ide, decl: iddl, encl: idel
|
||||
),
|
||||
|
@ -328,16 +328,16 @@ const
|
|||
]
|
||||
|
||||
proc initMultiBaseCodeTable(): Table[char, MBCodec] {.compileTime.} =
|
||||
for item in MultibaseCodecs:
|
||||
for item in MultiBaseCodecs:
|
||||
result[item.code] = item
|
||||
|
||||
proc initMultiBaseNameTable(): Table[string, MBCodec] {.compileTime.} =
|
||||
for item in MultibaseCodecs:
|
||||
for item in MultiBaseCodecs:
|
||||
result[item.name] = item
|
||||
|
||||
const
|
||||
CodeMultibases = initMultiBaseCodeTable()
|
||||
NameMultibases = initMultiBaseNameTable()
|
||||
CodeMultiBases = initMultiBaseCodeTable()
|
||||
NameMultiBases = initMultiBaseNameTable()
|
||||
|
||||
proc encodedLength*(mbtype: typedesc[MultiBase], encoding: string,
|
||||
length: int): int =
|
||||
|
@ -346,7 +346,7 @@ proc encodedLength*(mbtype: typedesc[MultiBase], encoding: string,
|
|||
##
|
||||
## Procedure returns ``-1`` if ``encoding`` scheme is not supported or
|
||||
## not present.
|
||||
let mb = NameMultibases.getOrDefault(encoding)
|
||||
let mb = NameMultiBases.getOrDefault(encoding)
|
||||
if len(mb.name) == 0 or isNil(mb.encl):
|
||||
result = -1
|
||||
else:
|
||||
|
@ -359,7 +359,7 @@ proc decodedLength*(mbtype: typedesc[MultiBase], encoding: char,
|
|||
length: int): int =
|
||||
## Return estimated size of buffer to store MultiBase decoded value with
|
||||
## encoding character ``encoding`` of length ``length``.
|
||||
let mb = CodeMultibases.getOrDefault(encoding)
|
||||
let mb = CodeMultiBases.getOrDefault(encoding)
|
||||
if len(mb.name) == 0 or isNil(mb.decl) or length == 0:
|
||||
result = -1
|
||||
else:
|
||||
|
@ -369,8 +369,8 @@ proc decodedLength*(mbtype: typedesc[MultiBase], encoding: char,
|
|||
result = mb.decl(length - 1)
|
||||
|
||||
proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
||||
inbytes: openarray[byte], outbytes: var openarray[char],
|
||||
outlen: var int): MultibaseStatus =
|
||||
inbytes: openArray[byte], outbytes: var openArray[char],
|
||||
outlen: var int): MultiBaseStatus =
|
||||
## Encode array ``inbytes`` using MultiBase encoding scheme ``encoding`` and
|
||||
## store encoded value to ``outbytes``.
|
||||
##
|
||||
|
@ -386,11 +386,11 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
|||
##
|
||||
## On successfull encoding ``MultiBaseStatus.Success`` will be returned and
|
||||
## ``outlen`` will be set to number of encoded octets (bytes).
|
||||
let mb = NameMultibases.getOrDefault(encoding)
|
||||
let mb = NameMultiBases.getOrDefault(encoding)
|
||||
if len(mb.name) == 0:
|
||||
return MultibaseStatus.BadCodec
|
||||
return MultiBaseStatus.BadCodec
|
||||
if isNil(mb.encr) or isNil(mb.encl):
|
||||
return MultibaseStatus.NotSupported
|
||||
return MultiBaseStatus.NotSupported
|
||||
if len(outbytes) > 1:
|
||||
result = mb.encr(inbytes, outbytes.toOpenArray(1, outbytes.high),
|
||||
outlen)
|
||||
|
@ -408,8 +408,8 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
|||
result = MultiBaseStatus.Overrun
|
||||
outlen = mb.encl(len(inbytes)) + 1
|
||||
|
||||
proc decode*(mbtype: typedesc[MultiBase], inbytes: openarray[char],
|
||||
outbytes: var openarray[byte], outlen: var int): MultibaseStatus =
|
||||
proc decode*(mbtype: typedesc[MultiBase], inbytes: openArray[char],
|
||||
outbytes: var openArray[byte], outlen: var int): MultiBaseStatus =
|
||||
## Decode array ``inbytes`` using MultiBase encoding and store decoded value
|
||||
## to ``outbytes``.
|
||||
##
|
||||
|
@ -426,24 +426,24 @@ proc decode*(mbtype: typedesc[MultiBase], inbytes: openarray[char],
|
|||
## ``outlen`` will be set to number of encoded octets (bytes).
|
||||
let length = len(inbytes)
|
||||
if length == 0:
|
||||
return MultibaseStatus.Incorrect
|
||||
let mb = CodeMultibases.getOrDefault(inbytes[0])
|
||||
return MultiBaseStatus.Incorrect
|
||||
let mb = CodeMultiBases.getOrDefault(inbytes[0])
|
||||
if len(mb.name) == 0:
|
||||
return MultibaseStatus.BadCodec
|
||||
return MultiBaseStatus.BadCodec
|
||||
if isNil(mb.decr) or isNil(mb.decl):
|
||||
return MultibaseStatus.NotSupported
|
||||
return MultiBaseStatus.NotSupported
|
||||
if length == 1:
|
||||
outlen = 0
|
||||
result = MultibaseStatus.Success
|
||||
result = MultiBaseStatus.Success
|
||||
else:
|
||||
result = mb.decr(inbytes.toOpenArray(1, length - 1), outbytes, outlen)
|
||||
|
||||
proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
||||
inbytes: openarray[byte]): Result[string, string] =
|
||||
inbytes: openArray[byte]): Result[string, string] =
|
||||
## Encode array ``inbytes`` using MultiBase encoding scheme ``encoding`` and
|
||||
## return encoded string.
|
||||
let length = len(inbytes)
|
||||
let mb = NameMultibases.getOrDefault(encoding)
|
||||
let mb = NameMultiBases.getOrDefault(encoding)
|
||||
if len(mb.name) == 0:
|
||||
return err("multibase: Encoding scheme is incorrect!")
|
||||
if isNil(mb.encr) or isNil(mb.encl):
|
||||
|
@ -462,13 +462,13 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
|||
buffer[0] = mb.code
|
||||
ok(buffer)
|
||||
|
||||
proc decode*(mbtype: typedesc[MultiBase], inbytes: openarray[char]): Result[seq[byte], string] =
|
||||
proc decode*(mbtype: typedesc[MultiBase], inbytes: openArray[char]): Result[seq[byte], string] =
|
||||
## Decode MultiBase encoded array ``inbytes`` and return decoded sequence of
|
||||
## bytes.
|
||||
let length = len(inbytes)
|
||||
if length == 0:
|
||||
return err("multibase: Could not decode zero-length string")
|
||||
let mb = CodeMultibases.getOrDefault(inbytes[0])
|
||||
let mb = CodeMultiBases.getOrDefault(inbytes[0])
|
||||
if len(mb.name) == 0:
|
||||
return err("multibase: MultiBase scheme is incorrect!")
|
||||
if isNil(mb.decr) or isNil(mb.decl):
|
||||
|
|
|
@ -201,6 +201,7 @@ const MultiCodecList = [
|
|||
("p2p-webrtc-direct", 0x0114), # not in multicodec list
|
||||
("onion", 0x01BC),
|
||||
("p2p-circuit", 0x0122),
|
||||
("libp2p-peer-record", 0x0301),
|
||||
("dns", 0x35),
|
||||
("dns4", 0x36),
|
||||
("dns6", 0x37),
|
||||
|
|
|
@ -41,8 +41,8 @@ const
|
|||
ErrParseError = "Parse error fromHex"
|
||||
|
||||
type
|
||||
MHashCoderProc* = proc(data: openarray[byte],
|
||||
output: var openarray[byte]) {.nimcall, gcsafe, noSideEffect, raises: [Defect].}
|
||||
MHashCoderProc* = proc(data: openArray[byte],
|
||||
output: var openArray[byte]) {.nimcall, gcsafe, noSideEffect, raises: [Defect].}
|
||||
MHash* = object
|
||||
mcodec*: MultiCodec
|
||||
size*: int
|
||||
|
@ -56,20 +56,20 @@ type
|
|||
|
||||
MhResult*[T] = Result[T, cstring]
|
||||
|
||||
proc identhash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc identhash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var length = if len(data) > len(output): len(output)
|
||||
else: len(data)
|
||||
copyMem(addr output[0], unsafeAddr data[0], length)
|
||||
|
||||
proc sha1hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha1hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha1.digest(data)
|
||||
var length = if sha1.sizeDigest > len(output): len(output)
|
||||
else: sha1.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc dblsha2_256hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc dblsha2_256hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest1 = sha256.digest(data)
|
||||
var digest2 = sha256.digest(digest1.data)
|
||||
|
@ -77,91 +77,91 @@ proc dblsha2_256hash(data: openarray[byte], output: var openarray[byte]) =
|
|||
else: sha256.sizeDigest
|
||||
copyMem(addr output[0], addr digest2.data[0], length)
|
||||
|
||||
proc blake2Bhash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc blake2Bhash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = blake2_512.digest(data)
|
||||
var length = if blake2_512.sizeDigest > len(output): len(output)
|
||||
else: blake2_512.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc blake2Shash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc blake2Shash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = blake2_256.digest(data)
|
||||
var length = if blake2_256.sizeDigest > len(output): len(output)
|
||||
else: blake2_256.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc sha2_256hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha2_256hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha256.digest(data)
|
||||
var length = if sha256.sizeDigest > len(output): len(output)
|
||||
else: sha256.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc sha2_512hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha2_512hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha512.digest(data)
|
||||
var length = if sha512.sizeDigest > len(output): len(output)
|
||||
else: sha512.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc sha3_224hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha3_224hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha3_224.digest(data)
|
||||
var length = if sha3_224.sizeDigest > len(output): len(output)
|
||||
else: sha3_224.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc sha3_256hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha3_256hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha3_256.digest(data)
|
||||
var length = if sha3_256.sizeDigest > len(output): len(output)
|
||||
else: sha3_256.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc sha3_384hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha3_384hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha3_384.digest(data)
|
||||
var length = if sha3_384.sizeDigest > len(output): len(output)
|
||||
else: sha3_384.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc sha3_512hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc sha3_512hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = sha3_512.digest(data)
|
||||
var length = if sha3_512.sizeDigest > len(output): len(output)
|
||||
else: sha3_512.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc keccak_224hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc keccak_224hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = keccak224.digest(data)
|
||||
var length = if keccak224.sizeDigest > len(output): len(output)
|
||||
else: keccak224.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc keccak_256hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc keccak_256hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = keccak256.digest(data)
|
||||
var length = if keccak256.sizeDigest > len(output): len(output)
|
||||
else: keccak256.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc keccak_384hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc keccak_384hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = keccak384.digest(data)
|
||||
var length = if keccak384.sizeDigest > len(output): len(output)
|
||||
else: keccak384.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc keccak_512hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc keccak_512hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
if len(output) > 0:
|
||||
var digest = keccak512.digest(data)
|
||||
var length = if keccak512.sizeDigest > len(output): len(output)
|
||||
else: keccak512.sizeDigest
|
||||
copyMem(addr output[0], addr digest.data[0], length)
|
||||
|
||||
proc shake_128hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc shake_128hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
var sctx: shake128
|
||||
if len(output) > 0:
|
||||
sctx.init()
|
||||
|
@ -170,7 +170,7 @@ proc shake_128hash(data: openarray[byte], output: var openarray[byte]) =
|
|||
discard sctx.output(addr output[0], uint(len(output)))
|
||||
sctx.clear()
|
||||
|
||||
proc shake_256hash(data: openarray[byte], output: var openarray[byte]) =
|
||||
proc shake_256hash(data: openArray[byte], output: var openArray[byte]) =
|
||||
var sctx: shake256
|
||||
if len(output) > 0:
|
||||
sctx.init()
|
||||
|
@ -208,16 +208,16 @@ const
|
|||
),
|
||||
MHash(mcodec: multiCodec("shake-128"), size: 32, coder: shake_128hash),
|
||||
MHash(mcodec: multiCodec("shake-256"), size: 64, coder: shake_256hash),
|
||||
MHash(mcodec: multiCodec("keccak-224"), size: keccak_224.sizeDigest,
|
||||
MHash(mcodec: multiCodec("keccak-224"), size: keccak224.sizeDigest,
|
||||
coder: keccak_224hash
|
||||
),
|
||||
MHash(mcodec: multiCodec("keccak-256"), size: keccak_256.sizeDigest,
|
||||
MHash(mcodec: multiCodec("keccak-256"), size: keccak256.sizeDigest,
|
||||
coder: keccak_256hash
|
||||
),
|
||||
MHash(mcodec: multiCodec("keccak-384"), size: keccak_384.sizeDigest,
|
||||
MHash(mcodec: multiCodec("keccak-384"), size: keccak384.sizeDigest,
|
||||
coder: keccak_384hash
|
||||
),
|
||||
MHash(mcodec: multiCodec("keccak-512"), size: keccak_512.sizeDigest,
|
||||
MHash(mcodec: multiCodec("keccak-512"), size: keccak512.sizeDigest,
|
||||
coder: keccak_512hash
|
||||
),
|
||||
MHash(mcodec: multiCodec("blake2b-8"), size: 1, coder: blake2Bhash),
|
||||
|
@ -325,7 +325,7 @@ proc initMultiHashCodeTable(): Table[MultiCodec, MHash] {.compileTime.} =
|
|||
const
|
||||
CodeHashes = initMultiHashCodeTable()
|
||||
|
||||
proc digestImplWithHash(hash: MHash, data: openarray[byte]): MultiHash =
|
||||
proc digestImplWithHash(hash: MHash, data: openArray[byte]): MultiHash =
|
||||
var buffer: array[MaxHashSize, byte]
|
||||
result.data = initVBuffer()
|
||||
result.mcodec = hash.mcodec
|
||||
|
@ -343,7 +343,7 @@ proc digestImplWithHash(hash: MHash, data: openarray[byte]): MultiHash =
|
|||
result.size = hash.size
|
||||
result.data.finish()
|
||||
|
||||
proc digestImplWithoutHash(hash: MHash, data: openarray[byte]): MultiHash =
|
||||
proc digestImplWithoutHash(hash: MHash, data: openArray[byte]): MultiHash =
|
||||
result.data = initVBuffer()
|
||||
result.mcodec = hash.mcodec
|
||||
result.size = len(data)
|
||||
|
@ -354,7 +354,7 @@ proc digestImplWithoutHash(hash: MHash, data: openarray[byte]): MultiHash =
|
|||
result.data.finish()
|
||||
|
||||
proc digest*(mhtype: typedesc[MultiHash], hashname: string,
|
||||
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
data: openArray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
## Perform digest calculation using hash algorithm with name ``hashname`` on
|
||||
## data array ``data``.
|
||||
let mc = MultiCodec.codec(hashname)
|
||||
|
@ -368,7 +368,7 @@ proc digest*(mhtype: typedesc[MultiHash], hashname: string,
|
|||
ok(digestImplWithHash(hash, data))
|
||||
|
||||
proc digest*(mhtype: typedesc[MultiHash], hashcode: int,
|
||||
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
data: openArray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
## Perform digest calculation using hash algorithm with code ``hashcode`` on
|
||||
## data array ``data``.
|
||||
let hash = CodeHashes.getOrDefault(hashcode)
|
||||
|
@ -406,7 +406,7 @@ proc init*[T](mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
|||
ok(digestImplWithoutHash(hash, mdigest.data))
|
||||
|
||||
proc init*(mhtype: typedesc[MultiHash], hashname: string,
|
||||
bdigest: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
bdigest: openArray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code
|
||||
## ``hashcode``.
|
||||
let mc = MultiCodec.codec(hashname)
|
||||
|
@ -422,7 +422,7 @@ proc init*(mhtype: typedesc[MultiHash], hashname: string,
|
|||
ok(digestImplWithoutHash(hash, bdigest))
|
||||
|
||||
proc init*(mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
||||
bdigest: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
bdigest: openArray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code
|
||||
## ``hashcode``.
|
||||
let hash = CodeHashes.getOrDefault(hashcode)
|
||||
|
@ -433,7 +433,7 @@ proc init*(mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
|||
else:
|
||||
ok(digestImplWithoutHash(hash, bdigest))
|
||||
|
||||
proc decode*(mhtype: typedesc[MultiHash], data: openarray[byte],
|
||||
proc decode*(mhtype: typedesc[MultiHash], data: openArray[byte],
|
||||
mhash: var MultiHash): MhResult[int] =
|
||||
## Decode MultiHash value from array of bytes ``data``.
|
||||
##
|
||||
|
@ -478,7 +478,7 @@ proc decode*(mhtype: typedesc[MultiHash], data: openarray[byte],
|
|||
vb.offset + int(size) - 1))
|
||||
ok(vb.offset + int(size))
|
||||
|
||||
proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
|
||||
proc validate*(mhtype: typedesc[MultiHash], data: openArray[byte]): bool =
|
||||
## Returns ``true`` if array of bytes ``data`` has correct MultiHash inside.
|
||||
var code, size: uint64
|
||||
var res: VarintResult[void]
|
||||
|
@ -509,7 +509,7 @@ proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
|
|||
result = true
|
||||
|
||||
proc init*(mhtype: typedesc[MultiHash],
|
||||
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
data: openArray[byte]): MhResult[MultiHash] {.inline.} =
|
||||
## Create MultiHash from bytes array ``data``.
|
||||
var hash: MultiHash
|
||||
discard ? MultiHash.decode(data, hash)
|
||||
|
@ -530,7 +530,7 @@ proc init58*(mhtype: typedesc[MultiHash],
|
|||
if MultiHash.decode(Base58.decode(data), result) == -1:
|
||||
raise newException(MultihashError, "Incorrect MultiHash binary format")
|
||||
|
||||
proc cmp(a: openarray[byte], b: openarray[byte]): bool {.inline.} =
|
||||
proc cmp(a: openArray[byte], b: openArray[byte]): bool {.inline.} =
|
||||
if len(a) != len(b):
|
||||
return false
|
||||
var n = len(a)
|
||||
|
|
|
@ -175,9 +175,9 @@ method readOnce*(s: LPChannel,
|
|||
await s.reset()
|
||||
raise exc
|
||||
|
||||
method write*(s: LPChannel, msg: seq[byte]): Future[void] {.async.} =
|
||||
## Write to mplex channel - there may be up to MaxWrite concurrent writes
|
||||
## pending after which the peer is disconnected
|
||||
proc prepareWrite(s: LPChannel, msg: seq[byte]): Future[void] {.async.} =
|
||||
# prepareWrite is the slow path of writing a message - see conditions in
|
||||
# write
|
||||
if s.closedLocal or s.conn.closed:
|
||||
raise newLPStreamClosedError()
|
||||
|
||||
|
@ -191,19 +191,20 @@ method write*(s: LPChannel, msg: seq[byte]): Future[void] {.async.} =
|
|||
await s.conn.close()
|
||||
return
|
||||
|
||||
s.writes += 1
|
||||
if not s.isOpen:
|
||||
await s.open()
|
||||
|
||||
await s.conn.writeMsg(s.id, s.msgCode, msg)
|
||||
|
||||
proc completeWrite(
|
||||
s: LPChannel, fut: Future[void], msgLen: int): Future[void] {.async.} =
|
||||
try:
|
||||
if not s.isOpen:
|
||||
await s.open()
|
||||
|
||||
# writes should happen in sequence
|
||||
trace "write msg", s, conn = s.conn, len = msg.len
|
||||
|
||||
await s.conn.writeMsg(s.id, s.msgCode, msg)
|
||||
s.writes += 1
|
||||
|
||||
await fut
|
||||
when defined(libp2p_network_protocols_metrics):
|
||||
if s.tag.len > 0:
|
||||
libp2p_protocols_bytes.inc(msg.len.int64, labelValues=[s.tag, "out"])
|
||||
libp2p_protocols_bytes.inc(msgLen.int64, labelValues=[s.tag, "out"])
|
||||
|
||||
s.activity = true
|
||||
except CatchableError as exc:
|
||||
|
@ -214,6 +215,24 @@ method write*(s: LPChannel, msg: seq[byte]): Future[void] {.async.} =
|
|||
finally:
|
||||
s.writes -= 1
|
||||
|
||||
method write*(s: LPChannel, msg: seq[byte]): Future[void] =
|
||||
## Write to mplex channel - there may be up to MaxWrite concurrent writes
|
||||
## pending after which the peer is disconnected
|
||||
|
||||
let
|
||||
closed = s.closedLocal or s.conn.closed
|
||||
|
||||
let fut =
|
||||
if (not closed) and msg.len > 0 and s.writes < MaxWrites and s.isOpen:
|
||||
# Fast path: Avoid a copy of msg being kept in the closure created by
|
||||
# `{.async.}` as this drives up memory usage - the conditions are laid out
|
||||
# in prepareWrite
|
||||
s.conn.writeMsg(s.id, s.msgCode, msg)
|
||||
else:
|
||||
prepareWrite(s, msg)
|
||||
|
||||
s.completeWrite(fut, msg.len)
|
||||
|
||||
proc init*(
|
||||
L: type LPChannel,
|
||||
id: uint64,
|
||||
|
|
|
@ -46,7 +46,7 @@ type
|
|||
oid*: Oid
|
||||
maxChannCount: int
|
||||
|
||||
func shortLog*(m: MPlex): auto =
|
||||
func shortLog*(m: Mplex): auto =
|
||||
shortLog(m.connection)
|
||||
|
||||
chronicles.formatIt(Mplex): shortLog(it)
|
||||
|
|
|
@ -88,9 +88,9 @@ method resolveIp*(
|
|||
port: Port,
|
||||
domain: Domain = Domain.AF_UNSPEC): Future[seq[TransportAddress]] {.async.} =
|
||||
|
||||
trace "Resolving IP using DNS", address, servers = self.nameservers.mapIt($it), domain
|
||||
for _ in 0 ..< self.nameservers.len:
|
||||
let server = self.nameservers[0]
|
||||
trace "Resolving IP using DNS", address, servers = self.nameServers.mapIt($it), domain
|
||||
for _ in 0 ..< self.nameServers.len:
|
||||
let server = self.nameServers[0]
|
||||
var responseFutures: seq[Future[Response]]
|
||||
if domain == Domain.AF_INET or domain == Domain.AF_UNSPEC:
|
||||
responseFutures.add(getDnsResponse(server, address, A))
|
||||
|
@ -122,8 +122,8 @@ method resolveIp*(
|
|||
break
|
||||
|
||||
if resolveFailed:
|
||||
self.nameservers.add(self.nameservers[0])
|
||||
self.nameservers.delete(0)
|
||||
self.nameServers.add(self.nameServers[0])
|
||||
self.nameServers.delete(0)
|
||||
continue
|
||||
|
||||
trace "Got IPs from DNS server", resolvedAddresses, server = $server
|
||||
|
@ -136,9 +136,9 @@ method resolveTxt*(
|
|||
self: DnsResolver,
|
||||
address: string): Future[seq[string]] {.async.} =
|
||||
|
||||
trace "Resolving TXT using DNS", address, servers = self.nameservers.mapIt($it)
|
||||
for _ in 0 ..< self.nameservers.len:
|
||||
let server = self.nameservers[0]
|
||||
trace "Resolving TXT using DNS", address, servers = self.nameServers.mapIt($it)
|
||||
for _ in 0 ..< self.nameServers.len:
|
||||
let server = self.nameServers[0]
|
||||
try:
|
||||
let response = await getDnsResponse(server, address, TXT)
|
||||
trace "Got TXT response", server = $server, answer=response.answers.mapIt(it.toString())
|
||||
|
@ -147,8 +147,8 @@ method resolveTxt*(
|
|||
raise e
|
||||
except CatchableError as e:
|
||||
info "Failed to query DNS", address, error=e.msg
|
||||
self.nameservers.add(self.nameservers[0])
|
||||
self.nameservers.delete(0)
|
||||
self.nameServers.add(self.nameServers[0])
|
||||
self.nameServers.delete(0)
|
||||
continue
|
||||
|
||||
debug "Failed to resolve TXT, returning empty set"
|
||||
|
|
|
@ -25,10 +25,10 @@ const
|
|||
maxInlineKeyLength* = 42
|
||||
|
||||
type
|
||||
PeerID* = object
|
||||
PeerId* = object
|
||||
data*: seq[byte]
|
||||
|
||||
func `$`*(pid: PeerID): string =
|
||||
func `$`*(pid: PeerId): string =
|
||||
## Return base58 encoded ``pid`` representation.
|
||||
# This unusual call syntax is used to avoid a strange Nim compilation error
|
||||
base58.encode(Base58, pid.data)
|
||||
|
@ -42,29 +42,29 @@ func shortLog*(pid: PeerId): string =
|
|||
|
||||
spid
|
||||
|
||||
chronicles.formatIt(PeerID): shortLog(it)
|
||||
chronicles.formatIt(PeerId): shortLog(it)
|
||||
|
||||
func toBytes*(pid: PeerID, data: var openarray[byte]): int =
|
||||
## Store PeerID ``pid`` to array of bytes ``data``.
|
||||
func toBytes*(pid: PeerId, data: var openArray[byte]): int =
|
||||
## Store PeerId ``pid`` to array of bytes ``data``.
|
||||
##
|
||||
## Returns number of bytes needed to store ``pid``.
|
||||
result = len(pid.data)
|
||||
if len(data) >= result and result > 0:
|
||||
copyMem(addr data[0], unsafeAddr pid.data[0], result)
|
||||
|
||||
template getBytes*(pid: PeerID): seq[byte] =
|
||||
## Return PeerID ``pid`` as array of bytes.
|
||||
template getBytes*(pid: PeerId): seq[byte] =
|
||||
## Return PeerId ``pid`` as array of bytes.
|
||||
pid.data
|
||||
|
||||
func hex*(pid: PeerID): string =
|
||||
func hex*(pid: PeerId): string =
|
||||
## Returns hexadecimal string representation of ``pid``.
|
||||
toHex(pid.data)
|
||||
|
||||
template len*(pid: PeerID): int =
|
||||
template len*(pid: PeerId): int =
|
||||
## Returns length of ``pid`` binary representation.
|
||||
len(pid.data)
|
||||
|
||||
func cmp*(a, b: PeerID): int =
|
||||
func cmp*(a, b: PeerId): int =
|
||||
## Compares two peer ids ``a`` and ``b``.
|
||||
## Returns:
|
||||
##
|
||||
|
@ -79,29 +79,29 @@ func cmp*(a, b: PeerID): int =
|
|||
inc(i)
|
||||
result = len(a.data) - len(b.data)
|
||||
|
||||
template `<=`*(a, b: PeerID): bool =
|
||||
template `<=`*(a, b: PeerId): bool =
|
||||
(cmp(a, b) <= 0)
|
||||
|
||||
template `<`*(a, b: PeerID): bool =
|
||||
template `<`*(a, b: PeerId): bool =
|
||||
(cmp(a, b) < 0)
|
||||
|
||||
template `>=`*(a, b: PeerID): bool =
|
||||
template `>=`*(a, b: PeerId): bool =
|
||||
(cmp(a, b) >= 0)
|
||||
|
||||
template `>`*(a, b: PeerID): bool =
|
||||
template `>`*(a, b: PeerId): bool =
|
||||
(cmp(a, b) > 0)
|
||||
|
||||
template `==`*(a, b: PeerID): bool =
|
||||
template `==`*(a, b: PeerId): bool =
|
||||
(cmp(a, b) == 0)
|
||||
|
||||
template hash*(pid: PeerID): Hash =
|
||||
template hash*(pid: PeerId): Hash =
|
||||
hash(pid.data)
|
||||
|
||||
func validate*(pid: PeerID): bool =
|
||||
func validate*(pid: PeerId): bool =
|
||||
## Validate check if ``pid`` is empty or not.
|
||||
len(pid.data) > 0 and MultiHash.validate(pid.data)
|
||||
|
||||
func hasPublicKey*(pid: PeerID): bool =
|
||||
func hasPublicKey*(pid: PeerId): bool =
|
||||
## Returns ``true`` if ``pid`` is small enough to hold public key inside.
|
||||
if len(pid.data) > 0:
|
||||
var mh: MultiHash
|
||||
|
@ -109,8 +109,8 @@ func hasPublicKey*(pid: PeerID): bool =
|
|||
if mh.mcodec == multiCodec("identity"):
|
||||
result = true
|
||||
|
||||
func extractPublicKey*(pid: PeerID, pubkey: var PublicKey): bool =
|
||||
## Returns ``true`` if public key was successfully decoded from PeerID
|
||||
func extractPublicKey*(pid: PeerId, pubkey: var PublicKey): bool =
|
||||
## Returns ``true`` if public key was successfully decoded from PeerId
|
||||
## ``pid``and stored to ``pubkey``.
|
||||
##
|
||||
## Returns ``false`` otherwise.
|
||||
|
@ -121,16 +121,16 @@ func extractPublicKey*(pid: PeerID, pubkey: var PublicKey): bool =
|
|||
let length = len(mh.data.buffer)
|
||||
result = pubkey.init(mh.data.buffer.toOpenArray(mh.dpos, length - 1))
|
||||
|
||||
func init*(pid: var PeerID, data: openarray[byte]): bool =
|
||||
func init*(pid: var PeerId, data: openArray[byte]): bool =
|
||||
## Initialize peer id from raw binary representation ``data``.
|
||||
##
|
||||
## Returns ``true`` if peer was successfully initialiazed.
|
||||
var p = PeerID(data: @data)
|
||||
var p = PeerId(data: @data)
|
||||
if p.validate():
|
||||
pid = p
|
||||
result = true
|
||||
|
||||
func init*(pid: var PeerID, data: string): bool =
|
||||
func init*(pid: var PeerId, data: string): bool =
|
||||
## Initialize peer id from base58 encoded string representation.
|
||||
##
|
||||
## Returns ``true`` if peer was successfully initialiazed.
|
||||
|
@ -138,29 +138,29 @@ func init*(pid: var PeerID, data: string): bool =
|
|||
var length = 0
|
||||
if Base58.decode(data, p, length) == Base58Status.Success:
|
||||
p.setLen(length)
|
||||
var opid: PeerID
|
||||
var opid: PeerId
|
||||
shallowCopy(opid.data, p)
|
||||
if opid.validate():
|
||||
pid = opid
|
||||
result = true
|
||||
|
||||
func init*(t: typedesc[PeerID], data: openarray[byte]): Result[PeerID, cstring] =
|
||||
func init*(t: typedesc[PeerId], data: openArray[byte]): Result[PeerId, cstring] =
|
||||
## Create new peer id from raw binary representation ``data``.
|
||||
var res: PeerID
|
||||
var res: PeerId
|
||||
if not init(res, data):
|
||||
err("peerid: incorrect PeerID binary form")
|
||||
err("peerid: incorrect PeerId binary form")
|
||||
else:
|
||||
ok(res)
|
||||
|
||||
func init*(t: typedesc[PeerID], data: string): Result[PeerID, cstring] =
|
||||
func init*(t: typedesc[PeerId], data: string): Result[PeerId, cstring] =
|
||||
## Create new peer id from base58 encoded string representation ``data``.
|
||||
var res: PeerID
|
||||
var res: PeerId
|
||||
if not init(res, data):
|
||||
err("peerid: incorrect PeerID string")
|
||||
err("peerid: incorrect PeerId string")
|
||||
else:
|
||||
ok(res)
|
||||
|
||||
func init*(t: typedesc[PeerID], pubkey: PublicKey): Result[PeerID, cstring] =
|
||||
func init*(t: typedesc[PeerId], pubkey: PublicKey): Result[PeerId, cstring] =
|
||||
## Create new peer id from public key ``pubkey``.
|
||||
var pubraw = ? pubkey.getBytes().orError(
|
||||
cstring("peerid: failed to get bytes from given key"))
|
||||
|
@ -169,23 +169,23 @@ func init*(t: typedesc[PeerID], pubkey: PublicKey): Result[PeerID, cstring] =
|
|||
mh = ? MultiHash.digest("identity", pubraw)
|
||||
else:
|
||||
mh = ? MultiHash.digest("sha2-256", pubraw)
|
||||
ok(PeerID(data: mh.data.buffer))
|
||||
ok(PeerId(data: mh.data.buffer))
|
||||
|
||||
func init*(t: typedesc[PeerID], seckey: PrivateKey): Result[PeerID, cstring] =
|
||||
func init*(t: typedesc[PeerId], seckey: PrivateKey): Result[PeerId, cstring] =
|
||||
## Create new peer id from private key ``seckey``.
|
||||
PeerID.init(? seckey.getPublicKey().orError(cstring("invalid private key")))
|
||||
PeerId.init(? seckey.getPublicKey().orError(cstring("invalid private key")))
|
||||
|
||||
func match*(pid: PeerID, pubkey: PublicKey): bool =
|
||||
func match*(pid: PeerId, pubkey: PublicKey): bool =
|
||||
## Returns ``true`` if ``pid`` matches public key ``pubkey``.
|
||||
let p = PeerID.init(pubkey)
|
||||
let p = PeerId.init(pubkey)
|
||||
if p.isErr:
|
||||
false
|
||||
else:
|
||||
pid == p.get()
|
||||
|
||||
func match*(pid: PeerID, seckey: PrivateKey): bool =
|
||||
func match*(pid: PeerId, seckey: PrivateKey): bool =
|
||||
## Returns ``true`` if ``pid`` matches private key ``seckey``.
|
||||
let p = PeerID.init(seckey)
|
||||
let p = PeerId.init(seckey)
|
||||
if p.isErr:
|
||||
false
|
||||
else:
|
||||
|
@ -193,23 +193,23 @@ func match*(pid: PeerID, seckey: PrivateKey): bool =
|
|||
|
||||
## Serialization/Deserialization helpers
|
||||
|
||||
func write*(vb: var VBuffer, pid: PeerID) =
|
||||
## Write PeerID value ``peerid`` to buffer ``vb``.
|
||||
func write*(vb: var VBuffer, pid: PeerId) =
|
||||
## Write PeerId value ``peerid`` to buffer ``vb``.
|
||||
vb.writeSeq(pid.data)
|
||||
|
||||
func write*(pb: var ProtoBuffer, field: int, pid: PeerID) =
|
||||
## Write PeerID value ``peerid`` to object ``pb`` using ProtoBuf's encoding.
|
||||
func write*(pb: var ProtoBuffer, field: int, pid: PeerId) =
|
||||
## Write PeerId value ``peerid`` to object ``pb`` using ProtoBuf's encoding.
|
||||
write(pb, field, pid.data)
|
||||
|
||||
func getField*(pb: ProtoBuffer, field: int,
|
||||
pid: var PeerID): ProtoResult[bool] {.inline.} =
|
||||
## Read ``PeerID`` from ProtoBuf's message and validate it
|
||||
pid: var PeerId): ProtoResult[bool] {.inline.} =
|
||||
## Read ``PeerId`` from ProtoBuf's message and validate it
|
||||
var buffer: seq[byte]
|
||||
let res = ? pb.getField(field, buffer)
|
||||
if not(res):
|
||||
ok(false)
|
||||
else:
|
||||
var peerId: PeerID
|
||||
var peerId: PeerId
|
||||
if peerId.init(buffer):
|
||||
pid = peerId
|
||||
ok(true)
|
||||
|
|
|
@ -21,7 +21,7 @@ type
|
|||
PeerInfoError* = LPError
|
||||
|
||||
PeerInfo* = ref object
|
||||
peerId*: PeerID
|
||||
peerId*: PeerId
|
||||
addrs*: seq[MultiAddress]
|
||||
protocols*: seq[string]
|
||||
protoVersion*: string
|
||||
|
@ -42,8 +42,8 @@ chronicles.formatIt(PeerInfo): shortLog(it)
|
|||
proc new*(
|
||||
p: typedesc[PeerInfo],
|
||||
key: PrivateKey,
|
||||
addrs: openarray[MultiAddress] = [],
|
||||
protocols: openarray[string] = [],
|
||||
addrs: openArray[MultiAddress] = [],
|
||||
protocols: openArray[string] = [],
|
||||
protoVersion: string = "",
|
||||
agentVersion: string = ""): PeerInfo
|
||||
{.raises: [Defect, PeerInfoError].} =
|
||||
|
@ -54,7 +54,7 @@ proc new*(
|
|||
raise newException(PeerInfoError, "invalid private key")
|
||||
|
||||
let peerInfo = PeerInfo(
|
||||
peerId: PeerID.init(key).tryGet(),
|
||||
peerId: PeerId.init(key).tryGet(),
|
||||
publicKey: pubkey,
|
||||
privateKey: key,
|
||||
protoVersion: protoVersion,
|
||||
|
|
|
@ -21,7 +21,7 @@ type
|
|||
# Handler types #
|
||||
#################
|
||||
|
||||
PeerBookChangeHandler*[T] = proc(peerId: PeerID, entry: T)
|
||||
PeerBookChangeHandler*[T] = proc(peerId: PeerId, entry: T)
|
||||
|
||||
AddrChangeHandler* = PeerBookChangeHandler[HashSet[MultiAddress]]
|
||||
ProtoChangeHandler* = PeerBookChangeHandler[HashSet[string]]
|
||||
|
@ -33,7 +33,7 @@ type
|
|||
|
||||
# Each book contains a book (map) and event handler(s)
|
||||
PeerBook*[T] = object of RootObj
|
||||
book*: Table[PeerID, T]
|
||||
book*: Table[PeerId, T]
|
||||
changeHandlers: seq[PeerBookChangeHandler[T]]
|
||||
|
||||
SetPeerBook*[T] = object of PeerBook[HashSet[T]]
|
||||
|
@ -65,13 +65,13 @@ proc new*(T: type PeerStore): PeerStore =
|
|||
#########################
|
||||
|
||||
proc get*[T](peerBook: PeerBook[T],
|
||||
peerId: PeerID): T =
|
||||
peerId: PeerId): T =
|
||||
## Get all the known metadata of a provided peer.
|
||||
|
||||
peerBook.book.getOrDefault(peerId)
|
||||
|
||||
proc set*[T](peerBook: var PeerBook[T],
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
entry: T) =
|
||||
## Set metadata for a given peerId. This will replace any
|
||||
## previously stored metadata.
|
||||
|
@ -83,7 +83,7 @@ proc set*[T](peerBook: var PeerBook[T],
|
|||
handler(peerId, peerBook.get(peerId))
|
||||
|
||||
proc delete*[T](peerBook: var PeerBook[T],
|
||||
peerId: PeerID): bool =
|
||||
peerId: PeerId): bool =
|
||||
## Delete the provided peer from the book.
|
||||
|
||||
if not peerBook.book.hasKey(peerId):
|
||||
|
@ -92,7 +92,7 @@ proc delete*[T](peerBook: var PeerBook[T],
|
|||
peerBook.book.del(peerId)
|
||||
return true
|
||||
|
||||
proc contains*[T](peerBook: PeerBook[T], peerId: PeerID): bool =
|
||||
proc contains*[T](peerBook: PeerBook[T], peerId: PeerId): bool =
|
||||
peerId in peerBook.book
|
||||
|
||||
################
|
||||
|
@ -101,7 +101,7 @@ proc contains*[T](peerBook: PeerBook[T], peerId: PeerID): bool =
|
|||
|
||||
proc add*[T](
|
||||
peerBook: var SetPeerBook[T],
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
entry: T) =
|
||||
## Add entry to a given peer. If the peer is not known,
|
||||
## it will be set with the provided entry.
|
||||
|
@ -116,7 +116,7 @@ proc add*[T](
|
|||
# Helper for seq
|
||||
proc set*[T](
|
||||
peerBook: var SetPeerBook[T],
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
entry: seq[T]) =
|
||||
## Add entry to a given peer. If the peer is not known,
|
||||
## it will be set with the provided entry.
|
||||
|
@ -138,7 +138,7 @@ proc addHandlers*(peerStore: PeerStore,
|
|||
peerStore.keyBook.changeHandlers.add(keyChangeHandler)
|
||||
|
||||
proc delete*(peerStore: PeerStore,
|
||||
peerId: PeerID): bool =
|
||||
peerId: PeerId): bool =
|
||||
## Delete the provided peer from every book.
|
||||
|
||||
peerStore.addressBook.delete(peerId) and
|
||||
|
|
|
@ -123,7 +123,7 @@ proc initProtoBuffer*(data: seq[byte], offset = 0,
|
|||
result.offset = offset
|
||||
result.options = options
|
||||
|
||||
proc initProtoBuffer*(data: openarray[byte], offset = 0,
|
||||
proc initProtoBuffer*(data: openArray[byte], offset = 0,
|
||||
options: set[ProtoFlags] = {}): ProtoBuffer =
|
||||
## Initialize ProtoBuffer with copy of ``data``.
|
||||
result.buffer = @data
|
||||
|
@ -191,7 +191,7 @@ proc write*[T: ProtoScalar](pb: var ProtoBuffer,
|
|||
pb.offset += sizeof(T)
|
||||
|
||||
proc writePacked*[T: ProtoScalar](pb: var ProtoBuffer, field: int,
|
||||
value: openarray[T]) =
|
||||
value: openArray[T]) =
|
||||
checkFieldNumber(field)
|
||||
var length = 0
|
||||
let dlength =
|
||||
|
@ -239,7 +239,7 @@ proc writePacked*[T: ProtoScalar](pb: var ProtoBuffer, field: int,
|
|||
pb.offset += sizeof(T)
|
||||
|
||||
proc write*[T: byte|char](pb: var ProtoBuffer, field: int,
|
||||
value: openarray[T]) =
|
||||
value: openArray[T]) =
|
||||
checkFieldNumber(field)
|
||||
var length = 0
|
||||
let flength = vsizeof(getProtoHeader(field, ProtoFieldKind.Length)) +
|
||||
|
@ -265,8 +265,8 @@ proc write*(pb: var ProtoBuffer, field: int, value: ProtoBuffer) {.inline.} =
|
|||
|
||||
proc finish*(pb: var ProtoBuffer) =
|
||||
## Prepare protobuf's buffer ``pb`` for writing to stream.
|
||||
doAssert(len(pb.buffer) > 0)
|
||||
if WithVarintLength in pb.options:
|
||||
doAssert(len(pb.buffer) >= 10)
|
||||
let size = uint(len(pb.buffer) - 10)
|
||||
let pos = 10 - vsizeof(size)
|
||||
var usedBytes = 0
|
||||
|
@ -274,14 +274,17 @@ proc finish*(pb: var ProtoBuffer) =
|
|||
doAssert(res.isOk())
|
||||
pb.offset = pos
|
||||
elif WithUint32BeLength in pb.options:
|
||||
doAssert(len(pb.buffer) >= 4)
|
||||
let size = uint(len(pb.buffer) - 4)
|
||||
pb.buffer[0 ..< 4] = toBytesBE(uint32(size))
|
||||
pb.offset = 4
|
||||
elif WithUint32LeLength in pb.options:
|
||||
doAssert(len(pb.buffer) >= 4)
|
||||
let size = uint(len(pb.buffer) - 4)
|
||||
pb.buffer[0 ..< 4] = toBytesLE(uint32(size))
|
||||
pb.offset = 4
|
||||
else:
|
||||
doAssert(len(pb.buffer) > 0)
|
||||
pb.offset = 0
|
||||
|
||||
proc getHeader(data: var ProtoBuffer,
|
||||
|
@ -382,7 +385,7 @@ proc getValue[T: ProtoScalar](data: var ProtoBuffer,
|
|||
err(ProtoError.MessageIncomplete)
|
||||
|
||||
proc getValue[T:byte|char](data: var ProtoBuffer, header: ProtoHeader,
|
||||
outBytes: var openarray[T],
|
||||
outBytes: var openArray[T],
|
||||
outLength: var int): ProtoResult[void] =
|
||||
doAssert(header.wire == ProtoFieldKind.Length)
|
||||
var length = 0
|
||||
|
@ -475,7 +478,7 @@ proc getField*[T: ProtoScalar](data: ProtoBuffer, field: int,
|
|||
ok(false)
|
||||
|
||||
proc getField*[T: byte|char](data: ProtoBuffer, field: int,
|
||||
output: var openarray[T],
|
||||
output: var openArray[T],
|
||||
outlen: var int): ProtoResult[bool] =
|
||||
checkFieldNumber(field)
|
||||
var pb = data
|
||||
|
|
|
@ -37,7 +37,7 @@ type
|
|||
IdentifyNoPubKeyError* = object of IdentifyError
|
||||
|
||||
IdentifyInfo* = object
|
||||
pubKey*: Option[PublicKey]
|
||||
pubkey*: Option[PublicKey]
|
||||
peerId*: PeerId
|
||||
addrs*: seq[MultiAddress]
|
||||
observedAddr*: Option[MultiAddress]
|
||||
|
@ -57,7 +57,7 @@ type
|
|||
IdentifyPush* = ref object of LPProtocol
|
||||
identifyHandler: IdentifyPushHandler
|
||||
|
||||
proc encodeMsg*(peerInfo: PeerInfo, observedAddr: Multiaddress): ProtoBuffer
|
||||
proc encodeMsg*(peerInfo: PeerInfo, observedAddr: MultiAddress): ProtoBuffer
|
||||
{.raises: [Defect, IdentifyNoPubKeyError].} =
|
||||
result = initProtoBuffer()
|
||||
|
||||
|
@ -81,14 +81,14 @@ proc encodeMsg*(peerInfo: PeerInfo, observedAddr: Multiaddress): ProtoBuffer
|
|||
proc decodeMsg*(buf: seq[byte]): Option[IdentifyInfo] =
|
||||
var
|
||||
iinfo: IdentifyInfo
|
||||
pubKey: PublicKey
|
||||
pubkey: PublicKey
|
||||
oaddr: MultiAddress
|
||||
protoVersion: string
|
||||
agentVersion: string
|
||||
|
||||
var pb = initProtoBuffer(buf)
|
||||
|
||||
let r1 = pb.getField(1, pubKey)
|
||||
let r1 = pb.getField(1, pubkey)
|
||||
let r2 = pb.getRepeatedField(2, iinfo.addrs)
|
||||
let r3 = pb.getRepeatedField(3, iinfo.protos)
|
||||
let r4 = pb.getField(4, oaddr)
|
||||
|
@ -100,14 +100,14 @@ proc decodeMsg*(buf: seq[byte]): Option[IdentifyInfo] =
|
|||
|
||||
if res:
|
||||
if r1.get():
|
||||
iinfo.pubKey = some(pubKey)
|
||||
iinfo.pubkey = some(pubkey)
|
||||
if r4.get():
|
||||
iinfo.observedAddr = some(oaddr)
|
||||
if r5.get():
|
||||
iinfo.protoVersion = some(protoVersion)
|
||||
if r6.get():
|
||||
iinfo.agentVersion = some(agentVersion)
|
||||
debug "decodeMsg: decoded message", pubkey = ($pubKey).shortLog,
|
||||
debug "decodeMsg: decoded message", pubkey = ($pubkey).shortLog,
|
||||
addresses = $iinfo.addrs, protocols = $iinfo.protos,
|
||||
observable_address = $iinfo.observedAddr,
|
||||
proto_version = $iinfo.protoVersion,
|
||||
|
@ -153,8 +153,8 @@ proc identify*(p: Identify,
|
|||
raise newException(IdentityInvalidMsgError, "Incorrect message received!")
|
||||
result = infoOpt.get()
|
||||
|
||||
if result.pubKey.isSome:
|
||||
let peer = PeerID.init(result.pubKey.get())
|
||||
if result.pubkey.isSome:
|
||||
let peer = PeerId.init(result.pubkey.get())
|
||||
if peer.isErr:
|
||||
raise newException(IdentityInvalidMsgError, $peer.error)
|
||||
else:
|
||||
|
@ -185,8 +185,8 @@ proc init*(p: IdentifyPush) =
|
|||
|
||||
var indentInfo = infoOpt.get()
|
||||
|
||||
if indentInfo.pubKey.isSome:
|
||||
let receivedPeerId = PeerID.init(indentInfo.pubKey.get()).tryGet()
|
||||
if indentInfo.pubkey.isSome:
|
||||
let receivedPeerId = PeerId.init(indentInfo.pubkey.get()).tryGet()
|
||||
if receivedPeerId != conn.peerId:
|
||||
raise newException(IdentityNoMatchError, "Peer ids don't match")
|
||||
indentInfo.peerId = receivedPeerId
|
||||
|
|
|
@ -75,7 +75,7 @@ proc handleSubscribe*(f: FloodSub,
|
|||
# unsubscribe the peer from the topic
|
||||
peers[].excl(peer)
|
||||
|
||||
method unsubscribePeer*(f: FloodSub, peer: PeerID) =
|
||||
method unsubscribePeer*(f: FloodSub, peer: PeerId) =
|
||||
## handle peer disconnects
|
||||
##
|
||||
trace "unsubscribing floodsub peer", peer
|
||||
|
|
|
@ -43,6 +43,7 @@ proc init*(_: type[GossipSubParams]): GossipSubParams =
|
|||
GossipSubParams(
|
||||
explicit: true,
|
||||
pruneBackoff: 1.minutes,
|
||||
unsubscribeBackoff: 5.seconds,
|
||||
floodPublish: true,
|
||||
gossipFactor: 0.25,
|
||||
d: GossipSubD,
|
||||
|
@ -77,6 +78,8 @@ proc validateParameters*(parameters: GossipSubParams): Result[void, cstring] =
|
|||
err("gossipsub: dOut parameter error, Number of outbound connections to keep in the mesh. Must be less than D_lo and at most D/2")
|
||||
elif parameters.gossipThreshold >= 0:
|
||||
err("gossipsub: gossipThreshold parameter error, Must be < 0")
|
||||
elif parameters.unsubscribeBackoff.seconds <= 0:
|
||||
err("gossipsub: unsubscribeBackoff parameter error, Must be > 0 seconds")
|
||||
elif parameters.publishThreshold >= parameters.gossipThreshold:
|
||||
err("gossipsub: publishThreshold parameter error, Must be < gossipThreshold")
|
||||
elif parameters.graylistThreshold >= parameters.publishThreshold:
|
||||
|
@ -166,7 +169,7 @@ method onPubSubPeerEvent*(p: GossipSub, peer: PubsubPeer, event: PubSubPeerEvent
|
|||
|
||||
procCall FloodSub(p).onPubSubPeerEvent(peer, event)
|
||||
|
||||
method unsubscribePeer*(g: GossipSub, peer: PeerID) =
|
||||
method unsubscribePeer*(g: GossipSub, peer: PeerId) =
|
||||
## handle peer disconnects
|
||||
##
|
||||
|
||||
|
@ -413,11 +416,11 @@ method onTopicSubscription*(g: GossipSub, topic: string, subscribed: bool) =
|
|||
prune: @[ControlPrune(
|
||||
topicID: topic,
|
||||
peers: g.peerExchangeList(topic),
|
||||
backoff: g.parameters.pruneBackoff.seconds.uint64)])))
|
||||
backoff: g.parameters.unsubscribeBackoff.seconds.uint64)])))
|
||||
g.broadcast(mpeers, msg)
|
||||
|
||||
for peer in mpeers:
|
||||
g.pruned(peer, topic)
|
||||
g.pruned(peer, topic, backoff = some(g.parameters.unsubscribeBackoff))
|
||||
|
||||
g.mesh.del(topic)
|
||||
|
||||
|
|
|
@ -38,11 +38,20 @@ proc grafted*(g: GossipSub, p: PubSubPeer, topic: string) {.raises: [Defect].} =
|
|||
|
||||
trace "grafted", peer=p, topic
|
||||
|
||||
proc pruned*(g: GossipSub, p: PubSubPeer, topic: string, setBackoff: bool = true) {.raises: [Defect].} =
|
||||
proc pruned*(g: GossipSub,
|
||||
p: PubSubPeer,
|
||||
topic: string,
|
||||
setBackoff: bool = true,
|
||||
backoff = none(Duration)) {.raises: [Defect].} =
|
||||
if setBackoff:
|
||||
let backoff = Moment.fromNow(g.parameters.pruneBackoff)
|
||||
let
|
||||
backoffDuration =
|
||||
if isSome(backoff): backoff.get()
|
||||
else: g.parameters.pruneBackoff
|
||||
backoffMoment = Moment.fromNow(backoffDuration)
|
||||
|
||||
g.backingOff
|
||||
.mgetOrPut(topic, initTable[PeerID, Moment]())[p.peerId] = backoff
|
||||
.mgetOrPut(topic, initTable[PeerId, Moment]())[p.peerId] = backoffMoment
|
||||
|
||||
g.peerStats.withValue(p.peerId, stats):
|
||||
stats.topicInfos.withValue(topic, info):
|
||||
|
@ -62,7 +71,7 @@ proc pruned*(g: GossipSub, p: PubSubPeer, topic: string, setBackoff: bool = true
|
|||
proc handleBackingOff*(t: var BackoffTable, topic: string) {.raises: [Defect].} =
|
||||
let now = Moment.now()
|
||||
var expired = toSeq(t.getOrDefault(topic).pairs())
|
||||
expired.keepIf do (pair: tuple[peer: PeerID, expire: Moment]) -> bool:
|
||||
expired.keepIf do (pair: tuple[peer: PeerId, expire: Moment]) -> bool:
|
||||
now >= pair.expire
|
||||
for (peer, _) in expired:
|
||||
t.withValue(topic, v):
|
||||
|
@ -75,7 +84,7 @@ proc peerExchangeList*(g: GossipSub, topic: string): seq[PeerInfoMsg] {.raises:
|
|||
# by spec, larger then Dhi, but let's put some hard caps
|
||||
peers.setLen(min(peers.len, g.parameters.dHigh * 2))
|
||||
peers.map do (x: PubSubPeer) -> PeerInfoMsg:
|
||||
PeerInfoMsg(peerID: x.peerId.getBytes())
|
||||
PeerInfoMsg(peerId: x.peerId.getBytes())
|
||||
|
||||
proc handleGraft*(g: GossipSub,
|
||||
peer: PubSubPeer,
|
||||
|
@ -98,7 +107,7 @@ proc handleGraft*(g: GossipSub,
|
|||
|
||||
let backoff = Moment.fromNow(g.parameters.pruneBackoff)
|
||||
g.backingOff
|
||||
.mgetOrPut(topic, initTable[PeerID, Moment]())[peer.peerId] = backoff
|
||||
.mgetOrPut(topic, initTable[PeerId, Moment]())[peer.peerId] = backoff
|
||||
|
||||
peer.behaviourPenalty += 0.1
|
||||
|
||||
|
@ -120,7 +129,7 @@ proc handleGraft*(g: GossipSub,
|
|||
|
||||
let backoff = Moment.fromNow(g.parameters.pruneBackoff)
|
||||
g.backingOff
|
||||
.mgetOrPut(topic, initTable[PeerID, Moment]())[peer.peerId] = backoff
|
||||
.mgetOrPut(topic, initTable[PeerId, Moment]())[peer.peerId] = backoff
|
||||
|
||||
peer.behaviourPenalty += 0.1
|
||||
|
||||
|
@ -175,7 +184,7 @@ proc handlePrune*(g: GossipSub, peer: PubSubPeer, prunes: seq[ControlPrune]) {.r
|
|||
current = g.backingOff.getOrDefault(topic).getOrDefault(peer.peerId)
|
||||
if backoff > current:
|
||||
g.backingOff
|
||||
.mgetOrPut(topic, initTable[PeerID, Moment]())[peer.peerId] = backoff
|
||||
.mgetOrPut(topic, initTable[PeerId, Moment]())[peer.peerId] = backoff
|
||||
|
||||
trace "pruning rpc received peer", peer, score = peer.score
|
||||
g.pruned(peer, topic, setBackoff = false)
|
||||
|
|
|
@ -73,7 +73,7 @@ proc colocationFactor(g: GossipSub, peer: PubSubPeer): float64 =
|
|||
else:
|
||||
let
|
||||
address = peer.address.get()
|
||||
g.peersInIP.mgetOrPut(address, initHashSet[PeerID]()).incl(peer.peerId)
|
||||
g.peersInIP.mgetOrPut(address, initHashSet[PeerId]()).incl(peer.peerId)
|
||||
let
|
||||
ipPeers = g.peersInIP.getOrDefault(address).len().float64
|
||||
if ipPeers > g.parameters.ipColocationFactorThreshold:
|
||||
|
@ -109,7 +109,7 @@ proc updateScores*(g: GossipSub) = # avoid async
|
|||
trace "updating scores", peers = g.peers.len
|
||||
|
||||
let now = Moment.now()
|
||||
var evicting: seq[PeerID]
|
||||
var evicting: seq[PeerId]
|
||||
|
||||
for peerId, stats in g.peerStats.mpairs:
|
||||
let peer = g.peers.getOrDefault(peerId)
|
||||
|
|
|
@ -102,6 +102,7 @@ type
|
|||
GossipSubParams* = object
|
||||
explicit*: bool
|
||||
pruneBackoff*: Duration
|
||||
unsubscribeBackoff*: Duration
|
||||
floodPublish*: bool
|
||||
gossipFactor*: float64
|
||||
d*: int
|
||||
|
@ -138,7 +139,7 @@ type
|
|||
|
||||
disconnectBadPeers*: bool
|
||||
|
||||
BackoffTable* = Table[string, Table[PeerID, Moment]]
|
||||
BackoffTable* = Table[string, Table[PeerId, Moment]]
|
||||
ValidationSeenTable* = Table[MessageID, HashSet[PubSubPeer]]
|
||||
|
||||
GossipSub* = ref object of FloodSub
|
||||
|
@ -155,11 +156,11 @@ type
|
|||
heartbeatFut*: Future[void] # cancellation future for heartbeat interval
|
||||
heartbeatRunning*: bool
|
||||
|
||||
peerStats*: Table[PeerID, PeerStats]
|
||||
peerStats*: Table[PeerId, PeerStats]
|
||||
parameters*: GossipSubParams
|
||||
topicParams*: Table[string, TopicParams]
|
||||
directPeersLoop*: Future[void]
|
||||
peersInIP*: Table[MultiAddress, HashSet[PeerID]]
|
||||
peersInIP*: Table[MultiAddress, HashSet[PeerId]]
|
||||
|
||||
heartbeatEvents*: seq[AsyncEvent]
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import ./pubsubpeer, ../../peerid
|
|||
type
|
||||
PeerTable* = Table[string, HashSet[PubSubPeer]] # topic string to peer map
|
||||
|
||||
proc hasPeerID*(t: PeerTable, topic: string, peerId: PeerID): bool =
|
||||
proc hasPeerId*(t: PeerTable, topic: string, peerId: PeerId): bool =
|
||||
if topic in t:
|
||||
try:
|
||||
for peer in t[topic]:
|
||||
|
|
|
@ -94,7 +94,7 @@ type
|
|||
switch*: Switch # the switch used to dial/connect to peers
|
||||
peerInfo*: PeerInfo # this peer's info
|
||||
topics*: Table[string, seq[TopicHandler]] # the topics that _we_ are interested in
|
||||
peers*: Table[PeerID, PubSubPeer] ##\
|
||||
peers*: Table[PeerId, PubSubPeer] ##\
|
||||
## Peers that we are interested to gossip with (but not necessarily
|
||||
## yet connected to)
|
||||
triggerSelf*: bool # trigger own local handler on publish
|
||||
|
@ -119,7 +119,7 @@ type
|
|||
|
||||
knownTopics*: HashSet[string]
|
||||
|
||||
method unsubscribePeer*(p: PubSub, peerId: PeerID) {.base.} =
|
||||
method unsubscribePeer*(p: PubSub, peerId: PeerId) {.base.} =
|
||||
## handle peer disconnects
|
||||
##
|
||||
|
||||
|
@ -273,7 +273,7 @@ method onPubSubPeerEvent*(p: PubSub, peer: PubsubPeer, event: PubsubPeerEvent) {
|
|||
|
||||
proc getOrCreatePeer*(
|
||||
p: PubSub,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
protos: seq[string]): PubSubPeer =
|
||||
p.peers.withValue(peerId, peer):
|
||||
return peer[]
|
||||
|
@ -374,7 +374,7 @@ method handleConn*(p: PubSub,
|
|||
finally:
|
||||
await conn.closeWithEOF()
|
||||
|
||||
method subscribePeer*(p: PubSub, peer: PeerID) {.base.} =
|
||||
method subscribePeer*(p: PubSub, peer: PeerId) {.base.} =
|
||||
## subscribe to remote peer to receive/send pubsub
|
||||
## messages
|
||||
##
|
||||
|
|
|
@ -53,7 +53,7 @@ type
|
|||
codec*: string # the protocol that this peer joined from
|
||||
sendConn*: Connection # cached send connection
|
||||
address*: Option[MultiAddress]
|
||||
peerId*: PeerID
|
||||
peerId*: PeerId
|
||||
handler*: RPCHandler
|
||||
observers*: ref seq[PubSubObserver] # ref as in smart_ptr
|
||||
|
||||
|
@ -281,7 +281,7 @@ proc send*(p: PubSubPeer, msg: RPCMsg, anonymize: bool) {.raises: [Defect].} =
|
|||
|
||||
proc new*(
|
||||
T: typedesc[PubSubPeer],
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
getConn: GetConn,
|
||||
dropConn: DropConn,
|
||||
onEvent: OnEvent,
|
||||
|
|
|
@ -17,7 +17,7 @@ export options
|
|||
|
||||
type
|
||||
PeerInfoMsg* = object
|
||||
peerID*: seq[byte]
|
||||
peerId*: seq[byte]
|
||||
signedPeerRecord*: seq[byte]
|
||||
|
||||
SubOpts* = object
|
||||
|
|
|
@ -39,7 +39,7 @@ proc write*(pb: var ProtoBuffer, field: int, graft: ControlGraft) =
|
|||
|
||||
proc write*(pb: var ProtoBuffer, field: int, infoMsg: PeerInfoMsg) =
|
||||
var ipb = initProtoBuffer()
|
||||
ipb.write(1, infoMsg.peerID)
|
||||
ipb.write(1, infoMsg.peerId)
|
||||
ipb.write(2, infoMsg.signedPeerRecord)
|
||||
ipb.finish()
|
||||
pb.write(field, ipb)
|
||||
|
@ -142,10 +142,10 @@ proc decodePeerInfoMsg*(pb: ProtoBuffer): ProtoResult[PeerInfoMsg] {.
|
|||
inline.} =
|
||||
trace "decodePeerInfoMsg: decoding message"
|
||||
var pi = PeerInfoMsg()
|
||||
if ? pb.getField(1, pi.peerID):
|
||||
trace "decodePeerInfoMsg: read peerID", peerID = pi.peerID
|
||||
if ? pb.getField(1, pi.peerId):
|
||||
trace "decodePeerInfoMsg: read peerId", peerId = pi.peerId
|
||||
else:
|
||||
trace "decodePeerInfoMsg: peerID is missing"
|
||||
trace "decodePeerInfoMsg: peerId is missing"
|
||||
if ? pb.getField(2, pi.signedPeerRecord):
|
||||
trace "decodePeerInfoMsg: read signedPeerRecord", signedPeerRecord = pi.signedPeerRecord
|
||||
else:
|
||||
|
|
|
@ -146,7 +146,7 @@ proc encrypt(
|
|||
|
||||
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)
|
||||
|
||||
let tag = encrypt(state, result, ad)
|
||||
|
@ -217,7 +217,7 @@ proc encryptAndHash(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
|
||||
if ss.cs.hasKey:
|
||||
if ss.cs.hasKey and data.len > ChaChaPolyTag.len:
|
||||
result = ss.cs.decryptWithAd(ss.h.data, data)
|
||||
else:
|
||||
result = @data
|
||||
|
@ -368,7 +368,7 @@ proc handshakeXXOutbound(
|
|||
dh_se()
|
||||
|
||||
# last payload must follow the encrypted way of sending
|
||||
msg.add hs.ss.encryptAndHash(p2psecret)
|
||||
msg.add hs.ss.encryptAndHash(p2pSecret)
|
||||
|
||||
await conn.sendHSMessage(msg.data)
|
||||
|
||||
|
@ -408,7 +408,7 @@ proc handshakeXXInbound(
|
|||
write_s()
|
||||
dh_es()
|
||||
|
||||
msg.add hs.ss.encryptAndHash(p2psecret)
|
||||
msg.add hs.ss.encryptAndHash(p2pSecret)
|
||||
|
||||
await conn.sendHSMessage(msg.data)
|
||||
msg.clear()
|
||||
|
@ -431,7 +431,7 @@ method readMessage*(sconn: NoiseConnection): Future[seq[byte]] {.async.} =
|
|||
while true: # Discard 0-length payloads
|
||||
let frame = await sconn.stream.readFrame()
|
||||
sconn.activity = true
|
||||
if frame.len > 0:
|
||||
if frame.len > ChaChaPolyTag.len:
|
||||
let res = sconn.readCs.decryptWithAd([], frame)
|
||||
if res.len > 0:
|
||||
when defined(libp2p_dump):
|
||||
|
@ -460,10 +460,8 @@ proc encryptFrame(
|
|||
|
||||
cipherFrame[2 + src.len()..<cipherFrame.len] = tag
|
||||
|
||||
method write*(sconn: NoiseConnection, message: seq[byte]): Future[void] {.async.} =
|
||||
if message.len == 0:
|
||||
return
|
||||
|
||||
method write*(sconn: NoiseConnection, message: seq[byte]): Future[void] =
|
||||
# Fast path: `{.async.}` would introduce a copy of `message`
|
||||
const FramingSize = 2 + sizeof(ChaChaPolyTag)
|
||||
|
||||
let
|
||||
|
@ -479,10 +477,16 @@ method write*(sconn: NoiseConnection, message: seq[byte]): Future[void] {.async.
|
|||
let
|
||||
chunkSize = min(MaxPlainSize, left)
|
||||
|
||||
encryptFrame(
|
||||
sconn,
|
||||
cipherFrames.toOpenArray(woffset, woffset + chunkSize + FramingSize - 1),
|
||||
message.toOpenArray(offset, offset + chunkSize - 1))
|
||||
try:
|
||||
encryptFrame(
|
||||
sconn,
|
||||
cipherFrames.toOpenArray(woffset, woffset + chunkSize + FramingSize - 1),
|
||||
message.toOpenArray(offset, offset + chunkSize - 1))
|
||||
except NoiseNonceMaxError as exc:
|
||||
debug "Noise nonce exceeded"
|
||||
let fut = newFuture[void]("noise.write.nonce")
|
||||
fut.fail(exc)
|
||||
return fut
|
||||
|
||||
when defined(libp2p_dump):
|
||||
dumpMessage(
|
||||
|
@ -492,9 +496,12 @@ method write*(sconn: NoiseConnection, message: seq[byte]): Future[void] {.async.
|
|||
left = left - chunkSize
|
||||
offset += chunkSize
|
||||
woffset += chunkSize + FramingSize
|
||||
sconn.activity = true
|
||||
|
||||
await sconn.stream.write(cipherFrames)
|
||||
sconn.activity = true
|
||||
|
||||
# Write all `cipherFrames` in a single write, to avoid interleaving /
|
||||
# sequencing issues
|
||||
sconn.stream.write(cipherFrames)
|
||||
|
||||
method handshake*(p: Noise, conn: Connection, initiator: bool): Future[SecureConn] {.async.} =
|
||||
trace "Starting Noise handshake", conn, initiator
|
||||
|
@ -547,7 +554,7 @@ method handshake*(p: Noise, conn: Connection, initiator: bool): Future[SecureCon
|
|||
trace "Remote signature verified", conn
|
||||
|
||||
if initiator:
|
||||
let pid = PeerID.init(remotePubKey)
|
||||
let pid = PeerId.init(remotePubKey)
|
||||
if not conn.peerId.validate():
|
||||
raise newException(NoiseHandshakeError, "Failed to validate peerId.")
|
||||
if pid.isErr or pid.get() != conn.peerId:
|
||||
|
@ -560,7 +567,7 @@ method handshake*(p: Noise, conn: Connection, initiator: bool): Future[SecureCon
|
|||
received_key = $remotePubKey
|
||||
raise newException(NoiseHandshakeError, "Noise handshake, peer infos don't match! " & $pid & " != " & $conn.peerId)
|
||||
else:
|
||||
let pid = PeerID.init(remotePubKey)
|
||||
let pid = PeerId.init(remotePubKey)
|
||||
if pid.isErr:
|
||||
raise newException(NoiseHandshakeError, "Invalid remote peer id")
|
||||
conn.peerId = pid.get()
|
||||
|
|
|
@ -83,7 +83,7 @@ func shortLog*(conn: SecioConn): auto =
|
|||
|
||||
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]) =
|
||||
if hash == "SHA256":
|
||||
mac = SecureMac(kind: SecureMacType.Sha256)
|
||||
mac.ctxsha256.init(key)
|
||||
|
@ -94,7 +94,7 @@ proc init(mac: var SecureMac, hash: string, key: openarray[byte]) =
|
|||
mac = SecureMac(kind: SecureMacType.Sha1)
|
||||
mac.ctxsha1.init(key)
|
||||
|
||||
proc update(mac: var SecureMac, data: openarray[byte]) =
|
||||
proc update(mac: var SecureMac, data: openArray[byte]) =
|
||||
case mac.kind
|
||||
of SecureMacType.Sha256:
|
||||
update(mac.ctxsha256, data)
|
||||
|
@ -112,7 +112,7 @@ proc sizeDigest(mac: SecureMac): int {.inline.} =
|
|||
of SecureMacType.Sha1:
|
||||
result = int(mac.ctxsha1.sizeDigest())
|
||||
|
||||
proc finish(mac: var SecureMac, data: var openarray[byte]) =
|
||||
proc finish(mac: var SecureMac, data: var openArray[byte]) =
|
||||
case mac.kind
|
||||
of SecureMacType.Sha256:
|
||||
discard finish(mac.ctxsha256, data)
|
||||
|
@ -130,8 +130,8 @@ proc reset(mac: var SecureMac) =
|
|||
of SecureMacType.Sha1:
|
||||
reset(mac.ctxsha1)
|
||||
|
||||
proc init(sc: var SecureCipher, cipher: string, key: openarray[byte],
|
||||
iv: openarray[byte]) {.inline.} =
|
||||
proc init(sc: var SecureCipher, cipher: string, key: openArray[byte],
|
||||
iv: openArray[byte]) {.inline.} =
|
||||
if cipher == "AES-128":
|
||||
sc = SecureCipher(kind: SecureCipherType.Aes128)
|
||||
sc.ctxaes128.init(key, iv)
|
||||
|
@ -142,8 +142,8 @@ proc init(sc: var SecureCipher, cipher: string, key: openarray[byte],
|
|||
sc = SecureCipher(kind: SecureCipherType.Twofish)
|
||||
sc.ctxtwofish256.init(key, iv)
|
||||
|
||||
proc encrypt(cipher: var SecureCipher, input: openarray[byte],
|
||||
output: var openarray[byte]) {.inline.} =
|
||||
proc encrypt(cipher: var SecureCipher, input: openArray[byte],
|
||||
output: var openArray[byte]) {.inline.} =
|
||||
case cipher.kind
|
||||
of SecureCipherType.Aes128:
|
||||
cipher.ctxaes128.encrypt(input, output)
|
||||
|
@ -152,8 +152,8 @@ proc encrypt(cipher: var SecureCipher, input: openarray[byte],
|
|||
of SecureCipherType.Twofish:
|
||||
cipher.ctxtwofish256.encrypt(input, output)
|
||||
|
||||
proc decrypt(cipher: var SecureCipher, input: openarray[byte],
|
||||
output: var openarray[byte]) {.inline.} =
|
||||
proc decrypt(cipher: var SecureCipher, input: openArray[byte],
|
||||
output: var openArray[byte]) {.inline.} =
|
||||
case cipher.kind
|
||||
of SecureCipherType.Aes128:
|
||||
cipher.ctxaes128.decrypt(input, output)
|
||||
|
@ -300,8 +300,8 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
|
|||
remoteExchanges: string
|
||||
remoteCiphers: string
|
||||
remoteHashes: string
|
||||
remotePeerId: PeerID
|
||||
localPeerId: PeerID
|
||||
remotePeerId: PeerId
|
||||
localPeerId: PeerId
|
||||
localBytesPubkey = s.localPublicKey.getBytes().tryGet()
|
||||
|
||||
brHmacDrbgGenerate(s.rng[], localNonce)
|
||||
|
@ -312,7 +312,7 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
|
|||
SecioCiphers,
|
||||
SecioHashes)
|
||||
|
||||
localPeerId = PeerID.init(s.localPublicKey).tryGet()
|
||||
localPeerId = PeerId.init(s.localPublicKey).tryGet()
|
||||
|
||||
trace "Local proposal", schemes = SecioExchanges,
|
||||
ciphers = SecioCiphers,
|
||||
|
@ -336,9 +336,9 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
|
|||
pubkey = remoteBytesPubkey.shortLog
|
||||
raise (ref SecioError)(msg: "Remote public key incorrect or corrupted")
|
||||
|
||||
remotePeerId = PeerID.init(remotePubkey).tryGet()
|
||||
remotePeerId = PeerId.init(remotePubkey).tryGet()
|
||||
|
||||
# TODO: PeerID check against supplied PeerID
|
||||
# TODO: PeerId check against supplied PeerId
|
||||
if not initiator:
|
||||
conn.peerId = remotePeerId
|
||||
let order = getOrder(remoteBytesPubkey, localNonce, localBytesPubkey,
|
||||
|
|
|
@ -45,7 +45,7 @@ chronicles.formatIt(SecureConn): shortLog(it)
|
|||
proc new*(T: type SecureConn,
|
||||
conn: Connection,
|
||||
peerId: PeerId,
|
||||
observedAddr: Multiaddress,
|
||||
observedAddr: MultiAddress,
|
||||
timeout: Duration = DefaultConnectionTimeout): T =
|
||||
result = T(stream: conn,
|
||||
peerId: peerId,
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
## 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.
|
||||
|
||||
## This module implements Routing Records.
|
||||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import std/[sequtils, times]
|
||||
import pkg/stew/[results, byteutils]
|
||||
import
|
||||
multiaddress,
|
||||
multicodec,
|
||||
peerid,
|
||||
protobuf/minprotobuf,
|
||||
signed_envelope
|
||||
|
||||
export peerid, multiaddress, signed_envelope
|
||||
|
||||
## Constants relating to signed peer records
|
||||
const
|
||||
EnvelopeDomain = multiCodec("libp2p-peer-record") # envelope domain as per RFC0002
|
||||
EnvelopePayloadType= @[(byte) 0x03, (byte) 0x01] # payload_type for routing records as spec'ed in RFC0003
|
||||
|
||||
type
|
||||
AddressInfo* = object
|
||||
address*: MultiAddress
|
||||
|
||||
PeerRecord* = object
|
||||
peerId*: PeerId
|
||||
seqNo*: uint64
|
||||
addresses*: seq[AddressInfo]
|
||||
|
||||
proc decode*(
|
||||
T: typedesc[PeerRecord],
|
||||
buffer: seq[byte]): Result[PeerRecord, ProtoError] =
|
||||
|
||||
let pb = initProtoBuffer(buffer)
|
||||
var record = PeerRecord()
|
||||
|
||||
? pb.getRequiredField(1, record.peerId)
|
||||
? pb.getRequiredField(2, record.seqNo)
|
||||
|
||||
var addressInfos: seq[seq[byte]]
|
||||
let pb3 = ? pb.getRepeatedField(3, addressInfos)
|
||||
|
||||
if pb3:
|
||||
for address in addressInfos:
|
||||
var addressInfo = AddressInfo()
|
||||
let subProto = initProtoBuffer(address)
|
||||
if ? subProto.getField(1, addressInfo.address) == false:
|
||||
return err(ProtoError.RequiredFieldMissing)
|
||||
|
||||
record.addresses &= addressInfo
|
||||
|
||||
ok(record)
|
||||
|
||||
proc encode*(record: PeerRecord): seq[byte] =
|
||||
var pb = initProtoBuffer()
|
||||
|
||||
pb.write(1, record.peerId)
|
||||
pb.write(2, record.seqNo)
|
||||
|
||||
for address in record.addresses:
|
||||
var addrPb = initProtoBuffer()
|
||||
addrPb.write(1, address.address)
|
||||
pb.write(3, addrPb)
|
||||
|
||||
pb.finish()
|
||||
pb.buffer
|
||||
|
||||
proc init*(T: typedesc[PeerRecord],
|
||||
peerId: PeerId,
|
||||
seqNo: uint64,
|
||||
addresses: seq[MultiAddress]): T =
|
||||
|
||||
PeerRecord(
|
||||
peerId: peerId,
|
||||
seqNo: seqNo,
|
||||
addresses: addresses.mapIt(AddressInfo(address: it))
|
||||
)
|
||||
|
||||
|
||||
## Functions related to signed peer records
|
||||
|
||||
proc init*(T: typedesc[Envelope],
|
||||
privateKey: PrivateKey,
|
||||
peerRecord: PeerRecord): Result[Envelope, CryptoError] =
|
||||
|
||||
## Init a signed envelope wrapping a peer record
|
||||
|
||||
let envelope = ? Envelope.init(privateKey,
|
||||
EnvelopePayloadType,
|
||||
peerRecord.encode(),
|
||||
$EnvelopeDomain)
|
||||
|
||||
ok(envelope)
|
||||
|
||||
proc init*(T: typedesc[Envelope],
|
||||
peerId: PeerId,
|
||||
addresses: seq[MultiAddress],
|
||||
privateKey: PrivateKey): Result[Envelope, CryptoError] =
|
||||
## Creates a signed peer record for this peer:
|
||||
## a peer routing record according to https://github.com/libp2p/specs/blob/500a7906dd7dd8f64e0af38de010ef7551fd61b6/RFC/0003-routing-records.md
|
||||
## in a signed envelope according to https://github.com/libp2p/specs/blob/500a7906dd7dd8f64e0af38de010ef7551fd61b6/RFC/0002-signed-envelopes.md
|
||||
|
||||
# First create a peer record from the peer info
|
||||
let peerRecord = PeerRecord.init(peerId,
|
||||
getTime().toUnix().uint64, # This currently follows the recommended implementation, using unix epoch as seq no.
|
||||
addresses)
|
||||
|
||||
let envelope = ? Envelope.init(privateKey,
|
||||
peerRecord)
|
||||
|
||||
ok(envelope)
|
||||
|
||||
proc getSignedPeerRecord*(pb: ProtoBuffer, field: int,
|
||||
value: var Envelope): ProtoResult[bool] {.
|
||||
inline.} =
|
||||
getField(pb, field, value, $EnvelopeDomain)
|
|
@ -0,0 +1,118 @@
|
|||
## 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.
|
||||
|
||||
## This module implements Signed Envelope.
|
||||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import pkg/stew/[results, byteutils]
|
||||
import multicodec,
|
||||
crypto/crypto,
|
||||
protobuf/minprotobuf,
|
||||
vbuffer
|
||||
|
||||
export crypto
|
||||
|
||||
type
|
||||
EnvelopeError* = enum
|
||||
EnvelopeInvalidProtobuf,
|
||||
EnvelopeFieldMissing,
|
||||
EnvelopeInvalidSignature
|
||||
|
||||
Envelope* = object
|
||||
publicKey*: PublicKey
|
||||
domain*: string
|
||||
payloadType*: seq[byte]
|
||||
payload: seq[byte]
|
||||
signature*: Signature
|
||||
|
||||
proc mapProtobufError(e: ProtoError): EnvelopeError =
|
||||
case e:
|
||||
of RequiredFieldMissing:
|
||||
EnvelopeFieldMissing
|
||||
else:
|
||||
EnvelopeInvalidProtobuf
|
||||
|
||||
proc getSignatureBuffer(e: Envelope): seq[byte] =
|
||||
var buffer = initVBuffer()
|
||||
|
||||
let domainBytes = e.domain.toBytes()
|
||||
buffer.writeSeq(domainBytes)
|
||||
buffer.writeSeq(e.payloadType)
|
||||
buffer.writeSeq(e.payload)
|
||||
|
||||
buffer.buffer
|
||||
|
||||
proc decode*(T: typedesc[Envelope],
|
||||
buf: seq[byte],
|
||||
domain: string): Result[Envelope, EnvelopeError] =
|
||||
|
||||
let pb = initProtoBuffer(buf)
|
||||
var envelope = Envelope()
|
||||
|
||||
envelope.domain = domain
|
||||
? pb.getRequiredField(1, envelope.publicKey).mapErr(mapProtobufError)
|
||||
discard ? pb.getField(2, envelope.payloadType).mapErr(mapProtobufError)
|
||||
? pb.getRequiredField(3, envelope.payload).mapErr(mapProtobufError)
|
||||
? pb.getRequiredField(5, envelope.signature).mapErr(mapProtobufError)
|
||||
|
||||
if envelope.signature.verify(envelope.getSignatureBuffer(), envelope.publicKey) == false:
|
||||
err(EnvelopeInvalidSignature)
|
||||
else:
|
||||
ok(envelope)
|
||||
|
||||
proc init*(T: typedesc[Envelope],
|
||||
privateKey: PrivateKey,
|
||||
payloadType: seq[byte],
|
||||
payload: seq[byte],
|
||||
domain: string): Result[Envelope, CryptoError] =
|
||||
var envelope = Envelope(
|
||||
publicKey: ? privateKey.getPublicKey(),
|
||||
domain: domain,
|
||||
payloadType: payloadType,
|
||||
payload: payload,
|
||||
)
|
||||
|
||||
envelope.signature = ? privateKey.sign(envelope.getSignatureBuffer())
|
||||
|
||||
ok(envelope)
|
||||
|
||||
proc encode*(env: Envelope): Result[seq[byte], CryptoError] =
|
||||
var pb = initProtoBuffer()
|
||||
|
||||
try:
|
||||
pb.write(1, env.publicKey)
|
||||
pb.write(2, env.payloadType)
|
||||
pb.write(3, env.payload)
|
||||
pb.write(5, env.signature)
|
||||
except ResultError[CryptoError] as exc:
|
||||
return err(exc.error)
|
||||
|
||||
pb.finish()
|
||||
ok(pb.buffer)
|
||||
|
||||
proc payload*(env: Envelope): seq[byte] =
|
||||
# Payload is readonly
|
||||
env.payload
|
||||
|
||||
proc getField*(pb: ProtoBuffer, field: int,
|
||||
value: var Envelope,
|
||||
domain: string): ProtoResult[bool] {.
|
||||
inline.} =
|
||||
var buffer: seq[byte]
|
||||
let res = ? pb.getField(field, buffer)
|
||||
if not(res):
|
||||
ok(false)
|
||||
else:
|
||||
let env = Envelope.decode(buffer, domain)
|
||||
if env.isOk():
|
||||
value = env.get()
|
||||
ok(true)
|
||||
else:
|
||||
err(ProtoError.IncorrectBlob)
|
|
@ -94,7 +94,6 @@ when defined(libp2p_agents_metrics):
|
|||
method readOnce*(s: ChronosStream, pbytes: pointer, nbytes: int): Future[int] {.async.} =
|
||||
if s.atEof:
|
||||
raise newLPStreamEOFError()
|
||||
|
||||
withExceptions:
|
||||
result = await s.client.readOnce(pbytes, nbytes)
|
||||
s.activity = true # reset activity flag
|
||||
|
@ -104,31 +103,36 @@ method readOnce*(s: ChronosStream, pbytes: pointer, nbytes: int): Future[int] {.
|
|||
if s.tracked:
|
||||
libp2p_peers_traffic_read.inc(nbytes.int64, labelValues = [s.shortAgent])
|
||||
|
||||
method write*(s: ChronosStream, msg: seq[byte]) {.async.} =
|
||||
if s.closed:
|
||||
raise newLPStreamClosedError()
|
||||
|
||||
if msg.len == 0:
|
||||
return
|
||||
|
||||
proc completeWrite(
|
||||
s: ChronosStream, fut: Future[int], msgLen: int): Future[void] {.async.} =
|
||||
withExceptions:
|
||||
# StreamTransport will only return written < msg.len on fatal failures where
|
||||
# further writing is not possible - in such cases, we'll raise here,
|
||||
# since we don't return partial writes lengths
|
||||
var written = await s.client.write(msg)
|
||||
var written = await fut
|
||||
|
||||
if written < msg.len:
|
||||
if written < msgLen:
|
||||
raise (ref LPStreamClosedError)(msg: "Write couldn't finish writing")
|
||||
|
||||
s.activity = true # reset activity flag
|
||||
libp2p_network_bytes.inc(msg.len.int64, labelValues = ["out"])
|
||||
libp2p_network_bytes.inc(msgLen.int64, labelValues = ["out"])
|
||||
when defined(libp2p_agents_metrics):
|
||||
s.trackPeerIdentity()
|
||||
if s.tracked:
|
||||
libp2p_peers_traffic_write.inc(msg.len.int64, labelValues = [s.shortAgent])
|
||||
libp2p_peers_traffic_write.inc(msgLen.int64, labelValues = [s.shortAgent])
|
||||
|
||||
method write*(s: ChronosStream, msg: seq[byte]): Future[void] =
|
||||
# Avoid a copy of msg being kept in the closure created by `{.async.}` as this
|
||||
# drives up memory usage
|
||||
if s.closed:
|
||||
let fut = newFuture[void]("chronosstream.write.closed")
|
||||
fut.fail(newLPStreamClosedError())
|
||||
return fut
|
||||
|
||||
s.completeWrite(s.client.write(msg), msg.len)
|
||||
|
||||
method closed*(s: ChronosStream): bool =
|
||||
result = s.client.closed
|
||||
s.client.closed
|
||||
|
||||
method atEof*(s: ChronosStream): bool =
|
||||
s.client.atEof()
|
||||
|
|
|
@ -34,7 +34,7 @@ type
|
|||
timerTaskFut: Future[void] # the current timer instance
|
||||
timeoutHandler*: TimeoutHandler # timeout handler
|
||||
peerId*: PeerId
|
||||
observedAddr*: Multiaddress
|
||||
observedAddr*: MultiAddress
|
||||
upgraded*: Future[void]
|
||||
tag*: string # debug tag for metrics (generally ms protocol)
|
||||
transportDir*: Direction # The bottom level transport (generally the socket) direction
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
import std/[tables,
|
||||
options,
|
||||
sequtils,
|
||||
sets,
|
||||
oids,
|
||||
sugar,
|
||||
|
@ -85,43 +86,43 @@ proc removePeerEventHandler*(s: Switch,
|
|||
kind: PeerEventKind) =
|
||||
s.connManager.removePeerEventHandler(handler, kind)
|
||||
|
||||
proc isConnected*(s: Switch, peerId: PeerID): bool =
|
||||
proc isConnected*(s: Switch, peerId: PeerId): bool =
|
||||
## returns true if the peer has one or more
|
||||
## associated connections (sockets)
|
||||
##
|
||||
|
||||
peerId in s.connManager
|
||||
|
||||
proc disconnect*(s: Switch, peerId: PeerID): Future[void] {.gcsafe.} =
|
||||
proc disconnect*(s: Switch, peerId: PeerId): Future[void] {.gcsafe.} =
|
||||
s.connManager.dropPeer(peerId)
|
||||
|
||||
method connect*(
|
||||
s: Switch,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress]): Future[void] =
|
||||
s.dialer.connect(peerId, addrs)
|
||||
|
||||
method dial*(
|
||||
s: Switch,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
protos: seq[string]): Future[Connection] =
|
||||
s.dialer.dial(peerId, protos)
|
||||
|
||||
proc dial*(s: Switch,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
proto: string): Future[Connection] =
|
||||
dial(s, peerId, @[proto])
|
||||
|
||||
method dial*(
|
||||
s: Switch,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress],
|
||||
protos: seq[string]): Future[Connection] =
|
||||
s.dialer.dial(peerId, addrs, protos)
|
||||
|
||||
proc dial*(
|
||||
s: Switch,
|
||||
peerId: PeerID,
|
||||
peerId: PeerId,
|
||||
addrs: seq[MultiAddress],
|
||||
proto: string): Future[Connection] =
|
||||
dial(s, peerId, addrs, @[proto])
|
||||
|
@ -211,9 +212,9 @@ proc stop*(s: Switch) {.async.} =
|
|||
# close and cleanup all connections
|
||||
await s.connManager.close()
|
||||
|
||||
for t in s.transports:
|
||||
for transp in s.transports:
|
||||
try:
|
||||
await t.stop()
|
||||
await transp.stop()
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
|
@ -233,33 +234,42 @@ proc stop*(s: Switch) {.async.} =
|
|||
|
||||
trace "Switch stopped"
|
||||
|
||||
proc start*(s: Switch): Future[seq[Future[void]]] {.async, gcsafe.} =
|
||||
proc start*(s: Switch) {.async, gcsafe.} =
|
||||
trace "starting switch for peer", peerInfo = s.peerInfo
|
||||
var startFuts: seq[Future[void]]
|
||||
for t in s.transports:
|
||||
let addrs = s.peerInfo.addrs.filterIt(
|
||||
t.handles(it)
|
||||
)
|
||||
|
||||
s.peerInfo.addrs.keepItIf(
|
||||
it notin addrs
|
||||
)
|
||||
|
||||
if addrs.len > 0:
|
||||
startFuts.add(t.start(addrs))
|
||||
|
||||
await allFutures(startFuts)
|
||||
|
||||
for s in startFuts:
|
||||
if s.failed:
|
||||
# TODO: replace this exception with a `listenError` callback. See
|
||||
# https://github.com/status-im/nim-libp2p/pull/662 for more info.
|
||||
raise newException(transport.TransportError,
|
||||
"Failed to start one transport", s.error)
|
||||
|
||||
for t in s.transports: # for each transport
|
||||
for i, a in s.peerInfo.addrs:
|
||||
if t.handles(a): # check if it handles the multiaddr
|
||||
let transpStart = t.start(a)
|
||||
startFuts.add(transpStart)
|
||||
try:
|
||||
await transpStart
|
||||
s.peerInfo.addrs[i] = t.ma # update peer's address
|
||||
s.acceptFuts.add(s.accept(t))
|
||||
except CancelledError as exc:
|
||||
await s.stop()
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
debug "Failed to start one transport", address = $a, err = exc.msg
|
||||
continue
|
||||
if t.addrs.len > 0:
|
||||
s.acceptFuts.add(s.accept(t))
|
||||
s.peerInfo.addrs &= t.addrs
|
||||
|
||||
debug "Started libp2p node", peer = s.peerInfo
|
||||
return startFuts # listen for incoming connections
|
||||
|
||||
proc newSwitch*(peerInfo: PeerInfo,
|
||||
transports: seq[Transport],
|
||||
identity: Identify,
|
||||
muxers: Table[string, MuxerProvider],
|
||||
secureManagers: openarray[Secure] = [],
|
||||
secureManagers: openArray[Secure] = [],
|
||||
connManager: ConnManager,
|
||||
ms: MultistreamSelect,
|
||||
nameResolver: NameResolver = nil): Switch
|
||||
|
|
|
@ -32,9 +32,10 @@ const
|
|||
|
||||
type
|
||||
TcpTransport* = ref object of Transport
|
||||
server*: StreamServer
|
||||
servers*: seq[StreamServer]
|
||||
clients: array[Direction, seq[StreamTransport]]
|
||||
flags: set[ServerFlags]
|
||||
acceptFuts: seq[Future[StreamTransport]]
|
||||
|
||||
TcpTransportTracker* = ref object of TrackerBase
|
||||
opened*: uint64
|
||||
|
@ -121,34 +122,42 @@ proc new*(
|
|||
|
||||
let transport = T(
|
||||
flags: flags,
|
||||
upgrader: upgrade
|
||||
)
|
||||
upgrader: upgrade)
|
||||
|
||||
inc getTcpTransportTracker().opened
|
||||
return transport
|
||||
|
||||
method start*(
|
||||
self: TcpTransport,
|
||||
ma: MultiAddress) {.async.} =
|
||||
addrs: seq[MultiAddress]) {.async.} =
|
||||
## listen on the transport
|
||||
##
|
||||
|
||||
if self.running:
|
||||
trace "TCP transport already running"
|
||||
warn "TCP transport already running"
|
||||
return
|
||||
|
||||
await procCall Transport(self).start(ma)
|
||||
await procCall Transport(self).start(addrs)
|
||||
trace "Starting TCP transport"
|
||||
|
||||
self.server = createStreamServer(
|
||||
ma = self.ma,
|
||||
flags = self.flags,
|
||||
udata = self)
|
||||
for i, ma in addrs:
|
||||
if not self.handles(ma):
|
||||
trace "Invalid address detected, skipping!", address = ma
|
||||
continue
|
||||
|
||||
# always get the resolved address in case we're bound to 0.0.0.0:0
|
||||
self.ma = MultiAddress.init(self.server.sock.getLocalAddress()).tryGet()
|
||||
let server = createStreamServer(
|
||||
ma = ma,
|
||||
flags = self.flags,
|
||||
udata = self)
|
||||
|
||||
trace "Listening on", address = self.ma
|
||||
# always get the resolved address in case we're bound to 0.0.0.0:0
|
||||
self.addrs[i] = MultiAddress.init(
|
||||
server.sock.getLocalAddress()
|
||||
).tryGet()
|
||||
|
||||
self.servers &= server
|
||||
|
||||
trace "Listening on", address = ma
|
||||
|
||||
method stop*(self: TcpTransport) {.async, gcsafe.} =
|
||||
## stop the transport
|
||||
|
@ -163,11 +172,21 @@ method stop*(self: TcpTransport) {.async, gcsafe.} =
|
|||
self.clients[Direction.In].mapIt(it.closeWait()) &
|
||||
self.clients[Direction.Out].mapIt(it.closeWait())))
|
||||
|
||||
# server can be nil
|
||||
if not isNil(self.server):
|
||||
await self.server.closeWait()
|
||||
var toWait: seq[Future[void]]
|
||||
for fut in self.acceptFuts:
|
||||
if not fut.finished:
|
||||
toWait.add(fut.cancelAndWait())
|
||||
elif fut.done:
|
||||
toWait.add(fut.read().closeWait())
|
||||
|
||||
for server in self.servers:
|
||||
server.stop()
|
||||
toWait.add(server.closeWait())
|
||||
|
||||
await allFutures(toWait)
|
||||
|
||||
self.servers = @[]
|
||||
|
||||
self.server = nil
|
||||
trace "Transport stopped"
|
||||
inc getTcpTransportTracker().closed
|
||||
except CatchableError as exc:
|
||||
|
@ -181,7 +200,19 @@ method accept*(self: TcpTransport): Future[Connection] {.async, gcsafe.} =
|
|||
raise newTransportClosedError()
|
||||
|
||||
try:
|
||||
let transp = await self.server.accept()
|
||||
if self.acceptFuts.len <= 0:
|
||||
self.acceptFuts = self.servers.mapIt(it.accept())
|
||||
|
||||
if self.acceptFuts.len <= 0:
|
||||
return
|
||||
|
||||
let
|
||||
finished = await one(self.acceptFuts)
|
||||
index = self.acceptFuts.find(finished)
|
||||
|
||||
self.acceptFuts[index] = self.servers[index].accept()
|
||||
|
||||
let transp = await finished
|
||||
return await self.connHandler(transp, Direction.In)
|
||||
except TransportOsError as exc:
|
||||
# TODO: it doesn't sound like all OS errors
|
||||
|
@ -193,6 +224,8 @@ method accept*(self: TcpTransport): Future[Connection] {.async, gcsafe.} =
|
|||
except TransportUseClosedError as exc:
|
||||
debug "Server was closed", exc = exc.msg
|
||||
raise newTransportClosedError(exc)
|
||||
except CancelledError as exc:
|
||||
raise
|
||||
except CatchableError as exc:
|
||||
debug "Unexpected error accepting connection", exc = exc.msg
|
||||
raise exc
|
||||
|
@ -207,7 +240,11 @@ method dial*(
|
|||
trace "Dialing remote peer", address = $address
|
||||
|
||||
let transp = await connect(address)
|
||||
return await self.connHandler(transp, Direction.Out)
|
||||
try:
|
||||
return await self.connHandler(transp, Direction.Out)
|
||||
except CatchableError as err:
|
||||
await transp.closeWait()
|
||||
raise err
|
||||
|
||||
method handles*(t: TcpTransport, address: MultiAddress): bool {.gcsafe.} =
|
||||
if procCall Transport(t).handles(address):
|
||||
|
|
|
@ -22,10 +22,11 @@ logScope:
|
|||
|
||||
type
|
||||
TransportError* = object of LPError
|
||||
TransportInvalidAddrError* = object of TransportError
|
||||
TransportClosedError* = object of TransportError
|
||||
|
||||
Transport* = ref object of RootObj
|
||||
ma*: Multiaddress
|
||||
addrs*: seq[MultiAddress]
|
||||
running*: bool
|
||||
upgrader*: Upgrade
|
||||
|
||||
|
@ -35,20 +36,20 @@ proc newTransportClosedError*(parent: ref Exception = nil): ref LPError =
|
|||
|
||||
method start*(
|
||||
self: Transport,
|
||||
ma: MultiAddress): Future[void] {.base, async.} =
|
||||
addrs: seq[MultiAddress]) {.base, async.} =
|
||||
## start the transport
|
||||
##
|
||||
|
||||
trace "starting transport", address = $ma
|
||||
self.ma = ma
|
||||
trace "starting transport on addrs", address = $addrs
|
||||
self.addrs = addrs
|
||||
self.running = true
|
||||
|
||||
method stop*(self: Transport): Future[void] {.base, async.} =
|
||||
method stop*(self: Transport) {.base, async.} =
|
||||
## stop and cleanup the transport
|
||||
## including all outstanding connections
|
||||
##
|
||||
|
||||
trace "stopping transport", address = $self.ma
|
||||
trace "stopping transport", address = $self.addrs
|
||||
self.running = false
|
||||
|
||||
method accept*(self: Transport): Future[Connection]
|
||||
|
|
|
@ -72,10 +72,12 @@ method closeImpl*(s: WsStream): Future[void] {.async.} =
|
|||
|
||||
type
|
||||
WsTransport* = ref object of Transport
|
||||
httpserver: HttpServer
|
||||
httpservers: seq[HttpServer]
|
||||
wsserver: WSServer
|
||||
connections: array[Direction, seq[WsStream]]
|
||||
|
||||
acceptFuts: seq[Future[HttpRequest]]
|
||||
|
||||
tlsPrivateKey: TLSPrivateKey
|
||||
tlsCertificate: TLSCertificate
|
||||
tlsFlags: set[TLSFlags]
|
||||
|
@ -88,42 +90,55 @@ proc secure*(self: WsTransport): bool =
|
|||
|
||||
method start*(
|
||||
self: WsTransport,
|
||||
ma: MultiAddress) {.async.} =
|
||||
addrs: seq[MultiAddress]) {.async.} =
|
||||
## listen on the transport
|
||||
##
|
||||
|
||||
if self.running:
|
||||
trace "WS transport already running"
|
||||
warn "WS transport already running"
|
||||
return
|
||||
|
||||
await procCall Transport(self).start(ma)
|
||||
await procCall Transport(self).start(addrs)
|
||||
trace "Starting WS transport"
|
||||
|
||||
self.httpserver =
|
||||
if self.secure:
|
||||
TlsHttpServer.create(
|
||||
address = self.ma.initTAddress().tryGet(),
|
||||
tlsPrivateKey = self.tlsPrivateKey,
|
||||
tlsCertificate = self.tlsCertificate,
|
||||
flags = self.flags)
|
||||
else:
|
||||
HttpServer.create(self.ma.initTAddress().tryGet())
|
||||
|
||||
self.wsserver = WSServer.new(
|
||||
factories = self.factories,
|
||||
rng = self.rng)
|
||||
|
||||
let codec = if self.secure:
|
||||
MultiAddress.init("/wss")
|
||||
else:
|
||||
MultiAddress.init("/ws")
|
||||
|
||||
for i, ma in addrs:
|
||||
let isWss =
|
||||
if WSS.match(ma):
|
||||
if self.secure: true
|
||||
else:
|
||||
warn "Trying to listen on a WSS address without setting the certificate!"
|
||||
false
|
||||
else: false
|
||||
|
||||
# always get the resolved address in case we're bound to 0.0.0.0:0
|
||||
self.ma = MultiAddress.init(
|
||||
self.httpserver.localAddress()).tryGet() & codec.tryGet()
|
||||
let httpserver =
|
||||
if isWss:
|
||||
TlsHttpServer.create(
|
||||
address = ma.initTAddress().tryGet(),
|
||||
tlsPrivateKey = self.tlsPrivateKey,
|
||||
tlsCertificate = self.tlsCertificate,
|
||||
flags = self.flags)
|
||||
else:
|
||||
HttpServer.create(ma.initTAddress().tryGet())
|
||||
|
||||
self.httpservers &= httpserver
|
||||
|
||||
let codec = if isWss:
|
||||
MultiAddress.init("/wss")
|
||||
else:
|
||||
MultiAddress.init("/ws")
|
||||
|
||||
# always get the resolved address in case we're bound to 0.0.0.0:0
|
||||
self.addrs[i] = MultiAddress.init(
|
||||
httpserver.localAddress()).tryGet() & codec.tryGet()
|
||||
|
||||
trace "Listening on", addresses = self.addrs
|
||||
|
||||
self.running = true
|
||||
trace "Listening on", address = self.ma
|
||||
|
||||
method stop*(self: WsTransport) {.async, gcsafe.} =
|
||||
## stop the transport
|
||||
|
@ -140,24 +155,33 @@ method stop*(self: WsTransport) {.async, gcsafe.} =
|
|||
self.connections[Direction.In].mapIt(it.close()) &
|
||||
self.connections[Direction.Out].mapIt(it.close())))
|
||||
|
||||
# server can be nil
|
||||
if not isNil(self.httpserver):
|
||||
self.httpserver.stop()
|
||||
await self.httpserver.closeWait()
|
||||
var toWait: seq[Future[void]]
|
||||
for fut in self.acceptFuts:
|
||||
if not fut.finished:
|
||||
toWait.add(fut.cancelAndWait())
|
||||
elif fut.done:
|
||||
toWait.add(fut.read().stream.closeWait())
|
||||
|
||||
self.httpserver = nil
|
||||
for server in self.httpservers:
|
||||
server.stop()
|
||||
toWait.add(server.closeWait())
|
||||
|
||||
await allFutures(toWait)
|
||||
|
||||
self.httpservers = @[]
|
||||
trace "Transport stopped"
|
||||
except CatchableError as exc:
|
||||
trace "Error shutting down ws transport", exc = exc.msg
|
||||
|
||||
proc connHandler(self: WsTransport,
|
||||
stream: WsSession,
|
||||
stream: WSSession,
|
||||
secure: bool,
|
||||
dir: Direction): Future[Connection] {.async.} =
|
||||
let observedAddr =
|
||||
try:
|
||||
let
|
||||
codec =
|
||||
if self.secure:
|
||||
if secure:
|
||||
MultiAddress.init("/wss")
|
||||
else:
|
||||
MultiAddress.init("/ws")
|
||||
|
@ -189,18 +213,43 @@ method accept*(self: WsTransport): Future[Connection] {.async, gcsafe.} =
|
|||
raise newTransportClosedError()
|
||||
|
||||
try:
|
||||
let
|
||||
req = await self.httpserver.accept()
|
||||
wstransp = await self.wsserver.handleRequest(req)
|
||||
if self.acceptFuts.len <= 0:
|
||||
self.acceptFuts = self.httpservers.mapIt(it.accept())
|
||||
|
||||
return await self.connHandler(wstransp, Direction.In)
|
||||
if self.acceptFuts.len <= 0:
|
||||
return
|
||||
|
||||
let
|
||||
finished = await one(self.acceptFuts)
|
||||
index = self.acceptFuts.find(finished)
|
||||
|
||||
self.acceptFuts[index] = self.httpservers[index].accept()
|
||||
|
||||
let req = await finished
|
||||
|
||||
try:
|
||||
let
|
||||
wstransp = await self.wsserver.handleRequest(req)
|
||||
isSecure = self.httpservers[index].secure
|
||||
|
||||
return await self.connHandler(wstransp, isSecure, Direction.In)
|
||||
except CatchableError as exc:
|
||||
await req.stream.closeWait()
|
||||
raise exc
|
||||
except TransportOsError as exc:
|
||||
debug "OS Error", exc = exc.msg
|
||||
except WebSocketError as exc:
|
||||
debug "Websocket Error", exc = exc.msg
|
||||
except AsyncStreamError as exc:
|
||||
debug "AsyncStream Error", exc = exc.msg
|
||||
except TransportTooManyError as exc:
|
||||
debug "Too many files opened", exc = exc.msg
|
||||
except TransportUseClosedError as exc:
|
||||
debug "Server was closed", exc = exc.msg
|
||||
raise newTransportClosedError(exc)
|
||||
except CancelledError as exc:
|
||||
# bubble up silently
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
warn "Unexpected error accepting connection", exc = exc.msg
|
||||
raise exc
|
||||
|
@ -223,7 +272,11 @@ method dial*(
|
|||
hostName = hostname,
|
||||
flags = self.tlsFlags)
|
||||
|
||||
return await self.connHandler(transp, Direction.Out)
|
||||
try:
|
||||
return await self.connHandler(transp, secure, Direction.Out)
|
||||
except CatchableError as exc:
|
||||
await transp.close()
|
||||
raise exc
|
||||
|
||||
method handles*(t: WsTransport, address: MultiAddress): bool {.gcsafe.} =
|
||||
if procCall Transport(t).handles(address):
|
||||
|
|
|
@ -198,7 +198,7 @@ proc new*(
|
|||
T: type MuxedUpgrade,
|
||||
identity: Identify,
|
||||
muxers: Table[string, MuxerProvider],
|
||||
secureManagers: openarray[Secure] = [],
|
||||
secureManagers: openArray[Secure] = [],
|
||||
connManager: ConnManager,
|
||||
ms: MultistreamSelect): T =
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ proc identify*(
|
|||
info = await self.identity.identify(conn, conn.peerId)
|
||||
peerStore = self.connManager.peerStore
|
||||
|
||||
if info.pubKey.isNone and isNil(conn):
|
||||
if info.pubkey.isNone and isNil(conn):
|
||||
raise newException(UpgradeFailedError,
|
||||
"no public key provided and no existing peer identity found")
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import stew/byteutils
|
|||
const
|
||||
ShortDumpMax = 12
|
||||
|
||||
func shortLog*(item: openarray[byte]): string =
|
||||
func shortLog*(item: openArray[byte]): string =
|
||||
if item.len <= ShortDumpMax:
|
||||
result = item.toHex()
|
||||
else:
|
||||
|
|
|
@ -103,7 +103,7 @@ proc vsizeof*(x: SomeVarint): int {.inline.} =
|
|||
Leb128.len(toUleb(x))
|
||||
|
||||
proc getUVarint*[T: PB|LP](vtype: typedesc[T],
|
||||
pbytes: openarray[byte],
|
||||
pbytes: openArray[byte],
|
||||
outlen: var int,
|
||||
outval: var SomeUVarint): VarintResult[void] =
|
||||
## Decode `unsigned varint` from buffer ``pbytes`` and store it to ``outval``.
|
||||
|
@ -149,7 +149,7 @@ proc getUVarint*[T: PB|LP](vtype: typedesc[T],
|
|||
ok()
|
||||
|
||||
proc putUVarint*[T: PB|LP](vtype: typedesc[T],
|
||||
pbytes: var openarray[byte],
|
||||
pbytes: var openArray[byte],
|
||||
outlen: var int,
|
||||
outval: SomeUVarint): VarintResult[void] =
|
||||
## Encode `unsigned varint` ``outval`` and store it to array ``pbytes``.
|
||||
|
@ -180,7 +180,7 @@ proc putUVarint*[T: PB|LP](vtype: typedesc[T],
|
|||
else:
|
||||
err(VarintError.Overrun)
|
||||
|
||||
proc getSVarint*(pbytes: openarray[byte], outsize: var int,
|
||||
proc getSVarint*(pbytes: openArray[byte], outsize: var int,
|
||||
outval: var (PBZigVarint | PBSomeSVarint)): VarintResult[void] {.inline.} =
|
||||
## Decode signed integer (``int32`` or ``int64``) from buffer ``pbytes``
|
||||
## and store it to ``outval``.
|
||||
|
@ -210,7 +210,7 @@ proc getSVarint*(pbytes: openarray[byte], outsize: var int,
|
|||
outval = fromUleb(value, type(outval))
|
||||
res
|
||||
|
||||
proc putSVarint*(pbytes: var openarray[byte], outsize: var int,
|
||||
proc putSVarint*(pbytes: var openArray[byte], outsize: var int,
|
||||
outval: (PBZigVarint | PBSomeSVarint)): VarintResult[void] {.inline.} =
|
||||
## Encode signed integer ``outval`` using ProtoBuffer's zigzag encoding
|
||||
## (``sint32`` or ``sint64``) and store it to array ``pbytes``.
|
||||
|
@ -230,7 +230,7 @@ template varintFatal(msg) =
|
|||
const m = msg
|
||||
{.fatal: m.}
|
||||
|
||||
proc putVarint*[T: PB|LP](vtype: typedesc[T], pbytes: var openarray[byte],
|
||||
proc putVarint*[T: PB|LP](vtype: typedesc[T], pbytes: var openArray[byte],
|
||||
nbytes: var int, value: SomeVarint): VarintResult[void] {.inline.} =
|
||||
when vtype is PB:
|
||||
when (type(value) is PBSomeSVarint) or (type(value) is PBZigVarint):
|
||||
|
@ -247,7 +247,7 @@ proc putVarint*[T: PB|LP](vtype: typedesc[T], pbytes: var openarray[byte],
|
|||
varintFatal("LibP2P's varint do not support type [" &
|
||||
typetraits.name(type(value)) & "]")
|
||||
|
||||
proc getVarint*[T: PB|LP](vtype: typedesc[T], pbytes: openarray[byte],
|
||||
proc getVarint*[T: PB|LP](vtype: typedesc[T], pbytes: openArray[byte],
|
||||
nbytes: var int,
|
||||
value: var SomeVarint): VarintResult[void] {.inline.} =
|
||||
when vtype is PB:
|
||||
|
|
|
@ -53,7 +53,7 @@ proc initVBuffer*(data: seq[byte], offset = 0): VBuffer =
|
|||
shallowCopy(result.buffer, data)
|
||||
result.offset = offset
|
||||
|
||||
proc initVBuffer*(data: openarray[byte], offset = 0): VBuffer =
|
||||
proc initVBuffer*(data: openArray[byte], offset = 0): VBuffer =
|
||||
## Initialize VBuffer with copy of ``data``.
|
||||
result.buffer = newSeq[byte](len(data))
|
||||
if len(data) > 0:
|
||||
|
@ -88,7 +88,7 @@ proc writeLPVarint*(vb: var VBuffer, value: LPSomeUVarint) =
|
|||
proc writeVarint*(vb: var VBuffer, value: LPSomeUVarint) =
|
||||
writeLPVarint(vb, value)
|
||||
|
||||
proc writeSeq*[T: byte|char](vb: var VBuffer, value: openarray[T]) =
|
||||
proc writeSeq*[T: byte|char](vb: var VBuffer, value: openArray[T]) =
|
||||
## Write array ``value`` to buffer ``vb``, value will be prefixed with
|
||||
## varint length of the array.
|
||||
var length = 0
|
||||
|
@ -101,7 +101,7 @@ proc writeSeq*[T: byte|char](vb: var VBuffer, value: openarray[T]) =
|
|||
copyMem(addr vb.buffer[vb.offset], unsafeAddr value[0], len(value))
|
||||
vb.offset += len(value)
|
||||
|
||||
proc writeArray*[T: byte|char](vb: var VBuffer, value: openarray[T]) =
|
||||
proc writeArray*[T: byte|char](vb: var VBuffer, value: openArray[T]) =
|
||||
## Write array ``value`` to buffer ``vb``, value will NOT be prefixed with
|
||||
## varint length of the array.
|
||||
if len(value) > 0:
|
||||
|
@ -151,7 +151,7 @@ proc peekSeq*[T: string|seq[byte]](vb: var VBuffer, value: var T): int =
|
|||
vb.offset -= length
|
||||
|
||||
proc peekArray*[T: char|byte](vb: var VBuffer,
|
||||
value: var openarray[T]): int =
|
||||
value: var openArray[T]): int =
|
||||
## Peek array from buffer ``vb`` and store result to ``value``.
|
||||
##
|
||||
## This procedure will not adjust internal offset.
|
||||
|
@ -183,7 +183,7 @@ proc readSeq*[T: string|seq[byte]](vb: var VBuffer,
|
|||
vb.offset += result
|
||||
|
||||
proc readArray*[T: char|byte](vb: var VBuffer,
|
||||
value: var openarray[T]): int {.inline.} =
|
||||
value: var openArray[T]): int {.inline.} =
|
||||
## Read array from buffer ``vb`` and store result to ``value``.
|
||||
##
|
||||
## Returns number of bytes consumed from ``vb`` or ``-1`` on error.
|
||||
|
|
|
@ -19,14 +19,14 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
checkTrackers()
|
||||
|
||||
asyncTest "can handle local address":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
check transport1.handles(transport1.ma)
|
||||
check transport1.handles(transport1.addrs[0])
|
||||
await transport1.stop()
|
||||
|
||||
asyncTest "e2e: handle observedAddr":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
@ -40,7 +40,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
|
||||
let handlerWait = acceptHandler()
|
||||
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
check transport2.handles(conn.observedAddr)
|
||||
|
||||
|
@ -54,7 +54,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
await handlerWait.wait(1.seconds) # when no issues will not wait that long!
|
||||
|
||||
asyncTest "e2e: handle write":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
@ -67,7 +67,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
let handlerWait = acceptHandler()
|
||||
|
||||
let transport2 = prov()
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
var msg = newSeq[byte](6)
|
||||
await conn.readExactly(addr msg[0], 6)
|
||||
|
||||
|
@ -82,7 +82,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
await handlerWait.wait(1.seconds) # when no issues will not wait that long!
|
||||
|
||||
asyncTest "e2e: handle read":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
||||
|
@ -96,7 +96,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
let handlerWait = acceptHandler()
|
||||
|
||||
let transport2 = prov()
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
await conn.write("Hello!")
|
||||
|
||||
await conn.close() #for some protocols, closing requires actively reading, so we must close here
|
||||
|
@ -108,13 +108,13 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
transport2.stop()))
|
||||
|
||||
asyncTest "e2e: handle dial cancellation":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
||||
let transport2 = prov()
|
||||
let cancellation = transport2.dial(transport1.ma)
|
||||
let cancellation = transport2.dial(transport1.addrs[0])
|
||||
|
||||
await cancellation.cancelAndWait()
|
||||
check cancellation.cancelled
|
||||
|
@ -125,7 +125,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
transport2.stop()))
|
||||
|
||||
asyncTest "e2e: handle accept cancellation":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
@ -136,8 +136,57 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
|
||||
await transport1.stop()
|
||||
|
||||
asyncTest "e2e should allow multiple local addresses":
|
||||
let addrs = @[MultiAddress.init(ma).tryGet(),
|
||||
MultiAddress.init(ma).tryGet()]
|
||||
|
||||
|
||||
let transport1 = prov()
|
||||
await transport1.start(addrs)
|
||||
|
||||
proc acceptHandler() {.async, gcsafe.} =
|
||||
while true:
|
||||
let conn = await transport1.accept()
|
||||
await conn.write("Hello!")
|
||||
await conn.close()
|
||||
|
||||
let handlerWait = acceptHandler()
|
||||
|
||||
check transport1.addrs.len == 2
|
||||
check transport1.addrs[0] != transport1.addrs[1]
|
||||
|
||||
var msg = newSeq[byte](6)
|
||||
|
||||
proc client(ma: MultiAddress) {.async.} =
|
||||
let conn1 = await transport1.dial(ma)
|
||||
await conn1.readExactly(addr msg[0], 6)
|
||||
check string.fromBytes(msg) == "Hello!"
|
||||
await conn1.close()
|
||||
|
||||
#Dial the same server multiple time in a row
|
||||
await client(transport1.addrs[0])
|
||||
await client(transport1.addrs[0])
|
||||
await client(transport1.addrs[0])
|
||||
|
||||
#Dial the same server on different addresses
|
||||
await client(transport1.addrs[1])
|
||||
await client(transport1.addrs[0])
|
||||
await client(transport1.addrs[1])
|
||||
|
||||
#Cancel a dial
|
||||
#TODO add back once chronos fixes cancellation
|
||||
#let
|
||||
# dial1 = transport1.dial(transport1.addrs[1])
|
||||
# dial2 = transport1.dial(transport1.addrs[0])
|
||||
#await dial1.cancelAndWait()
|
||||
#await dial2.cancelAndWait()
|
||||
|
||||
await handlerWait.cancelAndWait()
|
||||
|
||||
await transport1.stop()
|
||||
|
||||
asyncTest "e2e: stopping transport kills connections":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
@ -145,7 +194,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
let transport2 = prov()
|
||||
|
||||
let acceptHandler = transport1.accept()
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
let serverConn = await acceptHandler
|
||||
|
||||
await allFuturesThrowing(
|
||||
|
@ -157,7 +206,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
check conn.closed()
|
||||
|
||||
asyncTest "read or write on closed connection":
|
||||
let ma: MultiAddress = Multiaddress.init(ma).tryGet()
|
||||
let ma = @[MultiAddress.init(ma).tryGet()]
|
||||
let transport1 = prov()
|
||||
await transport1.start(ma)
|
||||
|
||||
|
@ -167,7 +216,7 @@ proc commonTransportTest*(name: string, prov: TransportProvider, ma: string) =
|
|||
|
||||
let handlerWait = acceptHandler()
|
||||
|
||||
let conn = await transport1.dial(transport1.ma)
|
||||
let conn = await transport1.dial(transport1.addrs[0])
|
||||
|
||||
var msg = newSeq[byte](6)
|
||||
try:
|
||||
|
|
|
@ -29,7 +29,7 @@ proc waitSub(sender, receiver: auto; key: string) {.async, gcsafe.} =
|
|||
var ceil = 15
|
||||
let fsub = cast[FloodSub](sender)
|
||||
while not fsub.floodsub.hasKey(key) or
|
||||
not fsub.floodsub.hasPeerID(key, receiver.peerInfo.peerId):
|
||||
not fsub.floodsub.hasPeerId(key, receiver.peerInfo.peerId):
|
||||
await sleepAsync(100.millis)
|
||||
dec ceil
|
||||
doAssert(ceil > 0, "waitSub timeout!")
|
||||
|
|
|
@ -18,7 +18,7 @@ type
|
|||
|
||||
proc noop(data: seq[byte]) {.async, gcsafe.} = discard
|
||||
|
||||
proc getPubSubPeer(p: TestGossipSub, peerId: PeerID): PubSubPeer =
|
||||
proc getPubSubPeer(p: TestGossipSub, peerId: PeerId): PubSubPeer =
|
||||
proc getConn(): Future[Connection] =
|
||||
p.switch.dial(peerId, GossipSubCodec)
|
||||
|
||||
|
@ -317,8 +317,8 @@ suite "GossipSub internal":
|
|||
let peers = gossipSub.getGossipPeers()
|
||||
check peers.len == gossipSub.parameters.d
|
||||
for p in peers.keys:
|
||||
check not gossipSub.fanout.hasPeerID(topic, p.peerId)
|
||||
check not gossipSub.mesh.hasPeerID(topic, p.peerId)
|
||||
check not gossipSub.fanout.hasPeerId(topic, p.peerId)
|
||||
check not gossipSub.mesh.hasPeerId(topic, p.peerId)
|
||||
|
||||
await allFuturesThrowing(conns.mapIt(it.close()))
|
||||
await gossipSub.switch.stop()
|
||||
|
@ -552,7 +552,7 @@ suite "GossipSub internal":
|
|||
peer.sendConn = conn
|
||||
gossipSub.gossipsub[topic].incl(peer)
|
||||
gossipSub.backingOff
|
||||
.mgetOrPut(topic, initTable[PeerID, Moment]())
|
||||
.mgetOrPut(topic, initTable[PeerId, Moment]())
|
||||
.add(peerId, Moment.now() + 1.hours)
|
||||
let prunes = gossipSub.handleGraft(peer, @[ControlGraft(topicID: topic)])
|
||||
# there must be a control prune due to violation of backoff
|
||||
|
|
|
@ -44,11 +44,11 @@ proc waitSub(sender, receiver: auto; key: string) {.async, gcsafe.} =
|
|||
ev.clear()
|
||||
|
||||
while (not fsub.gossipsub.hasKey(key) or
|
||||
not fsub.gossipsub.hasPeerID(key, receiver.peerInfo.peerId)) and
|
||||
not fsub.gossipsub.hasPeerId(key, receiver.peerInfo.peerId)) and
|
||||
(not fsub.mesh.hasKey(key) or
|
||||
not fsub.mesh.hasPeerID(key, receiver.peerInfo.peerId)) and
|
||||
not fsub.mesh.hasPeerId(key, receiver.peerInfo.peerId)) and
|
||||
(not fsub.fanout.hasKey(key) or
|
||||
not fsub.fanout.hasPeerID(key , receiver.peerInfo.peerId)):
|
||||
not fsub.fanout.hasPeerId(key , receiver.peerInfo.peerId)):
|
||||
trace "waitSub sleeping..."
|
||||
|
||||
# await more heartbeats
|
||||
|
@ -320,6 +320,70 @@ suite "GossipSub":
|
|||
|
||||
await allFuturesThrowing(nodesFut.concat())
|
||||
|
||||
asyncTest "GossipSub unsub - resub faster than backoff":
|
||||
var handlerFut = newFuture[bool]()
|
||||
proc handler(topic: string, data: seq[byte]) {.async, gcsafe.} =
|
||||
check topic == "foobar"
|
||||
handlerFut.complete(true)
|
||||
|
||||
let
|
||||
nodes = generateNodes(2, gossip = true)
|
||||
|
||||
# start switches
|
||||
nodesFut = await allFinished(
|
||||
nodes[0].switch.start(),
|
||||
nodes[1].switch.start(),
|
||||
)
|
||||
|
||||
# start pubsub
|
||||
await allFuturesThrowing(
|
||||
allFinished(
|
||||
nodes[0].start(),
|
||||
nodes[1].start(),
|
||||
))
|
||||
|
||||
await subscribeNodes(nodes)
|
||||
|
||||
nodes[0].subscribe("foobar", handler)
|
||||
nodes[1].subscribe("foobar", handler)
|
||||
|
||||
var subs: seq[Future[void]]
|
||||
subs &= waitSub(nodes[1], nodes[0], "foobar")
|
||||
subs &= waitSub(nodes[0], nodes[1], "foobar")
|
||||
|
||||
await allFuturesThrowing(subs)
|
||||
|
||||
nodes[0].unsubscribe("foobar", handler)
|
||||
nodes[0].subscribe("foobar", handler)
|
||||
|
||||
# regular backoff is 60 seconds, so we must not wait that long
|
||||
await (waitSub(nodes[0], nodes[1], "foobar") and waitSub(nodes[1], nodes[0], "foobar")).wait(30.seconds)
|
||||
|
||||
var validatorFut = newFuture[bool]()
|
||||
proc validator(topic: string,
|
||||
message: Message):
|
||||
Future[ValidationResult] {.async.} =
|
||||
check topic == "foobar"
|
||||
validatorFut.complete(true)
|
||||
result = ValidationResult.Accept
|
||||
|
||||
nodes[1].addValidator("foobar", validator)
|
||||
tryPublish await nodes[0].publish("foobar", "Hello!".toBytes()), 1
|
||||
|
||||
check (await validatorFut) and (await handlerFut)
|
||||
|
||||
await allFuturesThrowing(
|
||||
nodes[0].switch.stop(),
|
||||
nodes[1].switch.stop()
|
||||
)
|
||||
|
||||
await allFuturesThrowing(
|
||||
nodes[0].stop(),
|
||||
nodes[1].stop()
|
||||
)
|
||||
|
||||
await allFuturesThrowing(nodesFut.concat())
|
||||
|
||||
asyncTest "e2e - GossipSub should add remote peer topic subscriptions":
|
||||
proc handler(topic: string, data: seq[byte]) {.async, gcsafe.} =
|
||||
discard
|
||||
|
@ -353,7 +417,7 @@ suite "GossipSub":
|
|||
check:
|
||||
"foobar" in gossip2.topics
|
||||
"foobar" in gossip1.gossipsub
|
||||
gossip1.gossipsub.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
gossip1.gossipsub.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
|
||||
await allFuturesThrowing(
|
||||
nodes[0].switch.stop(),
|
||||
|
@ -411,11 +475,11 @@ suite "GossipSub":
|
|||
"foobar" in gossip1.gossipsub
|
||||
"foobar" in gossip2.gossipsub
|
||||
|
||||
gossip1.gossipsub.hasPeerID("foobar", gossip2.peerInfo.peerId) or
|
||||
gossip1.mesh.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
gossip1.gossipsub.hasPeerId("foobar", gossip2.peerInfo.peerId) or
|
||||
gossip1.mesh.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
|
||||
gossip2.gossipsub.hasPeerID("foobar", gossip1.peerInfo.peerId) or
|
||||
gossip2.mesh.hasPeerID("foobar", gossip1.peerInfo.peerId)
|
||||
gossip2.gossipsub.hasPeerId("foobar", gossip1.peerInfo.peerId) or
|
||||
gossip2.mesh.hasPeerId("foobar", gossip1.peerInfo.peerId)
|
||||
|
||||
await allFuturesThrowing(
|
||||
nodes[0].switch.stop(),
|
||||
|
@ -477,8 +541,8 @@ suite "GossipSub":
|
|||
|
||||
check:
|
||||
"foobar" in gossip1.gossipsub
|
||||
gossip1.fanout.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.mesh.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
gossip1.fanout.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.mesh.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
|
||||
await passed.wait(2.seconds)
|
||||
|
||||
|
@ -540,10 +604,10 @@ suite "GossipSub":
|
|||
check:
|
||||
"foobar" in gossip1.gossipsub
|
||||
"foobar" in gossip2.gossipsub
|
||||
gossip1.mesh.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.fanout.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
gossip2.mesh.hasPeerID("foobar", gossip1.peerInfo.peerId)
|
||||
not gossip2.fanout.hasPeerID("foobar", gossip1.peerInfo.peerId)
|
||||
gossip1.mesh.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.fanout.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
gossip2.mesh.hasPeerId("foobar", gossip1.peerInfo.peerId)
|
||||
not gossip2.fanout.hasPeerId("foobar", gossip1.peerInfo.peerId)
|
||||
|
||||
await allFuturesThrowing(
|
||||
nodes[0].switch.stop(),
|
||||
|
@ -682,8 +746,8 @@ suite "GossipSub":
|
|||
check:
|
||||
"foobar" in gossip1.gossipsub
|
||||
"foobar" notin gossip2.gossipsub
|
||||
not gossip1.mesh.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.fanout.hasPeerID("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.mesh.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
not gossip1.fanout.hasPeerId("foobar", gossip2.peerInfo.peerId)
|
||||
|
||||
await allFuturesThrowing(
|
||||
nodes[0].switch.stop(),
|
||||
|
|
|
@ -41,11 +41,11 @@ proc waitSub(sender, receiver: auto; key: string) {.async, gcsafe.} =
|
|||
ev.clear()
|
||||
|
||||
while (not fsub.gossipsub.hasKey(key) or
|
||||
not fsub.gossipsub.hasPeerID(key, receiver.peerInfo.peerId)) and
|
||||
not fsub.gossipsub.hasPeerId(key, receiver.peerInfo.peerId)) and
|
||||
(not fsub.mesh.hasKey(key) or
|
||||
not fsub.mesh.hasPeerID(key, receiver.peerInfo.peerId)) and
|
||||
not fsub.mesh.hasPeerId(key, receiver.peerInfo.peerId)) and
|
||||
(not fsub.fanout.hasKey(key) or
|
||||
not fsub.fanout.hasPeerID(key , receiver.peerInfo.peerId)):
|
||||
not fsub.fanout.hasPeerId(key , receiver.peerInfo.peerId)):
|
||||
trace "waitSub sleeping..."
|
||||
|
||||
# await more heartbeats
|
||||
|
|
|
@ -10,13 +10,13 @@ import ../../libp2p/[peerid,
|
|||
|
||||
var rng = newRng()
|
||||
|
||||
proc randomPeerID(): PeerID =
|
||||
PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get()
|
||||
proc randomPeerId(): PeerId =
|
||||
PeerId.init(PrivateKey.random(ECDSA, rng[]).get()).get()
|
||||
|
||||
suite "MCache":
|
||||
test "put/get":
|
||||
var mCache = MCache.init(3, 5)
|
||||
var msg = Message(fromPeer: randomPeerID(), seqno: "12345".toBytes())
|
||||
var msg = Message(fromPeer: randomPeerId(), seqno: "12345".toBytes())
|
||||
let msgId = defaultMsgIdProvider(msg)
|
||||
mCache.put(msgId, msg)
|
||||
check mCache.get(msgId).isSome and mCache.get(msgId).get() == msg
|
||||
|
@ -25,13 +25,13 @@ suite "MCache":
|
|||
var mCache = MCache.init(3, 5)
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["foo"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
||||
for i in 0..<5:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["bar"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
@ -46,7 +46,7 @@ suite "MCache":
|
|||
var mCache = MCache.init(1, 5)
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["foo"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
@ -55,7 +55,7 @@ suite "MCache":
|
|||
check mCache.window("foo").len == 0
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["bar"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
@ -64,7 +64,7 @@ suite "MCache":
|
|||
check mCache.window("bar").len == 0
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["baz"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
@ -76,19 +76,19 @@ suite "MCache":
|
|||
var mCache = MCache.init(1, 5)
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["foo"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["bar"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
||||
for i in 0..<3:
|
||||
var msg = Message(fromPeer: randomPeerID(),
|
||||
var msg = Message(fromPeer: randomPeerId(),
|
||||
seqno: "12345".toBytes(),
|
||||
topicIDs: @["baz"])
|
||||
mCache.put(defaultMsgIdProvider(msg), msg)
|
||||
|
|
|
@ -18,7 +18,7 @@ randomize()
|
|||
|
||||
proc generateNodes*(
|
||||
num: Natural,
|
||||
secureManagers: openarray[SecureProtocol] = [
|
||||
secureManagers: openArray[SecureProtocol] = [
|
||||
SecureProtocol.Noise
|
||||
],
|
||||
msgIdProvider: MsgIdProvider = nil,
|
||||
|
@ -40,7 +40,7 @@ proc generateNodes*(
|
|||
msgIdProvider = msgIdProvider,
|
||||
anonymize = anonymize,
|
||||
maxMessageSize = maxMessageSize,
|
||||
parameters = (var p = GossipSubParams.init(); p.floodPublish = false; p.historyLength = 20; p.historyGossip = 20; p))
|
||||
parameters = (var p = GossipSubParams.init(); p.floodPublish = false; p.historyLength = 20; p.historyGossip = 20; p.unsubscribeBackoff = 1.seconds; p))
|
||||
# set some testing params, to enable scores
|
||||
g.topicParams.mgetOrPut("foobar", TopicParams.init()).topicWeight = 1.0
|
||||
g.topicParams.mgetOrPut("foo", TopicParams.init()).topicWeight = 1.0
|
||||
|
@ -79,7 +79,7 @@ proc subscribeSparseNodes*(nodes: seq[PubSub], degree: int = 2) {.async.} =
|
|||
|
||||
proc subscribeRandom*(nodes: seq[PubSub]) {.async.} =
|
||||
for dialer in nodes:
|
||||
var dialed: seq[PeerID]
|
||||
var dialed: seq[PeerId]
|
||||
while dialed.len < nodes.len - 1:
|
||||
let node = sample(nodes)
|
||||
if node.peerInfo.peerId notin dialed:
|
||||
|
|
|
@ -335,7 +335,7 @@ const
|
|||
"8613E8F86D2DD1CF3CEDC52AD91423F2F31E0003",
|
||||
]
|
||||
|
||||
proc cmp(a, b: openarray[byte]): bool =
|
||||
proc cmp(a, b: openArray[byte]): bool =
|
||||
result = (@a == @b)
|
||||
|
||||
proc testStretcher(s, e: int, cs: string, ds: string): bool =
|
||||
|
|
|
@ -315,6 +315,9 @@ suite "EC NIST-P256/384/521 test suite":
|
|||
rkey2 == key
|
||||
rkey3 == key
|
||||
rkey4 == key
|
||||
rkey1.key.xlen = rkey1.buffer.len + 1
|
||||
check:
|
||||
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
|
||||
|
||||
test "[secp256r1] Public key serialize/deserialize test":
|
||||
for i in 0..<TestsCount:
|
||||
|
@ -333,6 +336,9 @@ suite "EC NIST-P256/384/521 test suite":
|
|||
rkey2 == pair.pubkey
|
||||
rkey3 == pair.pubkey
|
||||
rkey4 == pair.pubkey
|
||||
rkey1.key.qlen = rkey1.buffer.len + 1
|
||||
check:
|
||||
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
|
||||
|
||||
test "[secp256r1] ECDHE test":
|
||||
for i in 0..<TestsCount:
|
||||
|
@ -422,6 +428,9 @@ suite "EC NIST-P256/384/521 test suite":
|
|||
rkey2 == key
|
||||
rkey3 == key
|
||||
rkey4 == key
|
||||
rkey1.key.xlen = rkey1.buffer.len + 1
|
||||
check:
|
||||
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
|
||||
|
||||
test "[secp384r1] Public key serialize/deserialize test":
|
||||
for i in 0..<TestsCount:
|
||||
|
@ -440,6 +449,9 @@ suite "EC NIST-P256/384/521 test suite":
|
|||
rkey2 == pair.pubkey
|
||||
rkey3 == pair.pubkey
|
||||
rkey4 == pair.pubkey
|
||||
rkey1.key.qlen = rkey1.buffer.len + 1
|
||||
check:
|
||||
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
|
||||
|
||||
test "[secp384r1] ECDHE test":
|
||||
for i in 0..<TestsCount:
|
||||
|
@ -529,6 +541,9 @@ suite "EC NIST-P256/384/521 test suite":
|
|||
rkey2 == key
|
||||
rkey3 == key
|
||||
rkey4 == key
|
||||
rkey1.key.xlen = rkey1.buffer.len + 1
|
||||
check:
|
||||
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
|
||||
|
||||
test "[secp521r1] Public key serialize/deserialize test":
|
||||
for i in 0..<TestsCount:
|
||||
|
@ -547,6 +562,9 @@ suite "EC NIST-P256/384/521 test suite":
|
|||
rkey2 == pair.pubkey
|
||||
rkey3 == pair.pubkey
|
||||
rkey4 == pair.pubkey
|
||||
rkey1.key.qlen = rkey1.buffer.len + 1
|
||||
check:
|
||||
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
|
||||
|
||||
test "[secp521r1] ECDHE test":
|
||||
for i in 0..<TestsCount:
|
||||
|
|
|
@ -22,7 +22,7 @@ suite "Identify":
|
|||
|
||||
suite "handle identify message":
|
||||
var
|
||||
ma {.threadvar.}: MultiAddress
|
||||
ma {.threadvar.}: seq[MultiAddress]
|
||||
remoteSecKey {.threadvar.}: PrivateKey
|
||||
remotePeerInfo {.threadvar.}: PeerInfo
|
||||
serverFut {.threadvar.}: Future[void]
|
||||
|
@ -36,10 +36,12 @@ suite "Identify":
|
|||
conn {.threadvar.}: Connection
|
||||
|
||||
asyncSetup:
|
||||
ma = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
remoteSecKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
remotePeerInfo = PeerInfo.new(
|
||||
remoteSecKey, [ma], ["/test/proto1/1.0.0", "/test/proto2/1.0.0"])
|
||||
remoteSecKey,
|
||||
ma,
|
||||
["/test/proto1/1.0.0", "/test/proto2/1.0.0"])
|
||||
|
||||
transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
transport2 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
@ -65,13 +67,13 @@ suite "Identify":
|
|||
await msListen.handle(c)
|
||||
|
||||
acceptFut = acceptHandler()
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
discard await msDial.select(conn, IdentifyCodec)
|
||||
let id = await identifyProto2.identify(conn, remotePeerInfo.peerId)
|
||||
|
||||
check id.pubKey.get() == remoteSecKey.getPublicKey().get()
|
||||
check id.addrs[0] == ma
|
||||
check id.pubkey.get() == remoteSecKey.getPublicKey().get()
|
||||
check id.addrs == ma
|
||||
check id.protoVersion.get() == ProtoVersion
|
||||
check id.agentVersion.get() == AgentVersion
|
||||
check id.protos == @["/test/proto1/1.0.0", "/test/proto2/1.0.0"]
|
||||
|
@ -88,13 +90,13 @@ suite "Identify":
|
|||
await msListen.handle(c)
|
||||
|
||||
acceptFut = acceptHandler()
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
discard await msDial.select(conn, IdentifyCodec)
|
||||
let id = await identifyProto2.identify(conn, remotePeerInfo.peerId)
|
||||
|
||||
check id.pubKey.get() == remoteSecKey.getPublicKey().get()
|
||||
check id.addrs[0] == ma
|
||||
check id.pubkey.get() == remoteSecKey.getPublicKey().get()
|
||||
check id.addrs == ma
|
||||
check id.protoVersion.get() == ProtoVersion
|
||||
check id.agentVersion.get() == customAgentVersion
|
||||
check id.protos == @["/test/proto1/1.0.0", "/test/proto2/1.0.0"]
|
||||
|
@ -114,7 +116,7 @@ suite "Identify":
|
|||
await conn.close()
|
||||
|
||||
acceptFut = acceptHandler()
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
expect IdentityNoMatchError:
|
||||
let pi2 = PeerInfo.new(PrivateKey.random(ECDSA, rng[]).get())
|
||||
|
@ -127,7 +129,6 @@ suite "Identify":
|
|||
switch2 {.threadvar.}: Switch
|
||||
identifyPush1 {.threadvar.}: IdentifyPush
|
||||
identifyPush2 {.threadvar.}: IdentifyPush
|
||||
awaiters {.threadvar.}: seq[Future[void]]
|
||||
conn {.threadvar.}: Connection
|
||||
asyncSetup:
|
||||
switch1 = newStandardSwitch()
|
||||
|
@ -144,10 +145,13 @@ suite "Identify":
|
|||
switch1.mount(identifyPush1)
|
||||
switch2.mount(identifyPush2)
|
||||
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, IdentifyPushCodec)
|
||||
conn = await switch2.dial(
|
||||
switch1.peerInfo.peerId,
|
||||
switch1.peerInfo.addrs,
|
||||
IdentifyPushCodec)
|
||||
|
||||
check:
|
||||
switch1.peerStore.addressBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.addrs.toHashSet()
|
||||
|
@ -162,9 +166,6 @@ suite "Identify":
|
|||
await switch1.stop()
|
||||
await switch2.stop()
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "simple push identify":
|
||||
switch2.peerInfo.protocols.add("/newprotocol/")
|
||||
switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet())
|
||||
|
@ -175,6 +176,9 @@ suite "Identify":
|
|||
|
||||
await identifyPush2.push(switch2.peerInfo, conn)
|
||||
|
||||
check await checkExpiring(switch1.peerStore.protoBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.protocols.toHashSet())
|
||||
check await checkExpiring(switch1.peerStore.addressBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.addrs.toHashSet())
|
||||
|
||||
await closeAll()
|
||||
|
||||
# Wait the very end to be sure that the push has been processed
|
||||
|
@ -196,6 +200,12 @@ suite "Identify":
|
|||
|
||||
await identifyPush2.push(switch2.peerInfo, conn)
|
||||
|
||||
# We have no way to know when the message will is received
|
||||
# because it will fail validation inside push identify itself
|
||||
#
|
||||
# So no choice but to sleep
|
||||
await sleepAsync(10.milliseconds)
|
||||
|
||||
await closeAll()
|
||||
|
||||
# Wait the very end to be sure that the push has been processed
|
||||
|
|
|
@ -54,7 +54,7 @@ proc testPubSubDaemonPublish(gossip: bool = false, count: int = 1) {.async.} =
|
|||
|
||||
nativeNode.mount(pubsub)
|
||||
|
||||
let awaiters = nativeNode.start()
|
||||
await nativeNode.start()
|
||||
await pubsub.start()
|
||||
let nativePeer = nativeNode.peerInfo
|
||||
|
||||
|
@ -90,7 +90,6 @@ proc testPubSubDaemonPublish(gossip: bool = false, count: int = 1) {.async.} =
|
|||
|
||||
await nativeNode.stop()
|
||||
await pubsub.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
|
||||
proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} =
|
||||
|
@ -115,7 +114,7 @@ proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} =
|
|||
|
||||
nativeNode.mount(pubsub)
|
||||
|
||||
let awaiters = nativeNode.start()
|
||||
await nativeNode.start()
|
||||
await pubsub.start()
|
||||
let nativePeer = nativeNode.peerInfo
|
||||
|
||||
|
@ -151,7 +150,6 @@ proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} =
|
|||
check finished
|
||||
await nativeNode.stop()
|
||||
await pubsub.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
|
||||
suite "Interop":
|
||||
|
@ -171,7 +169,7 @@ suite "Interop":
|
|||
secureManagers = [SecureProtocol.Noise],
|
||||
outTimeout = 5.minutes)
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
let daemonNode = await newDaemonApi()
|
||||
let daemonPeer = await daemonNode.identity()
|
||||
|
||||
|
@ -195,7 +193,6 @@ suite "Interop":
|
|||
|
||||
await nativeNode.stop()
|
||||
await daemonNode.close()
|
||||
await allFutures(awaiters)
|
||||
|
||||
await sleepAsync(1.seconds)
|
||||
|
||||
|
@ -215,7 +212,7 @@ suite "Interop":
|
|||
secureManagers = [SecureProtocol.Noise],
|
||||
outTimeout = 5.minutes)
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
|
||||
let daemonNode = await newDaemonApi()
|
||||
let daemonPeer = await daemonNode.identity()
|
||||
|
@ -236,7 +233,6 @@ suite "Interop":
|
|||
|
||||
await conn.close()
|
||||
await nativeNode.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
|
||||
asyncTest "daemon -> native connection":
|
||||
|
@ -260,7 +256,7 @@ suite "Interop":
|
|||
|
||||
nativeNode.mount(proto)
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
let nativePeer = nativeNode.peerInfo
|
||||
|
||||
let daemonNode = await newDaemonApi()
|
||||
|
@ -272,7 +268,6 @@ suite "Interop":
|
|||
|
||||
await stream.close()
|
||||
await nativeNode.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
await sleepAsync(1.seconds)
|
||||
|
||||
|
@ -305,7 +300,7 @@ suite "Interop":
|
|||
|
||||
nativeNode.mount(proto)
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
let nativePeer = nativeNode.peerInfo
|
||||
|
||||
let daemonNode = await newDaemonApi(hostAddresses = @[wsAddress])
|
||||
|
@ -317,7 +312,6 @@ suite "Interop":
|
|||
|
||||
await stream.close()
|
||||
await nativeNode.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
await sleepAsync(1.seconds)
|
||||
|
||||
|
@ -343,7 +337,7 @@ suite "Interop":
|
|||
.withNoise()
|
||||
.build()
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
|
||||
let daemonNode = await newDaemonApi(hostAddresses = @[wsAddress])
|
||||
let daemonPeer = await daemonNode.identity()
|
||||
|
@ -364,7 +358,6 @@ suite "Interop":
|
|||
|
||||
await conn.close()
|
||||
await nativeNode.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
|
||||
asyncTest "daemon -> multiple reads and writes":
|
||||
|
@ -391,7 +384,7 @@ suite "Interop":
|
|||
|
||||
nativeNode.mount(proto)
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
let nativePeer = nativeNode.peerInfo
|
||||
|
||||
let daemonNode = await newDaemonApi()
|
||||
|
@ -408,7 +401,6 @@ suite "Interop":
|
|||
|
||||
await stream.close()
|
||||
await nativeNode.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
|
||||
asyncTest "read write multiple":
|
||||
|
@ -437,7 +429,7 @@ suite "Interop":
|
|||
|
||||
nativeNode.mount(proto)
|
||||
|
||||
let awaiters = await nativeNode.start()
|
||||
await nativeNode.start()
|
||||
let nativePeer = nativeNode.peerInfo
|
||||
|
||||
let daemonNode = await newDaemonApi()
|
||||
|
@ -454,7 +446,6 @@ suite "Interop":
|
|||
check 10 == (await wait(testFuture, 1.minutes))
|
||||
await stream.close()
|
||||
await nativeNode.stop()
|
||||
await allFutures(awaiters)
|
||||
await daemonNode.close()
|
||||
|
||||
asyncTest "floodsub: daemon publish one":
|
||||
|
|
|
@ -96,7 +96,7 @@ suite "Minimal ASN.1 encode/decode suite":
|
|||
ncrutils.fromHex(Asn1EdgeExpects[i]) == value
|
||||
|
||||
test "ASN.1 DER INTEGER encoding/decoding of native unsigned values test":
|
||||
proc decodeBuffer(data: openarray[byte]): uint64 =
|
||||
proc decodeBuffer(data: openArray[byte]): uint64 =
|
||||
var ab = Asn1Buffer.init(data)
|
||||
let fres = ab.read()
|
||||
doAssert(fres.isOk() and fres.get().kind == Asn1Tag.Integer)
|
||||
|
|
|
@ -84,7 +84,7 @@ suite "MinProtobuf test suite":
|
|||
pb.finish()
|
||||
return pb.buffer
|
||||
|
||||
proc getVarintDecodedValue(data: openarray[byte]): uint64 =
|
||||
proc getVarintDecodedValue(data: openArray[byte]): uint64 =
|
||||
var value: uint64
|
||||
var pb = initProtoBuffer(data)
|
||||
let res = pb.getField(1, value)
|
||||
|
@ -97,7 +97,7 @@ suite "MinProtobuf test suite":
|
|||
pb.finish()
|
||||
return pb.buffer
|
||||
|
||||
proc getFixed32DecodedValue(data: openarray[byte]): uint32 =
|
||||
proc getFixed32DecodedValue(data: openArray[byte]): uint32 =
|
||||
var value: float32
|
||||
var pb = initProtoBuffer(data)
|
||||
let res = pb.getField(1, value)
|
||||
|
@ -110,7 +110,7 @@ suite "MinProtobuf test suite":
|
|||
pb.finish()
|
||||
return pb.buffer
|
||||
|
||||
proc getFixed64DecodedValue(data: openarray[byte]): uint64 =
|
||||
proc getFixed64DecodedValue(data: openArray[byte]): uint64 =
|
||||
var value: float64
|
||||
var pb = initProtoBuffer(data)
|
||||
let res = pb.getField(1, value)
|
||||
|
@ -129,7 +129,7 @@ suite "MinProtobuf test suite":
|
|||
pb.finish()
|
||||
return pb.buffer
|
||||
|
||||
proc getLengthDecodedValue(data: openarray[byte]): string =
|
||||
proc getLengthDecodedValue(data: openArray[byte]): string =
|
||||
var value = newString(len(data))
|
||||
var valueLen = 0
|
||||
var pb = initProtoBuffer(data)
|
||||
|
@ -138,13 +138,13 @@ suite "MinProtobuf test suite":
|
|||
value.setLen(valueLen)
|
||||
value
|
||||
|
||||
proc isFullZero[T: byte|char](data: openarray[T]): bool =
|
||||
proc isFullZero[T: byte|char](data: openArray[T]): bool =
|
||||
for ch in data:
|
||||
if int(ch) != 0:
|
||||
return false
|
||||
return true
|
||||
|
||||
proc corruptHeader(data: var openarray[byte], index: int) =
|
||||
proc corruptHeader(data: var openArray[byte], index: int) =
|
||||
var values = [3, 4, 6]
|
||||
data[0] = data[0] and 0xF8'u8
|
||||
data[0] = data[0] or byte(values[index mod len(values)])
|
||||
|
|
|
@ -378,7 +378,7 @@ suite "Mplex":
|
|||
|
||||
suite "mplex e2e":
|
||||
asyncTest "read/write receiver":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -397,7 +397,7 @@ suite "Mplex":
|
|||
|
||||
let acceptFut = acceptHandler()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -415,7 +415,7 @@ suite "Mplex":
|
|||
await listenFut
|
||||
|
||||
asyncTest "read/write receiver lazy":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -434,7 +434,7 @@ suite "Mplex":
|
|||
|
||||
let acceptFut = acceptHandler()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let stream = await mplexDial.newStream(lazy = true)
|
||||
|
@ -454,7 +454,7 @@ suite "Mplex":
|
|||
|
||||
asyncTest "write fragmented":
|
||||
let
|
||||
ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
listenJob = newFuture[void]()
|
||||
|
||||
var bigseq = newSeqOfCap[uint8](MaxMsgSize * 2)
|
||||
|
@ -486,7 +486,7 @@ suite "Mplex":
|
|||
|
||||
let acceptFut = acceptHandler()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -506,7 +506,7 @@ suite "Mplex":
|
|||
await listenFut
|
||||
|
||||
asyncTest "read/write initiator":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -523,7 +523,7 @@ suite "Mplex":
|
|||
await mplexListen.close()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let acceptFut = acceptHandler()
|
||||
let mplexDial = Mplex.new(conn)
|
||||
|
@ -542,7 +542,7 @@ suite "Mplex":
|
|||
await listenFut
|
||||
|
||||
asyncTest "multiple streams":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -565,7 +565,7 @@ suite "Mplex":
|
|||
await mplexListen.close()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let acceptFut = acceptHandler()
|
||||
let mplexDial = Mplex.new(conn)
|
||||
|
@ -586,7 +586,7 @@ suite "Mplex":
|
|||
await listenFut
|
||||
|
||||
asyncTest "multiple read/write streams":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -610,7 +610,7 @@ suite "Mplex":
|
|||
await mplexListen.close()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let acceptFut = acceptHandler()
|
||||
let mplexDial = Mplex.new(conn)
|
||||
|
@ -633,7 +633,7 @@ suite "Mplex":
|
|||
await listenFut
|
||||
|
||||
asyncTest "channel closes listener with EOF":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
var listenStreams: seq[Connection]
|
||||
|
@ -658,7 +658,7 @@ suite "Mplex":
|
|||
await transport1.start(ma)
|
||||
let acceptFut = acceptHandler()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -681,7 +681,7 @@ suite "Mplex":
|
|||
await acceptFut
|
||||
|
||||
asyncTest "channel closes dialer with EOF":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
||||
var count = 0
|
||||
|
@ -706,7 +706,7 @@ suite "Mplex":
|
|||
let acceptFut = acceptHandler()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -746,7 +746,7 @@ suite "Mplex":
|
|||
await acceptFut
|
||||
|
||||
asyncTest "dialing mplex closes both ends":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
||||
var listenStreams: seq[Connection]
|
||||
|
@ -765,7 +765,7 @@ suite "Mplex":
|
|||
let acceptFut = acceptHandler()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -788,7 +788,7 @@ suite "Mplex":
|
|||
await acceptFut
|
||||
|
||||
asyncTest "listening mplex closes both ends":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
||||
var mplexListen: Mplex
|
||||
|
@ -808,7 +808,7 @@ suite "Mplex":
|
|||
let acceptFut = acceptHandler()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -816,6 +816,8 @@ suite "Mplex":
|
|||
for i in 0..9:
|
||||
dialStreams.add((await mplexDial.newStream()))
|
||||
|
||||
check await checkExpiring(listenStreams.len == 10 and dialStreams.len == 10)
|
||||
|
||||
await mplexListen.close()
|
||||
await allFuturesThrowing(
|
||||
(dialStreams & listenStreams)
|
||||
|
@ -831,7 +833,7 @@ suite "Mplex":
|
|||
await acceptFut
|
||||
|
||||
asyncTest "canceling mplex handler closes both ends":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
||||
var mplexHandle: Future[void]
|
||||
|
@ -852,7 +854,7 @@ suite "Mplex":
|
|||
let acceptFut = acceptHandler()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -860,6 +862,8 @@ suite "Mplex":
|
|||
for i in 0..9:
|
||||
dialStreams.add((await mplexDial.newStream()))
|
||||
|
||||
check await checkExpiring(listenStreams.len == 10 and dialStreams.len == 10)
|
||||
|
||||
mplexHandle.cancel()
|
||||
await allFuturesThrowing(
|
||||
(dialStreams & listenStreams)
|
||||
|
@ -874,7 +878,7 @@ suite "Mplex":
|
|||
transport2.stop())
|
||||
|
||||
asyncTest "closing dialing connection should close both ends":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
||||
var listenStreams: seq[Connection]
|
||||
|
@ -893,7 +897,7 @@ suite "Mplex":
|
|||
let acceptFut = acceptHandler()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -901,11 +905,14 @@ suite "Mplex":
|
|||
for i in 0..9:
|
||||
dialStreams.add((await mplexDial.newStream()))
|
||||
|
||||
check await checkExpiring(listenStreams.len == 10 and dialStreams.len == 10)
|
||||
|
||||
await conn.close()
|
||||
await allFuturesThrowing(
|
||||
(dialStreams & listenStreams)
|
||||
.mapIt( it.join() ))
|
||||
|
||||
|
||||
checkTracker(LPChannelTrackerName)
|
||||
|
||||
await conn.closeWithEOF()
|
||||
|
@ -916,7 +923,7 @@ suite "Mplex":
|
|||
await acceptFut
|
||||
|
||||
asyncTest "canceling listening connection should close both ends":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
||||
var listenConn: Connection
|
||||
|
@ -936,7 +943,7 @@ suite "Mplex":
|
|||
let acceptFut = acceptHandler()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let mplexDial = Mplex.new(conn)
|
||||
let mplexDialFut = mplexDial.handle()
|
||||
|
@ -944,7 +951,8 @@ suite "Mplex":
|
|||
for i in 0..9:
|
||||
dialStreams.add((await mplexDial.newStream()))
|
||||
|
||||
await sleepAsync(100.millis)
|
||||
check await checkExpiring(listenStreams.len == 10 and dialStreams.len == 10)
|
||||
|
||||
await listenConn.closeWithEOF()
|
||||
await allFuturesThrowing(
|
||||
(dialStreams & listenStreams)
|
||||
|
@ -961,7 +969,7 @@ suite "Mplex":
|
|||
|
||||
suite "jitter":
|
||||
asyncTest "channel should be able to handle erratic read/writes":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -985,7 +993,7 @@ suite "Mplex":
|
|||
await mplexListen.close()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let acceptFut = acceptHandler()
|
||||
let mplexDial = Mplex.new(conn)
|
||||
|
@ -1033,7 +1041,7 @@ suite "Mplex":
|
|||
await listenFut
|
||||
|
||||
asyncTest "channel should handle 1 byte read/write":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let listenFut = transport1.start(ma)
|
||||
|
@ -1054,7 +1062,7 @@ suite "Mplex":
|
|||
await mplexListen.close()
|
||||
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let acceptFut = acceptHandler()
|
||||
let mplexDial = Mplex.new(conn)
|
||||
|
|
|
@ -234,7 +234,7 @@ suite "Multistream select":
|
|||
await ms.handle(conn)
|
||||
|
||||
asyncTest "e2e - handle":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
var protocol: LPProtocol = new LPProtocol
|
||||
proc testHandler(conn: Connection,
|
||||
|
@ -260,7 +260,7 @@ suite "Multistream select":
|
|||
|
||||
let msDial = MultistreamSelect.new()
|
||||
let transport2 = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
check (await msDial.select(conn, "/test/proto/1.0.0")) == true
|
||||
|
||||
|
@ -274,7 +274,7 @@ suite "Multistream select":
|
|||
await handlerWait.wait(30.seconds)
|
||||
|
||||
asyncTest "e2e - ls":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let
|
||||
handlerWait = newFuture[void]()
|
||||
|
@ -312,7 +312,7 @@ suite "Multistream select":
|
|||
let acceptFut = acceptHandler()
|
||||
let msDial = MultistreamSelect.new()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
let ls = await msDial.list(conn)
|
||||
let protos: seq[string] = @["/test/proto1/1.0.0", "/test/proto2/1.0.0"]
|
||||
|
@ -326,7 +326,7 @@ suite "Multistream select":
|
|||
await listenFut.wait(5.seconds)
|
||||
|
||||
asyncTest "e2e - select one from a list with unsupported protos":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
var protocol: LPProtocol = new LPProtocol
|
||||
proc testHandler(conn: Connection,
|
||||
|
@ -350,7 +350,7 @@ suite "Multistream select":
|
|||
let acceptFut = acceptHandler()
|
||||
let msDial = MultistreamSelect.new()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
check (await msDial.select(conn,
|
||||
@["/test/proto/1.0.0", "/test/no/proto/1.0.0"])) == "/test/proto/1.0.0"
|
||||
|
@ -364,7 +364,7 @@ suite "Multistream select":
|
|||
await transport1.stop()
|
||||
|
||||
asyncTest "e2e - select one with both valid":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
var protocol: LPProtocol = new LPProtocol
|
||||
proc testHandler(conn: Connection,
|
||||
|
@ -388,7 +388,7 @@ suite "Multistream select":
|
|||
let acceptFut = acceptHandler()
|
||||
let msDial = MultistreamSelect.new()
|
||||
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
let conn = await transport2.dial(transport1.ma)
|
||||
let conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
check (await msDial.select(conn,
|
||||
@[
|
||||
|
|
|
@ -58,8 +58,8 @@ suite "Name resolving":
|
|||
suite "Generic Resolving":
|
||||
var resolver {.threadvar.}: MockResolver
|
||||
|
||||
proc testOne(input: string, output: seq[Multiaddress]): bool =
|
||||
let resolved = waitFor resolver.resolveMAddress(Multiaddress.init(input).tryGet())
|
||||
proc testOne(input: string, output: seq[MultiAddress]): bool =
|
||||
let resolved = waitFor resolver.resolveMAddress(MultiAddress.init(input).tryGet())
|
||||
if resolved != output:
|
||||
echo "Expected ", output
|
||||
echo "Got ", resolved
|
||||
|
@ -67,10 +67,10 @@ suite "Name resolving":
|
|||
return true
|
||||
|
||||
proc testOne(input: string, output: seq[string]): bool =
|
||||
testOne(input, output.mapIt(Multiaddress.init(it).tryGet()))
|
||||
testOne(input, output.mapIt(MultiAddress.init(it).tryGet()))
|
||||
|
||||
proc testOne(input, output: string): bool =
|
||||
testOne(input, @[Multiaddress.init(output).tryGet()])
|
||||
testOne(input, @[MultiAddress.init(output).tryGet()])
|
||||
|
||||
asyncSetup:
|
||||
resolver = MockResolver.new()
|
||||
|
|
|
@ -15,7 +15,9 @@ import testmultibase,
|
|||
testmultihash,
|
||||
testmultiaddress,
|
||||
testcid,
|
||||
testpeerid
|
||||
testpeerid,
|
||||
testsigned_envelope,
|
||||
testrouting_record
|
||||
|
||||
import testtcptransport,
|
||||
testnameresolve,
|
||||
|
|
|
@ -88,9 +88,9 @@ suite "Noise":
|
|||
|
||||
asyncTest "e2e: handle write + noise":
|
||||
let
|
||||
server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
server = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
serverPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
serverInfo = PeerInfo.new(serverPrivKey, [server])
|
||||
serverInfo = PeerInfo.new(serverPrivKey, server)
|
||||
serverNoise = Noise.new(rng, serverPrivKey, outgoing = false)
|
||||
|
||||
let transport1: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
|
@ -109,9 +109,9 @@ suite "Noise":
|
|||
acceptFut = acceptHandler()
|
||||
transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
clientPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
clientInfo = PeerInfo.new(clientPrivKey, [transport1.ma])
|
||||
clientInfo = PeerInfo.new(clientPrivKey, transport1.addrs)
|
||||
clientNoise = Noise.new(rng, clientPrivKey, outgoing = true)
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
conn.peerId = serverInfo.peerId
|
||||
let sconn = await clientNoise.secure(conn, true)
|
||||
|
@ -129,9 +129,9 @@ suite "Noise":
|
|||
|
||||
asyncTest "e2e: handle write + noise (wrong prologue)":
|
||||
let
|
||||
server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
server = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
serverPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
serverInfo = PeerInfo.new(serverPrivKey, [server])
|
||||
serverInfo = PeerInfo.new(serverPrivKey, server)
|
||||
serverNoise = Noise.new(rng, serverPrivKey, outgoing = false)
|
||||
|
||||
let
|
||||
|
@ -153,9 +153,9 @@ suite "Noise":
|
|||
handlerWait = acceptHandler()
|
||||
transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
clientPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
clientInfo = PeerInfo.new(clientPrivKey, [transport1.ma])
|
||||
clientInfo = PeerInfo.new(clientPrivKey, transport1.addrs)
|
||||
clientNoise = Noise.new(rng, clientPrivKey, outgoing = true, commonPrologue = @[1'u8, 2'u8, 3'u8])
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
conn.peerId = serverInfo.peerId
|
||||
|
||||
var sconn: Connection = nil
|
||||
|
@ -169,9 +169,9 @@ suite "Noise":
|
|||
|
||||
asyncTest "e2e: handle read + noise":
|
||||
let
|
||||
server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
server = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
serverPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
serverInfo = PeerInfo.new(serverPrivKey, [server])
|
||||
serverInfo = PeerInfo.new(serverPrivKey, server)
|
||||
serverNoise = Noise.new(rng, serverPrivKey, outgoing = false)
|
||||
readTask = newFuture[void]()
|
||||
|
||||
|
@ -193,9 +193,9 @@ suite "Noise":
|
|||
acceptFut = acceptHandler()
|
||||
transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
clientPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
clientInfo = PeerInfo.new(clientPrivKey, [transport1.ma])
|
||||
clientInfo = PeerInfo.new(clientPrivKey, transport1.addrs)
|
||||
clientNoise = Noise.new(rng, clientPrivKey, outgoing = true)
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
conn.peerId = serverInfo.peerId
|
||||
let sconn = await clientNoise.secure(conn, true)
|
||||
|
||||
|
@ -208,9 +208,9 @@ suite "Noise":
|
|||
|
||||
asyncTest "e2e: handle read + noise fragmented":
|
||||
let
|
||||
server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
server = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
serverPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
serverInfo = PeerInfo.new(serverPrivKey, [server])
|
||||
serverInfo = PeerInfo.new(serverPrivKey, server)
|
||||
serverNoise = Noise.new(rng, serverPrivKey, outgoing = false)
|
||||
readTask = newFuture[void]()
|
||||
|
||||
|
@ -235,9 +235,9 @@ suite "Noise":
|
|||
acceptFut = acceptHandler()
|
||||
transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
clientPrivKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
clientInfo = PeerInfo.new(clientPrivKey, [transport1.ma])
|
||||
clientInfo = PeerInfo.new(clientPrivKey, transport1.addrs)
|
||||
clientNoise = Noise.new(rng, clientPrivKey, outgoing = true)
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
conn.peerId = serverInfo.peerId
|
||||
let sconn = await clientNoise.secure(conn, true)
|
||||
|
||||
|
@ -252,12 +252,11 @@ suite "Noise":
|
|||
await listenFut
|
||||
|
||||
asyncTest "e2e use switch dial proto string":
|
||||
let ma1: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma2: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma1 = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma2 = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
|
||||
var peerInfo1, peerInfo2: PeerInfo
|
||||
var switch1, switch2: Switch
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
(switch1, peerInfo1) = createSwitch(ma1, false)
|
||||
|
||||
|
@ -266,8 +265,8 @@ suite "Noise":
|
|||
testProto.codec = TestCodec
|
||||
switch1.mount(testProto)
|
||||
(switch2, peerInfo2) = createSwitch(ma2, true)
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
await conn.writeLp("Hello!")
|
||||
let msg = string.fromBytes(await conn.readLp(1024))
|
||||
|
@ -277,15 +276,13 @@ suite "Noise":
|
|||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e test wrong secure negotiation":
|
||||
let ma1: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma2: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma1 = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma2 = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
|
||||
var peerInfo1, peerInfo2: PeerInfo
|
||||
var switch1, switch2: Switch
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
(switch1, peerInfo1) = createSwitch(ma1, false)
|
||||
|
||||
|
@ -294,13 +291,11 @@ suite "Noise":
|
|||
testProto.codec = TestCodec
|
||||
switch1.mount(testProto)
|
||||
(switch2, peerInfo2) = createSwitch(ma2, true, true) # secio, we want to fail
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
expect(UpgradeFailedError):
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
||||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
|
|
@ -164,7 +164,7 @@ const
|
|||
"08021220B333BE3E843339E0E2CE9E083ABC119BE05C7B65B8665ADE19E172D47BF91305"
|
||||
]
|
||||
|
||||
PeerIDs = [
|
||||
PeerIds = [
|
||||
"QmeuZJbXrszW2jdT7GdduSjQskPU3S7vvGWKtKgDfkDvWs",
|
||||
"QmeasUkAi1BhVUmopWzYJ5G1PGys9T5MZ2sPn87XTyaUAM",
|
||||
"Qmc3PxhMhQja8N4t7mRDyGm2vHkvcxe5Kabp2iAig1DXHb",
|
||||
|
@ -180,15 +180,15 @@ const
|
|||
]
|
||||
|
||||
suite "Peer testing suite":
|
||||
test "Go PeerID test vectors":
|
||||
test "Go PeerId test vectors":
|
||||
for i in 0..<len(PrivateKeys):
|
||||
var seckey = PrivateKey.init(stripSpaces(PrivateKeys[i])).get()
|
||||
var pubkey = seckey.getPublicKey().get()
|
||||
var p1 = PeerID.init(seckey).get()
|
||||
var p2 = PeerID.init(pubkey).get()
|
||||
var p3 = PeerID.init(PeerIDs[i]).get()
|
||||
var b1 = Base58.decode(PeerIDs[i])
|
||||
var p4 = PeerID.init(b1).get()
|
||||
var p1 = PeerId.init(seckey).get()
|
||||
var p2 = PeerId.init(pubkey).get()
|
||||
var p3 = PeerId.init(PeerIds[i]).get()
|
||||
var b1 = Base58.decode(PeerIds[i])
|
||||
var p4 = PeerId.init(b1).get()
|
||||
var buf1 = newSeq[byte](len(p1))
|
||||
var buf2 = newSeq[byte](len(p2))
|
||||
var buf3 = newSeq[byte](len(p3))
|
||||
|
@ -200,10 +200,10 @@ suite "Peer testing suite":
|
|||
p1 == p2
|
||||
p1 == p4
|
||||
p2 == p4
|
||||
$p1 == PeerIDs[i]
|
||||
$p2 == PeerIDs[i]
|
||||
$p3 == PeerIDs[i]
|
||||
$p4 == PeerIDs[i]
|
||||
$p1 == PeerIds[i]
|
||||
$p2 == PeerIds[i]
|
||||
$p3 == PeerIds[i]
|
||||
$p4 == PeerIds[i]
|
||||
p1.match(seckey) == true
|
||||
p1.match(pubkey) == true
|
||||
p1.getBytes() == p2.getBytes()
|
||||
|
|
|
@ -12,7 +12,7 @@ suite "PeerInfo":
|
|||
test "Should init with private key":
|
||||
let seckey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
var peerInfo = PeerInfo.new(seckey)
|
||||
var peerId = PeerID.init(seckey).get()
|
||||
var peerId = PeerId.init(seckey).get()
|
||||
|
||||
check peerId == peerInfo.peerId
|
||||
check seckey.getPublicKey().get() == peerInfo.publicKey
|
||||
|
|
|
@ -12,13 +12,13 @@ suite "PeerStore":
|
|||
let
|
||||
# Peer 1
|
||||
keyPair1 = KeyPair.random(ECDSA, rng[]).get()
|
||||
peerId1 = PeerID.init(keyPair1.secKey).get()
|
||||
peerId1 = PeerId.init(keyPair1.seckey).get()
|
||||
multiaddrStr1 = "/ip4/127.0.0.1/udp/1234/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC"
|
||||
multiaddr1 = MultiAddress.init(multiaddrStr1).get()
|
||||
testcodec1 = "/nim/libp2p/test/0.0.1-beta1"
|
||||
# Peer 2
|
||||
keyPair2 = KeyPair.random(ECDSA, rng[]).get()
|
||||
peerId2 = PeerID.init(keyPair2.secKey).get()
|
||||
peerId2 = PeerId.init(keyPair2.seckey).get()
|
||||
multiaddrStr2 = "/ip4/0.0.0.0/tcp/1234/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC"
|
||||
multiaddr2 = MultiAddress.init(multiaddrStr2).get()
|
||||
testcodec2 = "/nim/libp2p/test/0.0.2-beta1"
|
||||
|
@ -32,8 +32,8 @@ suite "PeerStore":
|
|||
peerStore.addressBook.add(peerId2, multiaddr2)
|
||||
peerStore.protoBook.add(peerId1, testcodec1)
|
||||
peerStore.protoBook.add(peerId2, testcodec2)
|
||||
peerStore.keyBook.set(peerId1, keyPair1.pubKey)
|
||||
peerStore.keyBook.set(peerId2, keyPair2.pubKey)
|
||||
peerStore.keyBook.set(peerId1, keyPair1.pubkey)
|
||||
peerStore.keyBook.set(peerId2, keyPair2.pubkey)
|
||||
|
||||
# Test PeerStore::delete
|
||||
check:
|
||||
|
@ -52,13 +52,13 @@ suite "PeerStore":
|
|||
protoChanged = false
|
||||
keyChanged = false
|
||||
|
||||
proc addrChange(peerId: PeerID, addrs: HashSet[MultiAddress]) =
|
||||
proc addrChange(peerId: PeerId, addrs: HashSet[MultiAddress]) =
|
||||
addrChanged = true
|
||||
|
||||
proc protoChange(peerId: PeerID, protos: HashSet[string]) =
|
||||
proc protoChange(peerId: PeerId, protos: HashSet[string]) =
|
||||
protoChanged = true
|
||||
|
||||
proc keyChange(peerId: PeerID, publicKey: PublicKey) =
|
||||
proc keyChange(peerId: PeerId, publicKey: PublicKey) =
|
||||
keyChanged = true
|
||||
|
||||
peerStore.addHandlers(addrChangeHandler = addrChange,
|
||||
|
|
|
@ -31,7 +31,7 @@ suite "Ping":
|
|||
pingReceivedCount {.threadvar.}: int
|
||||
|
||||
asyncSetup:
|
||||
ma = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
ma = MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
|
||||
transport1 = TcpTransport.new(upgrade = Upgrade())
|
||||
transport2 = TcpTransport.new(upgrade = Upgrade())
|
||||
|
@ -56,13 +56,13 @@ suite "Ping":
|
|||
|
||||
asyncTest "simple ping":
|
||||
msListen.addHandler(PingCodec, pingProto1)
|
||||
serverFut = transport1.start(ma)
|
||||
serverFut = transport1.start(@[ma])
|
||||
proc acceptHandler(): Future[void] {.async, gcsafe.} =
|
||||
let c = await transport1.accept()
|
||||
await msListen.handle(c)
|
||||
|
||||
acceptFut = acceptHandler()
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
discard await msDial.select(conn, PingCodec)
|
||||
let time = await pingProto2.ping(conn)
|
||||
|
@ -71,14 +71,14 @@ suite "Ping":
|
|||
|
||||
asyncTest "ping callback":
|
||||
msDial.addHandler(PingCodec, pingProto2)
|
||||
serverFut = transport1.start(ma)
|
||||
serverFut = transport1.start(@[ma])
|
||||
proc acceptHandler(): Future[void] {.async, gcsafe.} =
|
||||
let c = await transport1.accept()
|
||||
discard await msListen.select(c, PingCodec)
|
||||
discard await pingProto1.ping(c)
|
||||
|
||||
acceptFut = acceptHandler()
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
await msDial.handle(conn)
|
||||
check pingReceivedCount == 1
|
||||
|
@ -96,13 +96,13 @@ suite "Ping":
|
|||
fakePingProto.handler = fakeHandle
|
||||
|
||||
msListen.addHandler(PingCodec, fakePingProto)
|
||||
serverFut = transport1.start(ma)
|
||||
serverFut = transport1.start(@[ma])
|
||||
proc acceptHandler(): Future[void] {.async, gcsafe.} =
|
||||
let c = await transport1.accept()
|
||||
await msListen.handle(c)
|
||||
|
||||
acceptFut = acceptHandler()
|
||||
conn = await transport2.dial(transport1.ma)
|
||||
conn = await transport2.dial(transport1.addrs[0])
|
||||
|
||||
discard await msDial.select(conn, PingCodec)
|
||||
let p = pingProto2.ping(conn)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import unittest2
|
||||
import stew/byteutils
|
||||
import ../libp2p/[routing_record, crypto/crypto]
|
||||
|
||||
suite "Routing record":
|
||||
test "Encode -> decode test":
|
||||
let
|
||||
rng = newRng()
|
||||
privKey = PrivateKey.random(rng[]).tryGet()
|
||||
peerId = PeerId.init(privKey).tryGet()
|
||||
multiAddresses = @[MultiAddress.init("/ip4/0.0.0.0/tcp/24").tryGet(), MultiAddress.init("/ip4/0.0.0.0/tcp/25").tryGet()]
|
||||
routingRecord = PeerRecord.init(peerId, 42, multiAddresses)
|
||||
|
||||
buffer = routingRecord.encode()
|
||||
|
||||
parsedRR = PeerRecord.decode(buffer).tryGet()
|
||||
|
||||
check:
|
||||
parsedRR.peerId == peerId
|
||||
parsedRR.seqNo == 42
|
||||
parsedRR.addresses.len == 2
|
||||
parsedRR.addresses[0].address == multiAddresses[0]
|
||||
parsedRR.addresses[1].address == multiAddresses[1]
|
||||
|
||||
test "Interop decode":
|
||||
let
|
||||
# from https://github.com/libp2p/go-libp2p-core/blob/b18a4c9c5629870bde2cd85ab3b87a507600d411/peer/record_test.go#L33
|
||||
# (with only 2 addresses)
|
||||
inputData = "0a2600240801122011bba3ed1721948cefb4e50b0a0bb5cad8a6b52dc7b1a40f4f6652105c91e2c4109bf59d8dd99d8ddb161a0a0a0804010203040600001a0a0a080401020304060001".hexToSeqByte()
|
||||
decodedRecord = PeerRecord.decode(inputData).tryGet()
|
||||
|
||||
check:
|
||||
$decodedRecord.peerId == "12D3KooWB1b3qZxWJanuhtseF3DmPggHCtG36KZ9ixkqHtdKH9fh"
|
||||
decodedRecord.seqNo == uint64 1636553709551319707
|
||||
decodedRecord.addresses.len == 2
|
||||
$decodedRecord.addresses[0].address == "/ip4/1.2.3.4/tcp/0"
|
||||
$decodedRecord.addresses[1].address == "/ip4/1.2.3.4/tcp/1"
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import unittest2
|
||||
import stew/byteutils
|
||||
import ../libp2p/[signed_envelope]
|
||||
|
||||
suite "Signed envelope":
|
||||
test "Encode -> decode test":
|
||||
let
|
||||
rng = newRng()
|
||||
privKey = PrivateKey.random(rng[]).tryGet()
|
||||
envelope = Envelope.init(privKey, @[byte 12, 0], "payload".toBytes(), "domain").tryGet()
|
||||
buffer = envelope.encode().tryGet()
|
||||
decodedEnvelope = Envelope.decode(buffer, "domain").tryGet()
|
||||
wrongDomain = Envelope.decode(buffer, "wdomain")
|
||||
|
||||
check:
|
||||
decodedEnvelope == envelope
|
||||
wrongDomain.error == EnvelopeInvalidSignature
|
||||
|
||||
test "Interop decode test":
|
||||
# from https://github.com/libp2p/go-libp2p-core/blob/b18a4c9c5629870bde2cd85ab3b87a507600d411/record/envelope_test.go#L68
|
||||
let inputData = "0a24080112206f1581709bb7b1ef030d210db18e3b0ba1c776fba65d8cdaad05415142d189f812102f6c69627032702f74657374646174611a0c68656c6c6f20776f726c64212a401178673b51dfa842aad17e465e25d646ad16628916b964c3fb10c711fee87872bdd4e4646f58c277cdff09704913d8be1aec6322de8d3d0bb852120374aece08".hexToSeqByte()
|
||||
let decodedEnvelope = Envelope.decode(inputData, "libp2p-testing").tryGet()
|
||||
check:
|
||||
decodedEnvelope.payloadType == "/libp2p/testdata".toBytes()
|
||||
decodedEnvelope.payload == "hello world!".toBytes()
|
||||
|
||||
test "Signature validation":
|
||||
# same as above, but payload altered
|
||||
let inputData = "0a24080112206f1581709bb7b1ef030d210db18e3b0ba1c776fba65d8cdaad05415142d189f812102f6c69627032702f74657374646174611a0c00006c6c6f20776f726c64212a401178673b51dfa842aad17e465e25d646ad16628916b964c3fb10c711fee87872bdd4e4646f58c277cdff09704913d8be1aec6322de8d3d0bb852120374aece08".hexToSeqByte()
|
||||
check Envelope.decode(inputData, "libp2p-testing").error == EnvelopeInvalidSignature
|
|
@ -54,9 +54,8 @@ suite "Switch":
|
|||
switch1.mount(testProto)
|
||||
|
||||
let switch2 = newStandardSwitch()
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
||||
|
@ -73,9 +72,6 @@ suite "Switch":
|
|||
switch1.stop(),
|
||||
switch2.stop())
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
check not switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check not switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
|
@ -103,9 +99,8 @@ suite "Switch":
|
|||
switch1.mount(testProto, match)
|
||||
|
||||
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, callProto)
|
||||
|
||||
|
@ -122,9 +117,6 @@ suite "Switch":
|
|||
switch1.stop(),
|
||||
switch2.stop())
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
check not switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check not switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
|
@ -147,9 +139,8 @@ suite "Switch":
|
|||
switch1.mount(testProto)
|
||||
|
||||
let switch2 = newStandardSwitch()
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
||||
|
@ -167,15 +158,10 @@ suite "Switch":
|
|||
switch2.stop(),
|
||||
)
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
check not switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check not switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
asyncTest "e2e use connect then dial":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
||||
try:
|
||||
let msg = string.fromBytes(await conn.readLp(1024))
|
||||
|
@ -192,8 +178,8 @@ suite "Switch":
|
|||
switch1.mount(testProto)
|
||||
|
||||
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
@ -210,18 +196,15 @@ suite "Switch":
|
|||
switch1.stop(),
|
||||
switch2.stop()
|
||||
)
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
check not switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check not switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
asyncTest "e2e should not leak on peer disconnect":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let switch1 = newStandardSwitch()
|
||||
let switch2 = newStandardSwitch()
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
|
||||
|
||||
|
@ -239,11 +222,8 @@ suite "Switch":
|
|||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should trigger connection events (remote)":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let switch1 = newStandardSwitch()
|
||||
let switch2 = newStandardSwitch()
|
||||
|
||||
|
@ -269,8 +249,8 @@ suite "Switch":
|
|||
switch2.addConnEventHandler(hook, ConnEventKind.Connected)
|
||||
switch2.addConnEventHandler(hook, ConnEventKind.Disconnected)
|
||||
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
|
||||
|
||||
|
@ -294,11 +274,8 @@ suite "Switch":
|
|||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should trigger connection events (local)":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let switch1 = newStandardSwitch()
|
||||
let switch2 = newStandardSwitch()
|
||||
|
||||
|
@ -324,8 +301,8 @@ suite "Switch":
|
|||
switch1.addConnEventHandler(hook, ConnEventKind.Connected)
|
||||
switch1.addConnEventHandler(hook, ConnEventKind.Disconnected)
|
||||
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
|
||||
|
||||
|
@ -349,11 +326,8 @@ suite "Switch":
|
|||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should trigger peer events (remote)":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let switch1 = newStandardSwitch()
|
||||
let switch2 = newStandardSwitch()
|
||||
|
||||
|
@ -378,8 +352,8 @@ suite "Switch":
|
|||
switch1.addPeerEventHandler(handler, PeerEventKind.Joined)
|
||||
switch1.addPeerEventHandler(handler, PeerEventKind.Left)
|
||||
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
|
||||
|
||||
|
@ -403,11 +377,8 @@ suite "Switch":
|
|||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should trigger peer events (local)":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let switch1 = newStandardSwitch()
|
||||
let switch2 = newStandardSwitch()
|
||||
|
||||
|
@ -432,8 +403,8 @@ suite "Switch":
|
|||
switch2.addPeerEventHandler(handler, PeerEventKind.Joined)
|
||||
switch2.addPeerEventHandler(handler, PeerEventKind.Left)
|
||||
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
|
||||
|
||||
|
@ -457,11 +428,8 @@ suite "Switch":
|
|||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should trigger peer events only once per peer":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let switch1 = newStandardSwitch()
|
||||
|
||||
let rng = crypto.newRng()
|
||||
|
@ -494,9 +462,9 @@ suite "Switch":
|
|||
switch1.addPeerEventHandler(handler, PeerEventKind.Joined)
|
||||
switch1.addPeerEventHandler(handler, PeerEventKind.Left)
|
||||
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
awaiters.add(await switch3.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
await switch3.start()
|
||||
|
||||
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) # should trigger 1st Join event
|
||||
await switch3.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) # should trigger 2nd Join event
|
||||
|
@ -526,11 +494,8 @@ suite "Switch":
|
|||
switch1.stop(),
|
||||
switch2.stop(),
|
||||
switch3.stop())
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should allow dropping peer from connection events":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let rng = crypto.newRng()
|
||||
# use same private keys to emulate two connection from same peer
|
||||
let
|
||||
|
@ -555,7 +520,7 @@ suite "Switch":
|
|||
|
||||
switches[0].addConnEventHandler(hook, ConnEventKind.Connected)
|
||||
switches[0].addConnEventHandler(hook, ConnEventKind.Disconnected)
|
||||
awaiters.add(await switches[0].start())
|
||||
await switches[0].start()
|
||||
|
||||
switches.add(newStandardSwitch(
|
||||
privKey = some(privateKey),
|
||||
|
@ -569,11 +534,8 @@ suite "Switch":
|
|||
|
||||
await allFuturesThrowing(
|
||||
switches.mapIt( it.stop() ))
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e should allow dropping multiple connections for peer from connection events":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
let rng = crypto.newRng()
|
||||
# use same private keys to emulate two connection from same peer
|
||||
let
|
||||
|
@ -603,7 +565,7 @@ suite "Switch":
|
|||
rng = rng))
|
||||
|
||||
switches[0].addConnEventHandler(hook, ConnEventKind.Connected)
|
||||
awaiters.add(await switches[0].start())
|
||||
await switches[0].start()
|
||||
|
||||
for i in 1..5:
|
||||
switches.add(newStandardSwitch(
|
||||
|
@ -619,13 +581,12 @@ suite "Switch":
|
|||
|
||||
await allFuturesThrowing(
|
||||
switches.mapIt( it.stop() ))
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
# TODO: we should be able to test cancellation
|
||||
# for most of the steps in the upgrade flow -
|
||||
# this is just a basic test for dials
|
||||
asyncTest "e2e canceling dial should not leak":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport = TcpTransport.new(upgrade = Upgrade())
|
||||
await transport.start(ma)
|
||||
|
@ -641,11 +602,10 @@ suite "Switch":
|
|||
let handlerWait = acceptHandler()
|
||||
let switch = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
|
||||
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch.start())
|
||||
await switch.start()
|
||||
|
||||
var peerId = PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get()
|
||||
let connectFut = switch.connect(peerId, @[transport.ma])
|
||||
var peerId = PeerId.init(PrivateKey.random(ECDSA, rng[]).get()).get()
|
||||
let connectFut = switch.connect(peerId, transport.addrs)
|
||||
await sleepAsync(500.millis)
|
||||
connectFut.cancel()
|
||||
await handlerWait
|
||||
|
@ -658,11 +618,8 @@ suite "Switch":
|
|||
transport.stop(),
|
||||
switch.stop())
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e closing remote conn should not leak":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport = TcpTransport.new(upgrade = Upgrade())
|
||||
await transport.start(ma)
|
||||
|
@ -674,12 +631,11 @@ suite "Switch":
|
|||
let handlerWait = acceptHandler()
|
||||
let switch = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
|
||||
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch.start())
|
||||
await switch.start()
|
||||
|
||||
var peerId = PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get()
|
||||
expect LPStreamClosedError:
|
||||
await switch.connect(peerId, @[transport.ma])
|
||||
var peerId = PeerId.init(PrivateKey.random(ECDSA, rng[]).get()).get()
|
||||
expect LPStreamClosedError, LPStreamEOFError:
|
||||
await switch.connect(peerId, transport.addrs)
|
||||
|
||||
await handlerWait
|
||||
|
||||
|
@ -691,9 +647,6 @@ suite "Switch":
|
|||
transport.stop(),
|
||||
switch.stop())
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e calling closeWithEOF on the same stream should not assert":
|
||||
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
||||
discard await conn.readLp(100)
|
||||
|
@ -707,8 +660,7 @@ suite "Switch":
|
|||
|
||||
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
|
||||
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch1.start())
|
||||
await switch1.start()
|
||||
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
||||
|
@ -721,7 +673,7 @@ suite "Switch":
|
|||
|
||||
await allFuturesThrowing(readers)
|
||||
await switch2.stop() #Otherwise this leaks
|
||||
check await checkExpiring(not switch1.isConnected(switch2.peerInfo.peerID))
|
||||
check await checkExpiring(not switch1.isConnected(switch2.peerInfo.peerId))
|
||||
|
||||
checkTracker(LPChannelTrackerName)
|
||||
checkTracker(SecureConnTrackerName)
|
||||
|
@ -729,60 +681,52 @@ suite "Switch":
|
|||
|
||||
await switch1.stop()
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "connect to inexistent peer":
|
||||
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
|
||||
discard await switch2.start()
|
||||
await switch2.start()
|
||||
let someAddr = MultiAddress.init("/ip4/127.128.0.99").get()
|
||||
let seckey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
let somePeer = PeerInfo.new(secKey, [someAddr])
|
||||
let somePeer = PeerInfo.new(seckey, [someAddr])
|
||||
expect(DialFailedError):
|
||||
discard await switch2.dial(somePeer.peerId, somePeer.addrs, TestCodec)
|
||||
await switch2.stop()
|
||||
|
||||
asyncTest "e2e total connection limits on incoming connections":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
var switches: seq[Switch]
|
||||
let destSwitch = newStandardSwitch(maxConnections = 3)
|
||||
switches.add(destSwitch)
|
||||
awaiters.add(await destSwitch.start())
|
||||
await destSwitch.start()
|
||||
|
||||
let destPeerInfo = destSwitch.peerInfo
|
||||
for i in 0..<3:
|
||||
let switch = newStandardSwitch()
|
||||
switches.add(switch)
|
||||
awaiters.add(await switch.start())
|
||||
await switch.start()
|
||||
|
||||
check await switch.connect(destPeerInfo.peerId, destPeerInfo.addrs)
|
||||
.withTimeout(1000.millis)
|
||||
|
||||
let switchFail = newStandardSwitch()
|
||||
switches.add(switchFail)
|
||||
awaiters.add(await switchFail.start())
|
||||
await switchFail.start()
|
||||
|
||||
check not(await switchFail.connect(destPeerInfo.peerId, destPeerInfo.addrs)
|
||||
.withTimeout(1000.millis))
|
||||
|
||||
await allFuturesThrowing(
|
||||
allFutures(switches.mapIt( it.stop() )))
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e total connection limits on incoming connections":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
var switches: seq[Switch]
|
||||
for i in 0..<3:
|
||||
switches.add(newStandardSwitch())
|
||||
awaiters.add(await switches[i].start())
|
||||
await switches[i].start()
|
||||
|
||||
let srcSwitch = newStandardSwitch(maxConnections = 3)
|
||||
awaiters.add(await srcSwitch.start())
|
||||
await srcSwitch.start()
|
||||
|
||||
let dstSwitch = newStandardSwitch()
|
||||
awaiters.add(await dstSwitch.start())
|
||||
await dstSwitch.start()
|
||||
|
||||
for s in switches:
|
||||
check await srcSwitch.connect(s.peerInfo.peerId, s.peerInfo.addrs)
|
||||
|
@ -796,49 +740,44 @@ suite "Switch":
|
|||
|
||||
await allFuturesThrowing(
|
||||
allFutures(switches.mapIt( it.stop() )))
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e max incoming connection limits":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
var switches: seq[Switch]
|
||||
let destSwitch = newStandardSwitch(maxIn = 3)
|
||||
switches.add(destSwitch)
|
||||
awaiters.add(await destSwitch.start())
|
||||
await destSwitch.start()
|
||||
|
||||
let destPeerInfo = destSwitch.peerInfo
|
||||
for i in 0..<3:
|
||||
let switch = newStandardSwitch()
|
||||
switches.add(switch)
|
||||
awaiters.add(await switch.start())
|
||||
await switch.start()
|
||||
|
||||
check await switch.connect(destPeerInfo.peerId, destPeerInfo.addrs)
|
||||
.withTimeout(1000.millis)
|
||||
|
||||
let switchFail = newStandardSwitch()
|
||||
switches.add(switchFail)
|
||||
awaiters.add(await switchFail.start())
|
||||
await switchFail.start()
|
||||
|
||||
check not(await switchFail.connect(destPeerInfo.peerId, destPeerInfo.addrs)
|
||||
.withTimeout(1000.millis))
|
||||
|
||||
await allFuturesThrowing(
|
||||
allFutures(switches.mapIt( it.stop() )))
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e max outgoing connection limits":
|
||||
var awaiters: seq[Future[void]]
|
||||
|
||||
var switches: seq[Switch]
|
||||
for i in 0..<3:
|
||||
switches.add(newStandardSwitch())
|
||||
awaiters.add(await switches[i].start())
|
||||
await switches[i].start()
|
||||
|
||||
let srcSwitch = newStandardSwitch(maxOut = 3)
|
||||
awaiters.add(await srcSwitch.start())
|
||||
await srcSwitch.start()
|
||||
|
||||
let dstSwitch = newStandardSwitch()
|
||||
awaiters.add(await dstSwitch.start())
|
||||
await dstSwitch.start()
|
||||
|
||||
for s in switches:
|
||||
check await srcSwitch.connect(s.peerInfo.peerId, s.peerInfo.addrs)
|
||||
|
@ -852,7 +791,6 @@ suite "Switch":
|
|||
|
||||
await allFuturesThrowing(
|
||||
allFutures(switches.mapIt( it.stop() )))
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
asyncTest "e2e peer store":
|
||||
let done = newFuture[void]()
|
||||
|
@ -873,9 +811,8 @@ suite "Switch":
|
|||
switch1.mount(testProto)
|
||||
|
||||
let switch2 = newStandardSwitch()
|
||||
var awaiters: seq[Future[void]]
|
||||
awaiters.add(await switch1.start())
|
||||
awaiters.add(await switch2.start())
|
||||
await switch1.start()
|
||||
await switch2.start()
|
||||
|
||||
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
|
||||
|
||||
|
@ -892,9 +829,6 @@ suite "Switch":
|
|||
switch1.stop(),
|
||||
switch2.stop())
|
||||
|
||||
# this needs to go at end
|
||||
await allFuturesThrowing(awaiters)
|
||||
|
||||
check not switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check not switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
|
@ -905,8 +839,74 @@ suite "Switch":
|
|||
switch1.peerStore.protoBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.protocols.toHashSet()
|
||||
switch2.peerStore.protoBook.get(switch1.peerInfo.peerId) == switch1.peerInfo.protocols.toHashSet()
|
||||
|
||||
asyncTest "e2e should allow multiple local addresses":
|
||||
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
||||
try:
|
||||
let msg = string.fromBytes(await conn.readLp(1024))
|
||||
check "Hello!" == msg
|
||||
await conn.writeLp("Hello!")
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
let testProto = new TestProto
|
||||
testProto.codec = TestCodec
|
||||
testProto.handler = handle
|
||||
|
||||
let addrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
||||
MultiAddress.init("/ip6/::1/tcp/0").tryGet()]
|
||||
|
||||
let switch1 = newStandardSwitch(
|
||||
addrs = addrs,
|
||||
transportFlags = {ServerFlags.ReuseAddr, ServerFlags.ReusePort})
|
||||
|
||||
switch1.mount(testProto)
|
||||
|
||||
let switch2 = newStandardSwitch()
|
||||
let switch3 = newStandardSwitch(
|
||||
addrs = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet()
|
||||
)
|
||||
|
||||
await allFuturesThrowing(
|
||||
switch1.start(),
|
||||
switch2.start(),
|
||||
switch3.start())
|
||||
|
||||
check IP4.matchPartial(switch1.peerInfo.addrs[0])
|
||||
check IP6.matchPartial(switch1.peerInfo.addrs[1])
|
||||
|
||||
let conn = await switch2.dial(
|
||||
switch1.peerInfo.peerId,
|
||||
@[switch1.peerInfo.addrs[0]],
|
||||
TestCodec)
|
||||
|
||||
check switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
await conn.writeLp("Hello!")
|
||||
check "Hello!" == string.fromBytes(await conn.readLp(1024))
|
||||
await conn.close()
|
||||
|
||||
let connv6 = await switch3.dial(
|
||||
switch1.peerInfo.peerId,
|
||||
@[switch1.peerInfo.addrs[1]],
|
||||
TestCodec)
|
||||
|
||||
check switch1.isConnected(switch3.peerInfo.peerId)
|
||||
check switch3.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
await connv6.writeLp("Hello!")
|
||||
check "Hello!" == string.fromBytes(await connv6.readLp(1024))
|
||||
await connv6.close()
|
||||
|
||||
await allFuturesThrowing(
|
||||
switch1.stop(),
|
||||
switch2.stop(),
|
||||
switch3.stop())
|
||||
|
||||
check not switch1.isConnected(switch2.peerInfo.peerId)
|
||||
check not switch2.isConnected(switch1.peerInfo.peerId)
|
||||
|
||||
asyncTest "e2e dial dns4 address":
|
||||
var awaiters: seq[Future[void]]
|
||||
let resolver = MockResolver.new()
|
||||
resolver.ipResponses[("localhost", false)] = @["127.0.0.1"]
|
||||
resolver.ipResponses[("localhost", true)] = @["::1"]
|
||||
|
@ -915,9 +915,8 @@ suite "Switch":
|
|||
srcSwitch = newStandardSwitch(nameResolver = resolver)
|
||||
destSwitch = newStandardSwitch()
|
||||
|
||||
awaiters.add(await destSwitch.start())
|
||||
awaiters.add(await srcSwitch.start())
|
||||
await allFuturesThrowing(awaiters)
|
||||
await destSwitch.start()
|
||||
await srcSwitch.start()
|
||||
|
||||
let testAddr = MultiAddress.init("/dns4/localhost/").tryGet() &
|
||||
destSwitch.peerInfo.addrs[0][1].tryGet()
|
||||
|
@ -929,7 +928,6 @@ suite "Switch":
|
|||
await srcSwitch.stop()
|
||||
|
||||
asyncTest "e2e dial dnsaddr with multiple transports":
|
||||
var awaiters: seq[Future[void]]
|
||||
let resolver = MockResolver.new()
|
||||
|
||||
let
|
||||
|
@ -957,14 +955,12 @@ suite "Switch":
|
|||
.withNoise()
|
||||
.build()
|
||||
|
||||
awaiters.add(await destSwitch.start())
|
||||
awaiters.add(await srcTcpSwitch.start())
|
||||
awaiters.add(await srcWsSwitch.start())
|
||||
await allFuturesThrowing(awaiters)
|
||||
await destSwitch.start()
|
||||
await srcWsSwitch.start()
|
||||
|
||||
resolver.txtResponses["_dnsaddr.test.io"] = @[
|
||||
"dnsaddr=/ip4/127.0.0.1" & $destSwitch.peerInfo.addrs[1][1].tryGet() & "/ws",
|
||||
"dnsaddr=/ip4/127.0.0.1" & $destSwitch.peerInfo.addrs[0][1].tryGet()
|
||||
"dnsaddr=" & $destSwitch.peerInfo.addrs[0],
|
||||
"dnsaddr=" & $destSwitch.peerInfo.addrs[1]
|
||||
]
|
||||
|
||||
let testAddr = MultiAddress.init("/dnsaddr/test.io/").tryGet()
|
||||
|
|
|
@ -17,7 +17,7 @@ suite "TCP transport":
|
|||
checkTrackers()
|
||||
|
||||
asyncTest "test listener: handle write":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
let transport: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
asyncSpawn transport.start(ma)
|
||||
|
||||
|
@ -28,7 +28,7 @@ suite "TCP transport":
|
|||
|
||||
let handlerWait = acceptHandler()
|
||||
|
||||
let streamTransport = await connect(transport.ma)
|
||||
let streamTransport = await connect(transport.addrs[0])
|
||||
|
||||
let msg = await streamTransport.read(6)
|
||||
|
||||
|
@ -38,7 +38,7 @@ suite "TCP transport":
|
|||
check string.fromBytes(msg) == "Hello!"
|
||||
|
||||
asyncTest "test listener: handle read":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
|
||||
|
||||
let transport: TcpTransport = TcpTransport.new(upgrade = Upgrade())
|
||||
asyncSpawn transport.start(ma)
|
||||
|
@ -51,7 +51,7 @@ suite "TCP transport":
|
|||
await conn.close()
|
||||
|
||||
let handlerWait = acceptHandler()
|
||||
let streamTransport: StreamTransport = await connect(transport.ma)
|
||||
let streamTransport: StreamTransport = await connect(transport.addrs[0])
|
||||
let sent = await streamTransport.write("Hello!")
|
||||
|
||||
await handlerWait.wait(1.seconds) # when no issues will not wait that long!
|
||||
|
|
|
@ -171,7 +171,7 @@ proc hexChar*(c: byte, lowercase: bool = false): string =
|
|||
of 0..9: result[1] = chr(t0 + ord('0'))
|
||||
else: result[1] = chr(t0 - 10 + alpha)
|
||||
|
||||
proc toHex*(a: openarray[byte], lowercase: bool = false): string =
|
||||
proc toHex*(a: openArray[byte], lowercase: bool = false): string =
|
||||
result = ""
|
||||
for i in a:
|
||||
result = result & hexChar(i, lowercase)
|
||||
|
@ -263,7 +263,7 @@ suite "Variable integer test suite":
|
|||
buffer.setLen(PBedgeSizes[i])
|
||||
check:
|
||||
PB.putUVarint(buffer, length, PBedgeValues[i]).isOk()
|
||||
buffer.setlen(buffer.high)
|
||||
buffer.setLen(buffer.high)
|
||||
check:
|
||||
PB.getUVarint(buffer, length, value).error() == VarintError.Incomplete
|
||||
|
||||
|
@ -339,7 +339,7 @@ suite "Variable integer test suite":
|
|||
buffer.setLen(LPedgeSizes[i])
|
||||
check:
|
||||
LP.putUVarint(buffer, length, LPedgeValues[i]).isOk()
|
||||
buffer.setlen(buffer.high)
|
||||
buffer.setLen(buffer.high)
|
||||
check:
|
||||
LP.getUVarint(buffer, length, value).error() == VarintError.Incomplete
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ suite "WebSocket transport":
|
|||
"/ip4/0.0.0.0/tcp/0/wss")
|
||||
|
||||
asyncTest "Hostname verification":
|
||||
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0/wss").tryGet()
|
||||
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0/wss").tryGet()]
|
||||
let transport1 = WsTransport.new(Upgrade(), TLSPrivateKey.init(SecureKey), TLSCertificate.init(SecureCert), {TLSFlags.NoVerifyHost})
|
||||
|
||||
await transport1.start(ma)
|
||||
|
@ -84,12 +84,12 @@ suite "WebSocket transport":
|
|||
let handlerWait = acceptHandler()
|
||||
|
||||
# ws.test is in certificate
|
||||
let conn = await transport1.dial("ws.test", transport1.ma)
|
||||
let conn = await transport1.dial("ws.test", transport1.addrs[0])
|
||||
|
||||
await conn.close()
|
||||
|
||||
try:
|
||||
let conn = await transport1.dial("ws.wronghostname", transport1.ma)
|
||||
let conn = await transport1.dial("ws.wronghostname", transport1.addrs[0])
|
||||
check false
|
||||
except CatchableError as exc:
|
||||
check true
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import os
|
||||
import strscans
|
||||
import algorithm
|
||||
import tables
|
||||
import sequtils
|
||||
import strutils
|
||||
import json
|
||||
import osproc
|
||||
|
||||
const PinFile = ".pinned"
|
||||
removeDir("nimbledeps")
|
||||
createDir("nimbledeps")
|
||||
discard execCmd("nimble install -dy")
|
||||
|
||||
var allDeps: Table[string, string]
|
||||
for (_, dependency) in walkDir("nimbledeps/pkgs"):
|
||||
let fileContent = parseJson(readFile(dependency & "/nimblemeta.json"))
|
||||
let url = fileContent.getOrDefault("url").getStr("")
|
||||
var version = fileContent.getOrDefault("vcsRevision").getStr("")
|
||||
var packageName = dependency.split('/')[^1].split('-')[0]
|
||||
|
||||
if version.len == 0:
|
||||
version = execCmdEx("git ls-remote " & url).output.split()[0]
|
||||
|
||||
if version.len > 0 and url.len > 0:
|
||||
let fullPackage = url & "@#" & version
|
||||
if packageName in allDeps and allDeps[packageName] != fullPackage:
|
||||
echo "Warning: duplicate package " & packageName & ":"
|
||||
echo allDeps[packageName]
|
||||
echo fullPackage
|
||||
echo ""
|
||||
allDeps[packageName] = fullPackage
|
||||
else:
|
||||
echo "Failed to get url & version for ", dependency
|
||||
|
||||
let asString = toSeq(allDeps.pairs).mapIt(it[0] & ";" & it[1]).sorted().join("\n")
|
||||
writeFile(PinFile, asString)
|
||||
echo asString
|
Loading…
Reference in New Issue