mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-08-26 07:51:09 +00:00
build(wasm): regenerate edge_builders from libp2p 2.0.0
edge_builders.nim was a stripped copy of libp2p 1.15.2's builders. Against
2.0.0 it does not compile: `{.public.}` was removed from the package
altogether, so the very first proc carrying it fails with "invalid pragma".
It had drifted ~850 lines from the version it is supposed to shadow.
Regenerated from 2.0.0's builders.nim with the same three edits as before --
imports rewritten to absolute `libp2p/...`, the QUIC and WS transports and
their with*Transport builders removed, autotls reduced to opaque stubs -- all
because those reach lsquic and boringssl x86 asm, which cannot build for
wasm32. 2.0.0 already guards the autotls service behind
`libp2p_autotls_support`, so only the two type names needed stubbing.
The edits are now a script rather than a hand-patch, so the next libp2p bump
is a re-run instead of an archaeology exercise.
Also tracks the wasm build script. build/ is gitignored, so it existed only in
one working tree -- the same "one rm -rf from unrecoverable" problem that
b3531ea0 fixed for wasm-deps itself.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qDYE5r2t2dMry5XpWWySu
This commit is contained in:
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/zsh
|
||||
# Build the edge FFI wasm module. Two-step: nim compiles all .o (the -shared
|
||||
# link it attempts fails — known issue), then we link a MAIN module with emcc.
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
source ~/emsdk/emsdk_env.sh >/dev/null 2>&1
|
||||
SHIM=$PWD/library/edge/wasm_shims.h
|
||||
QINC=$PWD/wasm-deps/shim-include
|
||||
# The wasm-deps/{ffi,brokers} overrides are wired in config.nims under
|
||||
# -d:emscripten -- they cannot be passed here, since config-file paths are
|
||||
# registered after the command line and so take precedence over it.
|
||||
nim c --cpu:wasm32 --os:linux --cc:clang --clang.exe:emcc --clang.linkerexe:emcc \
|
||||
--clang.cpp.exe:emcc --clang.cpp.linkerexe:emcc \
|
||||
-d:emscripten -d:disableMarchNative -d:release -d:useMalloc -d:noSignalHandler \
|
||||
--threads:off --mm:orc --debugger:off -d:chronicles_log_level=ERROR --hints:off --warnings:off \
|
||||
--passC:"-include $SHIM -I $QINC -Wno-error=incompatible-pointer-types -Wno-error=incompatible-function-pointer-types -Wno-error=int-conversion" \
|
||||
-o:build/wasm/edge_tmp.js library/edge/edge_lib.nim >/tmp/edgebuild.log 2>&1 || true
|
||||
emcc nimcache/release/edge_lib/*.o -o build/wasm/edge.js \
|
||||
-O3 --no-entry -sEXIT_RUNTIME=0 -sMODULARIZE -sEXPORT_NAME=createEdgeModule -sASYNCIFY \
|
||||
-sALLOW_MEMORY_GROWTH -sSTACK_SIZE=16MB -sALLOW_TABLE_GROWTH \
|
||||
"-sEXPORTED_RUNTIME_METHODS=['ccall','addFunction','removeFunction','UTF8ToString','HEAPU8']" \
|
||||
"-sEXPORTED_FUNCTIONS=['_edge_new','_edge_lightpush_publish','_edge_filter_subscribe','_edge_store_query','_edge_store_connect','_edge_stop','_logosdeliveryedge_set_event_callback','_ffi_poll','_malloc','_free','_wsbridge_on_open','_wsbridge_on_message','_wsbridge_on_close','_wsbridge_on_error']" \
|
||||
-lm
|
||||
echo "built build/wasm/edge.{js,wasm}"
|
||||
@@ -0,0 +1,101 @@
|
||||
import re, sys
|
||||
|
||||
SRC = "nimbledeps/pkgs2/libp2p-2.0.0-327dc7a0cb7e9d0be3d6083841bd496c4cbc48dc/libp2p/builders.nim"
|
||||
DST = "wasm-deps/edge_builders.nim"
|
||||
|
||||
s = open(SRC).read()
|
||||
|
||||
# 1. Rewrite the import block: qualify every module to absolute `libp2p/...`
|
||||
# (Nim keys modules by resolved path, so type identity with the real package
|
||||
# is preserved), and drop the transports that cannot build for wasm32.
|
||||
old_imports = s[s.index("import\n switch,"):s.index("import services/wildcardresolverservice")]
|
||||
new_imports = """import
|
||||
libp2p/switch,
|
||||
libp2p/peerid,
|
||||
libp2p/peerinfo,
|
||||
libp2p/peeraddrpolicy,
|
||||
libp2p/stream/connection,
|
||||
libp2p/multiaddress,
|
||||
libp2p/crypto/crypto,
|
||||
# wstransport and quictransport dropped: ws pulls autotls/service ->
|
||||
# certificate_ffi -> lsquic, quic pulls lsquic + boringssl x86 asm. Neither
|
||||
# builds for wasm32, and a browser edge node uses WsBrowserTransport anyway.
|
||||
libp2p/transports/[transport, tcptransport, memorytransport],
|
||||
libp2p/muxers/[muxer, mplex/mplex, yamux/yamux],
|
||||
libp2p/protocols/[identify, secure/secure, secure/noise, rendezvous, kademlia],
|
||||
libp2p/protocols/connectivity/[
|
||||
autonat/server,
|
||||
autonat/client,
|
||||
autonat/service,
|
||||
autonatv2/server,
|
||||
autonatv2/service,
|
||||
autonatv2/client,
|
||||
relay/relay,
|
||||
relay/client,
|
||||
relay/rtransport,
|
||||
],
|
||||
libp2p/services/[autorelayservice, hpservice, identify_pusher, natservice],
|
||||
libp2p/connmanager,
|
||||
libp2p/upgrademngrs/muxedupgrade,
|
||||
libp2p/observedaddrmanager,
|
||||
libp2p/nameresolving/nameresolver,
|
||||
libp2p/errors,
|
||||
libp2p/utility
|
||||
"""
|
||||
s = s.replace(old_imports, new_imports)
|
||||
s = s.replace("import services/wildcardresolverservice",
|
||||
"import libp2p/services/wildcardresolverservice")
|
||||
|
||||
# 2. TLSPrivateKey/TLSCertificate/TLSFlags came from the dropped wstransport.
|
||||
s = s.replace(" TLSPrivateKey, TLSCertificate, TLSFlags, ServerFlags, connmanager.ConnectionLimits,\n",
|
||||
" ServerFlags, connmanager.ConnectionLimits,\n")
|
||||
|
||||
# 3. autotls/service is dropped with wstransport, but SwitchBuilder still names
|
||||
# its types in field declarations that are NOT behind
|
||||
# `when defined(libp2p_autotls_support)`. Stub them: without that define
|
||||
# nothing ever constructs one, so the fields stay permanently none.
|
||||
anchor = "const MemoryAutoAddress* = memorytransport.MemoryAutoAddress"
|
||||
stub = """# autotls/service is not imported here (it reaches lsquic through
|
||||
# certificate_ffi). These two types are still named by SwitchBuilder fields that
|
||||
# sit outside `when defined(libp2p_autotls_support)`, so declare them as opaque
|
||||
# stubs. libp2p_autotls_support is never defined for the edge build, so nothing
|
||||
# constructs either one and both fields stay Opt.none forever.
|
||||
type
|
||||
AutotlsService* = ref object
|
||||
AutotlsConfig* = ref object
|
||||
|
||||
"""
|
||||
s = s.replace(anchor, stub + anchor)
|
||||
|
||||
# 4. Drop the two transport builders whose transports we removed.
|
||||
for proc_name in ("withWsTransport", "withQuicTransport"):
|
||||
m = re.search(r"^proc " + proc_name + r"\*\(.*?^\n", s, re.S | re.M)
|
||||
assert m, proc_name
|
||||
s = s[:m.start()] + s[m.end():]
|
||||
|
||||
note = """# withWsTransport and withQuicTransport are removed with their transports. The
|
||||
# edge node registers WsBrowserTransport itself and never speaks QUIC.
|
||||
"""
|
||||
s = s.replace("proc withMemoryTransport*", note + "proc withMemoryTransport*", 1)
|
||||
|
||||
header = """# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
# Copyright (c) Status Research & Development GmbH
|
||||
|
||||
## Generated override of libp2p/builders for the wasm/edge build.
|
||||
##
|
||||
## Identical to libp2p 2.0.0's builders.nim EXCEPT that the QUIC and WS
|
||||
## transports (and autotls, which WS drags in) are removed -- they reach lsquic
|
||||
## and boringssl x86 asm, neither of which compiles for wasm32.
|
||||
##
|
||||
## It is a separate module rather than a --path override because Nim resolves a
|
||||
## bare `import libp2p/builders` to the nimble package no matter what --path
|
||||
## says. Regenerate with scripts/gen_edge_builders.py after a libp2p bump.
|
||||
"""
|
||||
s = s.replace("""# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
# Copyright (c) Status Research & Development GmbH
|
||||
|
||||
## This module contains a Switch Building helper.
|
||||
""", header)
|
||||
|
||||
open(DST, "w").write(s)
|
||||
print("wrote", DST, len(s.splitlines()), "lines")
|
||||
+308
-281
@@ -1,35 +1,36 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
# Copyright (c) Status Research & Development GmbH
|
||||
|
||||
## This module contains a Switch Building helper.
|
||||
runnableExamples:
|
||||
let switch = SwitchBuilder.new().withRng(rng).withAddresses(multiaddress)
|
||||
# etc
|
||||
.build()
|
||||
# Copyright (c) Status Research & Development GmbH
|
||||
|
||||
## Generated override of libp2p/builders for the wasm/edge build.
|
||||
##
|
||||
## Identical to libp2p 2.0.0's builders.nim EXCEPT that the QUIC and WS
|
||||
## transports (and autotls, which WS drags in) are removed -- they reach lsquic
|
||||
## and boringssl x86 asm, neither of which compiles for wasm32.
|
||||
##
|
||||
## It is a separate module rather than a --path override because Nim resolves a
|
||||
## bare `import libp2p/builders` to the nimble package no matter what --path
|
||||
## says. Regenerate with scripts/gen_edge_builders.py after a libp2p bump.
|
||||
{.push raises: [].}
|
||||
|
||||
# NOTE: wasm/edge override of libp2p/builders. Identical to upstream EXCEPT the
|
||||
# QUIC transport is removed — quictransport pulls lsquic + boringssl x86 asm that
|
||||
# cannot build for wasm32, and an edge browser node never uses QUIC. Imports are
|
||||
# rewritten to absolute `libp2p/...` form so this single-file override resolves
|
||||
# the rest of the package (Nim keys modules by absolute path, so type identity is
|
||||
# preserved). Placed first on the path via --path so it shadows upstream builders.
|
||||
import options, tables, chronos, chronicles, sequtils
|
||||
import tables, chronos, chronicles, sequtils
|
||||
import
|
||||
libp2p/switch,
|
||||
libp2p/peerid,
|
||||
libp2p/peerinfo,
|
||||
libp2p/peeraddrpolicy,
|
||||
libp2p/stream/connection,
|
||||
libp2p/multiaddress,
|
||||
libp2p/crypto/crypto,
|
||||
# wstransport dropped: it imports autotls/service -> certificate_ffi -> lsquic.
|
||||
# The edge node uses WsBrowserTransport; builders' withWsTransport is removed.
|
||||
# wstransport and quictransport dropped: ws pulls autotls/service ->
|
||||
# certificate_ffi -> lsquic, quic pulls lsquic + boringssl x86 asm. Neither
|
||||
# builds for wasm32, and a browser edge node uses WsBrowserTransport anyway.
|
||||
libp2p/transports/[transport, tcptransport, memorytransport],
|
||||
libp2p/muxers/[muxer, mplex/mplex, yamux/yamux],
|
||||
libp2p/protocols/[identify, secure/secure, secure/noise, rendezvous, kademlia],
|
||||
libp2p/protocols/connectivity/[
|
||||
autonat/server,
|
||||
autonat/client,
|
||||
autonat/service,
|
||||
autonatv2/server,
|
||||
autonatv2/service,
|
||||
autonatv2/client,
|
||||
@@ -37,6 +38,7 @@ import
|
||||
relay/client,
|
||||
relay/rtransport,
|
||||
],
|
||||
libp2p/services/[autorelayservice, hpservice, identify_pusher, natservice],
|
||||
libp2p/connmanager,
|
||||
libp2p/upgrademngrs/muxedupgrade,
|
||||
libp2p/observedaddrmanager,
|
||||
@@ -45,29 +47,31 @@ import
|
||||
libp2p/utility
|
||||
import libp2p/services/wildcardresolverservice
|
||||
|
||||
# autotls is trimmed in the wasm/edge override: its `certificate_ffi` pulls
|
||||
# lsquic/boringssl, which won't build for wasm, and a browser edge node never
|
||||
# provisions TLS certs (the browser's WebSocket handles wss). The field stays as
|
||||
# a never-`Some` stub so the SwitchBuilder shape is otherwise unchanged.
|
||||
type AutotlsService* = ref object
|
||||
export
|
||||
switch, peerid, peerinfo, peeraddrpolicy, connection, multiaddress, crypto, errors,
|
||||
ServerFlags, connmanager.ConnectionLimits,
|
||||
connmanager.maxTotal, connmanager.maxInOut, natservice.NATConfig
|
||||
|
||||
# TLSPrivateKey/TLSCertificate/TLSFlags dropped from exports — they came from the
|
||||
# removed wstransport. ServerFlags stays (from tcptransport).
|
||||
export switch, peerid, peerinfo, connection, multiaddress, crypto, errors, ServerFlags
|
||||
# autotls/service is not imported here (it reaches lsquic through
|
||||
# certificate_ffi). These two types are still named by SwitchBuilder fields that
|
||||
# sit outside `when defined(libp2p_autotls_support)`, so declare them as opaque
|
||||
# stubs. libp2p_autotls_support is never defined for the edge build, so nothing
|
||||
# constructs either one and both fields stay Opt.none forever.
|
||||
type
|
||||
AutotlsService* = ref object
|
||||
AutotlsConfig* = ref object
|
||||
|
||||
const MemoryAutoAddress* = memorytransport.MemoryAutoAddress
|
||||
|
||||
type
|
||||
TransportProvider* {.deprecated: "Use TransportBuilder instead".} =
|
||||
proc(upgr: Upgrade, privateKey: PrivateKey): Transport {.gcsafe, raises: [].}
|
||||
|
||||
TransportBuilder* {.public.} =
|
||||
proc(config: TransportConfig): Transport {.gcsafe, raises: [].}
|
||||
TransportBuilder* = proc(config: TransportConfig): Transport {.gcsafe, raises: [].}
|
||||
|
||||
TransportConfig* = ref object
|
||||
upgr*: Upgrade
|
||||
privateKey*: PrivateKey
|
||||
autotls*: Opt[AutotlsService]
|
||||
connManager*: ConnManager
|
||||
rng*: Rng
|
||||
|
||||
SecureProtocol* {.pure.} = enum
|
||||
Noise
|
||||
@@ -79,32 +83,37 @@ type
|
||||
SwitchBuilder* = ref object
|
||||
privKey: Opt[PrivateKey]
|
||||
addresses: seq[MultiAddress]
|
||||
announcedAddrs: seq[MultiAddress]
|
||||
secureManagers: seq[SecureProtocol]
|
||||
muxers: seq[MuxerProvider]
|
||||
transports: seq[TransportBuilder]
|
||||
rng: ref HmacDrbgContext
|
||||
maxConnections: int
|
||||
maxIn: int
|
||||
sendSignedPeerRecord: bool
|
||||
maxOut: int
|
||||
rng: Rng
|
||||
maxConnsPerPeer: int
|
||||
limits: Opt[ConnectionLimits]
|
||||
watermark: Opt[WatermarkPolicy]
|
||||
scoring: PeerScoring
|
||||
sendSignedPeerRecord: bool
|
||||
protoVersion: string
|
||||
agentVersion: string
|
||||
nameResolver: NameResolver
|
||||
peerStoreCapacity: Opt[int]
|
||||
autonat: bool
|
||||
addressTtls: AddressConfidenceTtls
|
||||
autonatEnabled: bool
|
||||
autonatV2ServerConfig: Opt[AutonatV2Config]
|
||||
autonatV2Client: AutonatV2Client
|
||||
autonatV2ServiceConfig: AutonatV2ServiceConfig
|
||||
autotls: Opt[AutotlsService]
|
||||
autonatV2Service: Opt[AutonatV2Service]
|
||||
hpService: Opt[HPService]
|
||||
natConfig: Opt[NATConfig]
|
||||
autotlsConfig: Opt[AutotlsConfig]
|
||||
circuitRelay: Opt[Relay]
|
||||
rdv: Opt[RendezVous]
|
||||
rdvConfig: Opt[RendezVousConfig]
|
||||
kad: Opt[KadInfo]
|
||||
services: seq[Service]
|
||||
identifyPusherEnabled: bool
|
||||
observedAddrManager: ObservedAddrManager
|
||||
enableWildcardResolver: bool
|
||||
addressPolicy: PeerAddressPolicy
|
||||
|
||||
proc new*(T: type[SwitchBuilder]): T {.public.} =
|
||||
proc new*(T: type[SwitchBuilder]): T =
|
||||
## Creates a SwitchBuilder
|
||||
|
||||
let address =
|
||||
@@ -114,22 +123,23 @@ proc new*(T: type[SwitchBuilder]): T {.public.} =
|
||||
privKey: Opt.none(PrivateKey),
|
||||
addresses: @[address],
|
||||
secureManagers: @[],
|
||||
maxConnections: MaxConnections,
|
||||
maxIn: -1,
|
||||
maxOut: -1,
|
||||
maxConnsPerPeer: MaxConnectionsPerPeer,
|
||||
maxConnsPerPeer: -1,
|
||||
limits: Opt.none(ConnectionLimits),
|
||||
watermark: Opt.none(WatermarkPolicy),
|
||||
scoring: PeerScoring(),
|
||||
protoVersion: ProtoVersion,
|
||||
agentVersion: AgentVersion,
|
||||
autotls: Opt.none(AutotlsService),
|
||||
autotlsConfig: Opt.none(AutotlsConfig),
|
||||
circuitRelay: Opt.none(Relay),
|
||||
rdv: Opt.none(RendezVous),
|
||||
rdvConfig: Opt.none(RendezVousConfig),
|
||||
kad: Opt.none(KadInfo),
|
||||
identifyPusherEnabled: true,
|
||||
enableWildcardResolver: true,
|
||||
addressPolicy: defaultAddressPolicy,
|
||||
addressTtls: AddressConfidenceTtls(),
|
||||
)
|
||||
|
||||
proc withPrivateKey*(
|
||||
b: SwitchBuilder, privateKey: PrivateKey
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withPrivateKey*(b: SwitchBuilder, privateKey: PrivateKey): SwitchBuilder =
|
||||
## Set the private key of the switch. Will be used to
|
||||
## generate a PeerId
|
||||
|
||||
@@ -138,7 +148,7 @@ proc withPrivateKey*(
|
||||
|
||||
proc withAddresses*(
|
||||
b: SwitchBuilder, addresses: seq[MultiAddress], enableWildcardResolver: bool = true
|
||||
): SwitchBuilder {.public.} =
|
||||
): SwitchBuilder =
|
||||
## | Set the listening addresses of the switch
|
||||
## | Calling it multiple time will override the value
|
||||
b.addresses = addresses
|
||||
@@ -147,21 +157,36 @@ proc withAddresses*(
|
||||
|
||||
proc withAddress*(
|
||||
b: SwitchBuilder, address: MultiAddress, enableWildcardResolver: bool = true
|
||||
): SwitchBuilder {.public.} =
|
||||
): SwitchBuilder =
|
||||
## | Set the listening address of the switch
|
||||
## | Calling it multiple time will override the value
|
||||
b.withAddresses(@[address], enableWildcardResolver)
|
||||
|
||||
proc withSignedPeerRecord*(b: SwitchBuilder, sendIt = true): SwitchBuilder {.public.} =
|
||||
proc withAnnouncedAddresses*(
|
||||
b: SwitchBuilder, addresses: seq[MultiAddress]
|
||||
): SwitchBuilder =
|
||||
## Set explicit addresses to advertise to peers, distinct from the
|
||||
## switch's listening addresses. When non-empty, these replace the output
|
||||
## of the address mapper chain (the `addressPolicy` filter is still applied).
|
||||
## Use this to announce a public NAT-mapped address while binding locally.
|
||||
## Calling it multiple times overrides the previous value.
|
||||
b.announcedAddrs = addresses
|
||||
b
|
||||
|
||||
proc withAnnouncedAddress*(b: SwitchBuilder, address: MultiAddress): SwitchBuilder =
|
||||
## Set a single announced address. See `withAnnouncedAddresses`.
|
||||
b.withAnnouncedAddresses(@[address])
|
||||
|
||||
proc withSignedPeerRecord*(b: SwitchBuilder, sendIt = true): SwitchBuilder =
|
||||
b.sendSignedPeerRecord = sendIt
|
||||
b
|
||||
|
||||
proc withMplex*(
|
||||
b: SwitchBuilder, inTimeout = 5.minutes, outTimeout = 5.minutes, maxChannCount = 200
|
||||
): SwitchBuilder {.public.} =
|
||||
): SwitchBuilder =
|
||||
## | Uses `Mplex <https://docs.libp2p.io/concepts/stream-multiplexing/#mplex>`_ as a multiplexer
|
||||
## | `Timeout` is the duration after which a inactive connection will be closed
|
||||
proc newMuxer(conn: Connection): Muxer =
|
||||
proc newMuxer(conn: RawConn): Muxer =
|
||||
Mplex.new(conn, inTimeout, outTimeout, maxChannCount)
|
||||
|
||||
assert b.muxers.countIt(it.codec == MplexCodec) == 0, "Mplex build multiple times"
|
||||
@@ -175,7 +200,7 @@ proc withYamux*(
|
||||
inTimeout: Duration = 5.minutes,
|
||||
outTimeout: Duration = 5.minutes,
|
||||
): SwitchBuilder =
|
||||
proc newMuxer(conn: Connection): Muxer =
|
||||
proc newMuxer(conn: RawConn): Muxer =
|
||||
Yamux.new(
|
||||
conn,
|
||||
maxChannCount = maxChannCount,
|
||||
@@ -188,111 +213,112 @@ proc withYamux*(
|
||||
b.muxers.add(MuxerProvider.new(newMuxer, YamuxCodec))
|
||||
b
|
||||
|
||||
proc withNoise*(b: SwitchBuilder): SwitchBuilder {.public.} =
|
||||
proc withNoise*(b: SwitchBuilder): SwitchBuilder =
|
||||
b.secureManagers.add(SecureProtocol.Noise)
|
||||
b
|
||||
|
||||
proc withTransport*(
|
||||
b: SwitchBuilder, prov: TransportBuilder
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withTransport*(b: SwitchBuilder, prov: TransportBuilder): SwitchBuilder =
|
||||
## Use a custom transport
|
||||
runnableExamples:
|
||||
let switch = SwitchBuilder
|
||||
.new()
|
||||
.withTransport(
|
||||
proc(config: TransportConfig): Transport =
|
||||
TcpTransport.new(flags, config.upgr)
|
||||
)
|
||||
.build()
|
||||
b.transports.add(prov)
|
||||
b
|
||||
|
||||
proc withTransport*(
|
||||
b: SwitchBuilder, prov: TransportProvider
|
||||
): SwitchBuilder {.deprecated: "Use TransportBuilder instead".} =
|
||||
## Use a custom transport
|
||||
runnableExamples:
|
||||
let switch = SwitchBuilder
|
||||
.new()
|
||||
.withTransport(
|
||||
proc(upgr: Upgrade, privateKey: PrivateKey): Transport =
|
||||
TcpTransport.new(flags, upgr)
|
||||
)
|
||||
.build()
|
||||
let tBuilder: TransportBuilder = proc(config: TransportConfig): Transport =
|
||||
prov(config.upgr, config.privateKey)
|
||||
b.withTransport(tBuilder)
|
||||
|
||||
proc withTcpTransport*(
|
||||
b: SwitchBuilder, flags: set[ServerFlags] = {}
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withTcpTransport*(b: SwitchBuilder, flags: set[ServerFlags] = {}): SwitchBuilder =
|
||||
b.withTransport(
|
||||
proc(config: TransportConfig): Transport =
|
||||
TcpTransport.new(flags, config.upgr)
|
||||
)
|
||||
|
||||
# withWsTransport removed in the wasm/edge override: it threads `config.autotls`
|
||||
# into the real WsTransport, and the edge node uses the browser-WebSocket
|
||||
# transport instead. (withQuicTransport removed too — no QUIC in the browser.)
|
||||
|
||||
proc withMemoryTransport*(b: SwitchBuilder): SwitchBuilder {.public.} =
|
||||
# withWsTransport and withQuicTransport are removed with their transports. The
|
||||
# edge node registers WsBrowserTransport itself and never speaks QUIC.
|
||||
proc withMemoryTransport*(b: SwitchBuilder): SwitchBuilder =
|
||||
b.withTransport(
|
||||
proc(config: TransportConfig): Transport =
|
||||
MemoryTransport.new(config.upgr)
|
||||
MemoryTransport.new(config.upgr, config.rng)
|
||||
)
|
||||
|
||||
proc withRng*(b: SwitchBuilder, rng: ref HmacDrbgContext): SwitchBuilder {.public.} =
|
||||
proc withRng*(b: SwitchBuilder, rng: Rng): SwitchBuilder =
|
||||
b.rng = rng
|
||||
b
|
||||
|
||||
proc withMaxConnections*(
|
||||
b: SwitchBuilder, maxConnections: int
|
||||
): SwitchBuilder {.public.} =
|
||||
## Maximum concurrent connections of the switch. You should either use this, or
|
||||
## `withMaxIn <#withMaxIn,SwitchBuilder,int>`_ & `withMaxOut<#withMaxOut,SwitchBuilder,int>`_
|
||||
b.maxConnections = maxConnections
|
||||
proc withConnectionLimits*(b: SwitchBuilder, limits: ConnectionLimits): SwitchBuilder =
|
||||
## Set the connection limits for the switch. Construct `limits` via
|
||||
## `ConnectionLimits.maxTotal` for a shared cap or `ConnectionLimits.maxInOut`
|
||||
## for independent per-direction caps.
|
||||
b.limits = Opt.some(limits)
|
||||
b
|
||||
|
||||
proc withMaxIn*(b: SwitchBuilder, maxIn: int): SwitchBuilder {.public.} =
|
||||
## Maximum concurrent incoming connections. Should be used with `withMaxOut<#withMaxOut,SwitchBuilder,int>`_
|
||||
b.maxIn = maxIn
|
||||
proc withMaxConnections*(b: SwitchBuilder, maxConnections: int): SwitchBuilder =
|
||||
## Maximum concurrent connections of the switch. You should either use this,
|
||||
## or `withMaxInOut <#withMaxInOut,SwitchBuilder,int,int>`_.
|
||||
b.limits = Opt.some(ConnectionLimits.maxTotal(maxConnections))
|
||||
b
|
||||
|
||||
proc withMaxOut*(b: SwitchBuilder, maxOut: int): SwitchBuilder {.public.} =
|
||||
## Maximum concurrent outgoing connections. Should be used with `withMaxIn<#withMaxIn,SwitchBuilder,int>`_
|
||||
b.maxOut = maxOut
|
||||
proc withMaxInOut*(b: SwitchBuilder, maxIn: int, maxOut: int): SwitchBuilder =
|
||||
## Maximum concurrent incoming and outgoing connections.
|
||||
b.limits = Opt.some(ConnectionLimits.maxInOut(maxIn, maxOut))
|
||||
b
|
||||
|
||||
proc withMaxConnsPerPeer*(
|
||||
b: SwitchBuilder, maxConnsPerPeer: int
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withMaxConnsPerPeer*(b: SwitchBuilder, maxConnsPerPeer: int): SwitchBuilder =
|
||||
b.maxConnsPerPeer = maxConnsPerPeer
|
||||
b
|
||||
|
||||
proc withPeerStore*(b: SwitchBuilder, capacity: int): SwitchBuilder {.public.} =
|
||||
proc withWatermarkPolicy*(
|
||||
b: SwitchBuilder,
|
||||
lowWater: int,
|
||||
highWater: int,
|
||||
gracePeriod: Duration = 0.minutes,
|
||||
silencePeriod: Duration = 10.seconds,
|
||||
): SwitchBuilder =
|
||||
## Enable hi/lo watermark connection management.
|
||||
## When connected peers exceed `highWater`, the connection manager trims
|
||||
## down to `lowWater`, skipping peers within `gracePeriod` and protected peers.
|
||||
## Can be combined with `withMaxConnections`/`withMaxInOut` to apply both
|
||||
## a hard semaphore cap and active trimming simultaneously.
|
||||
doAssert lowWater > 0, "lowWater must be > 0"
|
||||
doAssert highWater > lowWater, "highWater must be > lowWater"
|
||||
b.watermark = Opt.some(
|
||||
WatermarkPolicy(
|
||||
lowWater: lowWater,
|
||||
highWater: highWater,
|
||||
gracePeriod: gracePeriod,
|
||||
silencePeriod: silencePeriod,
|
||||
)
|
||||
)
|
||||
b
|
||||
|
||||
proc withPeerScoring*(
|
||||
b: SwitchBuilder, scoring: PeerScoring = PeerScoring()
|
||||
): SwitchBuilder =
|
||||
## Configure peer scoring parameters.
|
||||
doAssert scoring.decayResolution > 0.seconds, "decayResolution must be > 0"
|
||||
b.scoring = scoring
|
||||
b
|
||||
|
||||
proc withPeerStore*(b: SwitchBuilder, capacity: int): SwitchBuilder =
|
||||
b.peerStoreCapacity = Opt.some(capacity)
|
||||
b
|
||||
|
||||
proc withProtoVersion*(
|
||||
b: SwitchBuilder, protoVersion: string
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withAddressConfidenceTtls*(
|
||||
b: SwitchBuilder, ttls: AddressConfidenceTtls
|
||||
): SwitchBuilder =
|
||||
## Override the per-confidence TTLs used to expire peer addresses.
|
||||
b.addressTtls = ttls
|
||||
b
|
||||
|
||||
proc withProtoVersion*(b: SwitchBuilder, protoVersion: string): SwitchBuilder =
|
||||
b.protoVersion = protoVersion
|
||||
b
|
||||
|
||||
proc withAgentVersion*(
|
||||
b: SwitchBuilder, agentVersion: string
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withAgentVersion*(b: SwitchBuilder, agentVersion: string): SwitchBuilder =
|
||||
b.agentVersion = agentVersion
|
||||
b
|
||||
|
||||
proc withNameResolver*(
|
||||
b: SwitchBuilder, nameResolver: NameResolver
|
||||
): SwitchBuilder {.public.} =
|
||||
proc withNameResolver*(b: SwitchBuilder, nameResolver: NameResolver): SwitchBuilder =
|
||||
b.nameResolver = nameResolver
|
||||
b
|
||||
|
||||
proc withAutonat*(b: SwitchBuilder): SwitchBuilder =
|
||||
b.autonat = true
|
||||
proc withAutonat*(b: SwitchBuilder, enabled: bool = true): SwitchBuilder =
|
||||
b.autonatEnabled = enabled
|
||||
b
|
||||
|
||||
proc withAutonatV2Server*(
|
||||
@@ -302,29 +328,59 @@ proc withAutonatV2Server*(
|
||||
b
|
||||
|
||||
proc withAutonatV2*(
|
||||
b: SwitchBuilder, serviceConfig = AutonatV2ServiceConfig.new()
|
||||
b: SwitchBuilder,
|
||||
serviceConfig: AutonatV2ServiceConfig = AutonatV2ServiceConfig.new(),
|
||||
): SwitchBuilder =
|
||||
b.autonatV2Client = AutonatV2Client.new(b.rng)
|
||||
b.autonatV2ServiceConfig = serviceConfig
|
||||
b.autonatV2Service = Opt.some(
|
||||
AutonatV2Service.new(b.rng, client = b.autonatV2Client, config = serviceConfig)
|
||||
)
|
||||
b
|
||||
|
||||
proc withNAT*(b: SwitchBuilder, config: NATConfig): SwitchBuilder =
|
||||
## Enable a NAT traversal service.
|
||||
## TODO: wire in autonat / hole-punching.
|
||||
b.natConfig = Opt.some(config)
|
||||
b
|
||||
|
||||
proc withHolePunching*(
|
||||
b: SwitchBuilder, maxNumRelays: int, onReservationHandler: proc
|
||||
): SwitchBuilder =
|
||||
let
|
||||
autonatService = AutonatService.new(AutonatClient(), b.rng)
|
||||
autoRelayService =
|
||||
AutoRelayService.new(maxNumRelays, RelayClient.new(), onReservationHandler, b.rng)
|
||||
hpService = HPService.new(autonatService, autoRelayService)
|
||||
|
||||
b.hpService = Opt.some(hpService)
|
||||
b
|
||||
|
||||
when defined(libp2p_autotls_support):
|
||||
proc withAutotls*(
|
||||
b: SwitchBuilder, config: AutotlsConfig = AutotlsConfig.new()
|
||||
): SwitchBuilder {.public.} =
|
||||
b.autotls = Opt.some(AutotlsService.new(config = config))
|
||||
): SwitchBuilder =
|
||||
if config.isNil:
|
||||
b.autotlsConfig = Opt.none(AutotlsConfig)
|
||||
else:
|
||||
b.autotlsConfig = Opt.some(config)
|
||||
b
|
||||
|
||||
proc withCircuitRelay*(b: SwitchBuilder, r: Relay = Relay.new()): SwitchBuilder =
|
||||
b.circuitRelay = Opt.some(r)
|
||||
if r.isNil:
|
||||
b.circuitRelay = Opt.none(Relay)
|
||||
else:
|
||||
b.circuitRelay = Opt.some(r)
|
||||
|
||||
b
|
||||
|
||||
proc withRendezVous*(b: SwitchBuilder, rdv: RendezVous): SwitchBuilder =
|
||||
var lrdv = rdv
|
||||
if rdv.isNil():
|
||||
lrdv = RendezVous.new()
|
||||
proc withRendezVous*(
|
||||
b: SwitchBuilder, config: RendezVousConfig = RendezVousConfig.new()
|
||||
): SwitchBuilder =
|
||||
if config.isNil:
|
||||
b.rdvConfig = Opt.none(RendezVousConfig)
|
||||
else:
|
||||
b.rdvConfig = Opt.some(config)
|
||||
|
||||
b.rdv = Opt.some(lrdv)
|
||||
b
|
||||
|
||||
proc withKademlia*(
|
||||
@@ -335,8 +391,12 @@ proc withKademlia*(
|
||||
b.kad = Opt.some(KadInfo(config: config, bootstrapNodes: bootstrapNodes))
|
||||
b
|
||||
|
||||
proc withServices*(b: SwitchBuilder, services: seq[Service]): SwitchBuilder =
|
||||
b.services = services
|
||||
proc withIdentifyPusher*(b: SwitchBuilder, enabled: bool = true): SwitchBuilder =
|
||||
## When enabled, the IdentifyPush protocol is mounted on the
|
||||
## switch and an `IdentifyPusher` service tracks which connected peers
|
||||
## advertise IdentifyPush, broadcasting our updated `PeerInfo` to all
|
||||
## tracked peers whenever it changes.
|
||||
b.identifyPusherEnabled = enabled
|
||||
b
|
||||
|
||||
proc withObservedAddrManager*(
|
||||
@@ -345,11 +405,30 @@ proc withObservedAddrManager*(
|
||||
b.observedAddrManager = observedAddrManager
|
||||
b
|
||||
|
||||
proc build*(b: SwitchBuilder): Switch {.raises: [LPError], public.} =
|
||||
proc withAddressPolicy*(
|
||||
b: SwitchBuilder, addressPolicy: PeerAddressPolicy
|
||||
): SwitchBuilder =
|
||||
## Applies a single address visibility policy across local address
|
||||
## announcements and all discovery/storage paths configured by the builder.
|
||||
b.addressPolicy = addressPolicy
|
||||
b
|
||||
|
||||
proc withPrivateAddressFilter*(b: SwitchBuilder): SwitchBuilder =
|
||||
## Filter private (RFC1918/link-local) addresses from all peer address
|
||||
## announcements and incoming peer address records. When enabled:
|
||||
## - Our node will not announce private addresses to the network
|
||||
## - Private addresses received from other peers are discarded
|
||||
## Circuit relay and DNS addresses are never filtered.
|
||||
b.withAddressPolicy(publicRoutableAddressPolicy)
|
||||
|
||||
proc buildSwitch(b: SwitchBuilder): Switch {.raises: [LPError].} =
|
||||
if isNil(b.rng):
|
||||
b.rng = newRng()
|
||||
|
||||
if b.rng == nil: # newRng could fail
|
||||
raise newException(Defect, "Cannot initialize RNG")
|
||||
|
||||
let pkRes = PrivateKey.random(b.rng[])
|
||||
let pkRes = PrivateKey.random(b.rng)
|
||||
let seckey = b.privKey.get(otherwise = pkRes.expect("Expected default Private Key"))
|
||||
|
||||
if b.secureManagers.len == 0:
|
||||
@@ -361,7 +440,12 @@ proc build*(b: SwitchBuilder): Switch {.raises: [LPError], public.} =
|
||||
secureManagerInstances.add(Noise.new(b.rng, seckey).Secure)
|
||||
|
||||
let peerInfo = PeerInfo.new(
|
||||
seckey, b.addresses, protoVersion = b.protoVersion, agentVersion = b.agentVersion
|
||||
seckey,
|
||||
b.addresses,
|
||||
protoVersion = b.protoVersion,
|
||||
agentVersion = b.agentVersion,
|
||||
addressPolicy = b.addressPolicy,
|
||||
announcedAddrs = b.announcedAddrs,
|
||||
)
|
||||
|
||||
let identify =
|
||||
@@ -370,178 +454,121 @@ proc build*(b: SwitchBuilder): Switch {.raises: [LPError], public.} =
|
||||
else:
|
||||
Identify.new(peerInfo, b.sendSignedPeerRecord)
|
||||
|
||||
let
|
||||
connManager =
|
||||
ConnManager.new(b.maxConnsPerPeer, b.maxConnections, b.maxIn, b.maxOut)
|
||||
ms = MultistreamSelect.new()
|
||||
muxedUpgrade = MuxedUpgrade.new(b.muxers, secureManagerInstances, ms)
|
||||
|
||||
# autotls service is never created in the edge override (field is always none).
|
||||
|
||||
let transports = block:
|
||||
var transports: seq[Transport]
|
||||
for tProvider in b.transports:
|
||||
transports.add(
|
||||
tProvider(
|
||||
TransportConfig(upgr: muxedUpgrade, privateKey: seckey, autotls: b.autotls)
|
||||
)
|
||||
)
|
||||
transports
|
||||
|
||||
if b.secureManagers.len == 0:
|
||||
b.secureManagers &= SecureProtocol.Noise
|
||||
|
||||
if isNil(b.rng):
|
||||
b.rng = newRng()
|
||||
|
||||
let peerStore = block:
|
||||
var peerStore = block:
|
||||
b.peerStoreCapacity.withValue(capacity):
|
||||
PeerStore.new(identify, capacity)
|
||||
PeerStore.new(identify, capacity, b.addressTtls)
|
||||
else:
|
||||
PeerStore.new(identify)
|
||||
PeerStore.new(identify, addressTtls = b.addressTtls)
|
||||
peerStore.addressPolicy = b.addressPolicy
|
||||
|
||||
if b.enableWildcardResolver:
|
||||
b.services.add(WildcardAddressResolverService.new())
|
||||
var connManager = ConnManager.new(
|
||||
maxConnsPerPeer = b.maxConnsPerPeer,
|
||||
limits = b.limits,
|
||||
watermark = b.watermark,
|
||||
scoring = b.scoring,
|
||||
)
|
||||
connManager.peerStore = peerStore
|
||||
|
||||
if not isNil(b.autonatV2Client):
|
||||
b.services.add(
|
||||
AutonatV2Service.new(
|
||||
b.rng, client = b.autonatV2Client, config = b.autonatV2ServiceConfig
|
||||
let ms = MultistreamSelect.new()
|
||||
let muxedUpgrade = MuxedUpgrade.new(b.muxers, secureManagerInstances, ms, connManager)
|
||||
|
||||
var services: seq[Service]
|
||||
var autotlsOpt = Opt.none(AutotlsService)
|
||||
when defined(libp2p_autotls_support):
|
||||
b.autotlsConfig.withValue(config):
|
||||
let autotlsService = AutotlsService.new(b.rng, config)
|
||||
autotlsOpt = Opt.some(autotlsService)
|
||||
services.add(autotlsService)
|
||||
|
||||
var transports: seq[Transport]
|
||||
for tProvider in b.transports:
|
||||
transports.add(
|
||||
tProvider(
|
||||
TransportConfig(
|
||||
upgr: muxedUpgrade,
|
||||
privateKey: seckey,
|
||||
autotls: autotlsOpt,
|
||||
connManager: connManager,
|
||||
rng: b.rng,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
let switch = newSwitch(
|
||||
peerInfo = peerInfo,
|
||||
transports = transports,
|
||||
secureManagers = secureManagerInstances,
|
||||
connManager = connManager,
|
||||
ms = ms,
|
||||
nameResolver = b.nameResolver,
|
||||
peerStore = peerStore,
|
||||
services = b.services,
|
||||
let dialer =
|
||||
Dialer.new(peerInfo.peerId, connManager, peerStore, transports, ms, b.nameResolver)
|
||||
|
||||
let switch = Switch(
|
||||
peerInfo: peerInfo,
|
||||
ms: ms,
|
||||
transports: transports,
|
||||
connManager: connManager,
|
||||
peerStore: peerStore,
|
||||
dialer: dialer,
|
||||
nameResolver: b.nameResolver,
|
||||
rng: b.rng,
|
||||
muxedUpgrade: muxedUpgrade,
|
||||
services: services,
|
||||
)
|
||||
|
||||
switch.mount(identify)
|
||||
return switch
|
||||
|
||||
if not isNil(b.autonatV2Client):
|
||||
proc setupServices(b: SwitchBuilder, switch: Switch) {.raises: [LPError].} =
|
||||
if b.enableWildcardResolver:
|
||||
switch.services.add(WildcardAddressResolverService.new())
|
||||
|
||||
b.autonatV2Service.withValue(autonatV2Service):
|
||||
switch.services.add(autonatV2Service)
|
||||
|
||||
b.hpService.withValue(hpservice):
|
||||
switch.services.add(hpservice)
|
||||
|
||||
b.natConfig.withValue(natCfg):
|
||||
switch.services.add(NATService.new(natCfg))
|
||||
|
||||
if b.identifyPusherEnabled:
|
||||
switch.services.add(IdentifyPusher.new())
|
||||
|
||||
for service in switch.services:
|
||||
service.setup(switch)
|
||||
|
||||
proc mountProtocols(b: SwitchBuilder, switch: Switch) {.raises: [LPError].} =
|
||||
if not switch.peerStore.identify.isNil:
|
||||
switch.mount(switch.peerStore.identify)
|
||||
|
||||
if not b.autonatV2Client.isNil:
|
||||
b.autonatV2Client.setup(switch)
|
||||
switch.mount(b.autonatV2Client)
|
||||
|
||||
b.rdvConfig.withValue(rdvCfg):
|
||||
let rend = RendezVous.new(b.rng, rdvCfg)
|
||||
rend.setup(switch)
|
||||
switch.mount(rend)
|
||||
|
||||
b.autonatV2ServerConfig.withValue(config):
|
||||
switch.mount(AutonatV2.new(switch, config = config))
|
||||
|
||||
if b.autonat:
|
||||
if b.autonatEnabled:
|
||||
switch.mount(Autonat.new(switch))
|
||||
|
||||
b.circuitRelay.withValue(relay):
|
||||
if relay of RelayClient:
|
||||
switch.addTransport(RelayTransport.new(RelayClient(relay), muxedUpgrade))
|
||||
switch.addTransport(RelayTransport.new(RelayClient(relay), switch.muxedUpgrade))
|
||||
relay.setup(switch)
|
||||
switch.mount(relay)
|
||||
|
||||
b.rdv.withValue(rdvService):
|
||||
rdvService.setup(switch)
|
||||
switch.mount(rdvService)
|
||||
|
||||
b.kad.withValue(kadInfo):
|
||||
kadInfo.config.addressPolicy = b.addressPolicy
|
||||
let kad = KadDHT.new(
|
||||
switch, bootstrapNodes = kadInfo.bootstrapNodes, config = kadInfo.config
|
||||
switch,
|
||||
bootstrapNodes = kadInfo.bootstrapNodes,
|
||||
config = kadInfo.config,
|
||||
rng = b.rng,
|
||||
)
|
||||
switch.mount(kad)
|
||||
|
||||
proc build*(b: SwitchBuilder): Switch {.raises: [LPError].} =
|
||||
var switch = b.buildSwitch()
|
||||
b.setupServices(switch)
|
||||
b.mountProtocols(switch)
|
||||
|
||||
return switch
|
||||
|
||||
type TransportType* {.pure.} = enum
|
||||
TCP
|
||||
Memory
|
||||
|
||||
proc newStandardSwitchBuilder*(
|
||||
privKey = Opt.none(PrivateKey),
|
||||
addrs: MultiAddress | seq[MultiAddress] = newSeq[MultiAddress](),
|
||||
transport: TransportType = TransportType.TCP,
|
||||
transportFlags: set[ServerFlags] = {},
|
||||
rng = newRng(),
|
||||
secureManagers: openArray[SecureProtocol] = [SecureProtocol.Noise],
|
||||
inTimeout: Duration = 5.minutes,
|
||||
outTimeout: Duration = 5.minutes,
|
||||
maxConnections = MaxConnections,
|
||||
maxIn = -1,
|
||||
maxOut = -1,
|
||||
maxConnsPerPeer = MaxConnectionsPerPeer,
|
||||
nameResolver = Opt.none(NameResolver),
|
||||
sendSignedPeerRecord = false,
|
||||
peerStoreCapacity = 1000,
|
||||
): SwitchBuilder {.raises: [LPError], public.} =
|
||||
## Helper for common switch configurations.
|
||||
var b = SwitchBuilder
|
||||
.new()
|
||||
.withRng(rng)
|
||||
.withSignedPeerRecord(sendSignedPeerRecord)
|
||||
.withMaxConnections(maxConnections)
|
||||
.withMaxIn(maxIn)
|
||||
.withMaxOut(maxOut)
|
||||
.withMaxConnsPerPeer(maxConnsPerPeer)
|
||||
.withPeerStore(capacity = peerStoreCapacity)
|
||||
.withNoise()
|
||||
|
||||
privKey.withValue(pkey):
|
||||
b = b.withPrivateKey(pkey)
|
||||
|
||||
nameResolver.withValue(nr):
|
||||
b = b.withNameResolver(nr)
|
||||
|
||||
var addrs =
|
||||
when addrs is MultiAddress:
|
||||
@[addrs]
|
||||
else:
|
||||
addrs
|
||||
|
||||
case transport
|
||||
of TransportType.TCP:
|
||||
if addrs.len == 0:
|
||||
addrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet()]
|
||||
b = b.withTcpTransport(transportFlags).withAddresses(addrs).withMplex(
|
||||
inTimeout, outTimeout
|
||||
)
|
||||
of TransportType.Memory:
|
||||
if addrs.len == 0:
|
||||
addrs = @[MultiAddress.init(MemoryAutoAddress).tryGet()]
|
||||
b = b.withMemoryTransport().withAddresses(addrs).withMplex(inTimeout, outTimeout)
|
||||
|
||||
b
|
||||
|
||||
proc newStandardSwitch*(
|
||||
privKey = Opt.none(PrivateKey),
|
||||
addrs: MultiAddress | seq[MultiAddress] = newSeq[MultiAddress](),
|
||||
transport: TransportType = TransportType.TCP,
|
||||
transportFlags: set[ServerFlags] = {},
|
||||
rng = newRng(),
|
||||
secureManagers: openArray[SecureProtocol] = [SecureProtocol.Noise],
|
||||
inTimeout: Duration = 5.minutes,
|
||||
outTimeout: Duration = 5.minutes,
|
||||
maxConnections = MaxConnections,
|
||||
maxIn = -1,
|
||||
maxOut = -1,
|
||||
maxConnsPerPeer = MaxConnectionsPerPeer,
|
||||
nameResolver = Opt.none(NameResolver),
|
||||
sendSignedPeerRecord = false,
|
||||
peerStoreCapacity = 1000,
|
||||
): Switch {.raises: [LPError], public.} =
|
||||
newStandardSwitchBuilder(
|
||||
privKey = privKey,
|
||||
addrs = addrs,
|
||||
transport = transport,
|
||||
transportFlags = transportFlags,
|
||||
rng = rng,
|
||||
secureManagers = secureManagers,
|
||||
inTimeout = inTimeout,
|
||||
outTimeout = outTimeout,
|
||||
maxConnections = maxConnections,
|
||||
maxIn = maxIn,
|
||||
maxOut = maxOut,
|
||||
maxConnsPerPeer = maxConnsPerPeer,
|
||||
nameResolver = nameResolver,
|
||||
sendSignedPeerRecord = sendSignedPeerRecord,
|
||||
peerStoreCapacity = peerStoreCapacity,
|
||||
)
|
||||
.build()
|
||||
|
||||
Reference in New Issue
Block a user