2021-11-02 10:29:11 +00:00
|
|
|
|
# Waku Switch utils.
|
2024-06-28 16:04:57 +05:30
|
|
|
|
{.push raises: [].}
|
2022-10-28 12:51:46 +03:00
|
|
|
|
|
2021-11-02 10:29:11 +00:00
|
|
|
|
import
|
2024-05-16 22:29:11 +02:00
|
|
|
|
std/options,
|
2024-03-16 00:08:47 +01:00
|
|
|
|
chronos,
|
|
|
|
|
|
chronicles,
|
2021-11-02 10:29:11 +00:00
|
|
|
|
eth/keys,
|
|
|
|
|
|
libp2p/crypto/crypto,
|
2026-06-04 16:54:44 +05:30
|
|
|
|
libp2p/crypto/rng as libp2p_rng,
|
2021-11-02 10:29:11 +00:00
|
|
|
|
libp2p/protocols/pubsub/gossipsub,
|
2023-06-01 21:43:10 +02:00
|
|
|
|
libp2p/protocols/rendezvous,
|
2024-10-28 09:17:46 +01:00
|
|
|
|
libp2p/protocols/connectivity/relay/relay,
|
2021-11-02 10:29:11 +00:00
|
|
|
|
libp2p/nameresolving/nameresolver,
|
|
|
|
|
|
libp2p/builders,
|
2023-01-11 10:57:49 +01:00
|
|
|
|
libp2p/switch,
|
2021-11-02 10:29:11 +00:00
|
|
|
|
libp2p/transports/[transport, tcptransport, wstransport]
|
|
|
|
|
|
|
2022-11-29 17:35:25 +01:00
|
|
|
|
# override nim-libp2p default value (which is also 1)
|
|
|
|
|
|
const MaxConnectionsPerPeer* = 1
|
|
|
|
|
|
|
2026-06-04 16:54:44 +05:30
|
|
|
|
# libp2p 1.15.3 ships a built-in `withWsTransport` matching this name, so
|
|
|
|
|
|
# the plain-WS wrapper that used to live here is now redundant. Callers
|
|
|
|
|
|
# that did `b.withWsTransport()` resolve to libp2p's overload (zero args =
|
|
|
|
|
|
# no TLS, no flags). Callers passing `tlsPrivateKey=`/`tlsCertificate=`
|
|
|
|
|
|
# also use libp2p's built-in.
|
|
|
|
|
|
|
|
|
|
|
|
# nim-libp2p#2329 made libp2p's MaxConnections const private (renamed to
|
|
|
|
|
|
# DefaultMaxConnections); redeclare here to keep waku's cap explicit.
|
|
|
|
|
|
const MaxConnections* = 50
|
2021-11-02 10:29:11 +00:00
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
|
proc getSecureKey(path: string): TLSPrivateKey {.raises: [Defect, IOError].} =
|
|
|
|
|
|
trace "Key path is.", path = path
|
2022-10-28 12:51:46 +03:00
|
|
|
|
let stringkey: string = readFile(path)
|
2021-11-10 12:05:36 +00:00
|
|
|
|
try:
|
|
|
|
|
|
let key = TLSPrivateKey.init(stringkey)
|
|
|
|
|
|
return key
|
2021-11-23 11:40:43 +00:00
|
|
|
|
except TLSStreamProtocolError as exc:
|
2025-10-15 10:49:36 +02:00
|
|
|
|
info "exception raised from getSecureKey", err = exc.msg
|
2022-10-28 12:51:46 +03:00
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
|
proc getSecureCert(path: string): TLSCertificate {.raises: [Defect, IOError].} =
|
|
|
|
|
|
trace "Certificate path is.", path = path
|
2022-10-28 12:51:46 +03:00
|
|
|
|
let stringCert: string = readFile(path)
|
2021-11-10 12:05:36 +00:00
|
|
|
|
try:
|
2024-03-16 00:08:47 +01:00
|
|
|
|
let cert = TLSCertificate.init(stringCert)
|
2021-11-10 12:05:36 +00:00
|
|
|
|
return cert
|
2021-11-23 11:40:43 +00:00
|
|
|
|
except TLSStreamProtocolError as exc:
|
2025-10-15 10:49:36 +02:00
|
|
|
|
info "exception raised from getSecureCert", err = exc.msg
|
2024-03-16 00:08:47 +01:00
|
|
|
|
|
|
|
|
|
|
proc withWssTransport*(
|
|
|
|
|
|
b: SwitchBuilder, secureKeyPath: string, secureCertPath: string
|
|
|
|
|
|
): SwitchBuilder {.raises: [Defect, IOError].} =
|
|
|
|
|
|
let key: TLSPrivateKey = getSecureKey(secureKeyPath)
|
|
|
|
|
|
let cert: TLSCertificate = getSecureCert(secureCertPath)
|
2025-09-11 20:40:01 +05:30
|
|
|
|
b.withWsTransport(
|
|
|
|
|
|
tlsPrivateKey = key,
|
|
|
|
|
|
tlsCertificate = cert,
|
|
|
|
|
|
{TLSFlags.NoVerifyHost, TLSFlags.NoVerifyServerName}, # THIS IS INSECURE, NO?
|
2024-03-16 00:08:47 +01:00
|
|
|
|
)
|
2021-11-10 12:05:36 +00:00
|
|
|
|
|
2021-11-02 10:29:11 +00:00
|
|
|
|
proc newWakuSwitch*(
|
|
|
|
|
|
privKey = none(crypto.PrivateKey),
|
|
|
|
|
|
address = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
2021-12-06 20:51:37 +01:00
|
|
|
|
wsAddress = none(MultiAddress),
|
2024-03-16 00:08:47 +01:00
|
|
|
|
secureManagers: openarray[SecureProtocol] = [SecureProtocol.Noise],
|
2021-11-02 10:29:11 +00:00
|
|
|
|
transportFlags: set[ServerFlags] = {},
|
2026-06-04 16:54:44 +05:30
|
|
|
|
rng: libp2p_rng.Rng,
|
2021-11-02 10:29:11 +00:00
|
|
|
|
inTimeout: Duration = 5.minutes,
|
|
|
|
|
|
outTimeout: Duration = 5.minutes,
|
|
|
|
|
|
maxConnections = MaxConnections,
|
|
|
|
|
|
maxIn = -1,
|
|
|
|
|
|
maxOut = -1,
|
|
|
|
|
|
maxConnsPerPeer = MaxConnectionsPerPeer,
|
|
|
|
|
|
nameResolver: NameResolver = nil,
|
2022-03-29 10:09:48 +02:00
|
|
|
|
sendSignedPeerRecord = false,
|
2021-11-10 12:05:36 +00:00
|
|
|
|
wssEnabled: bool = false,
|
|
|
|
|
|
secureKeyPath: string = "",
|
2022-10-28 15:12:06 +02:00
|
|
|
|
secureCertPath: string = "",
|
2024-03-16 00:08:47 +01:00
|
|
|
|
agentString = none(string), # defaults to nim-libp2p version
|
2023-01-31 17:26:22 +01:00
|
|
|
|
peerStoreCapacity = none(int), # defaults to 1.25 maxConnections
|
2026-06-04 16:54:44 +05:30
|
|
|
|
rendezvous: Opt[RendezVousConfig] = Opt.none(RendezVousConfig),
|
2024-10-28 09:17:46 +01:00
|
|
|
|
circuitRelay: Relay,
|
2024-03-16 00:08:47 +01:00
|
|
|
|
): Switch {.raises: [Defect, IOError, LPError].} =
|
2026-06-04 16:54:44 +05:30
|
|
|
|
var b = SwitchBuilder.new().withRng(rng).withMaxConnections(maxConnections)
|
|
|
|
|
|
# libp2p 1.15.3 asserts both maxIn and maxOut > 0; only opt into independent
|
|
|
|
|
|
# in/out caps when the caller actually supplied them. Otherwise the single
|
|
|
|
|
|
# `withMaxConnections` cap from above remains in effect.
|
|
|
|
|
|
if maxIn > 0 and maxOut > 0:
|
|
|
|
|
|
b = b.withMaxInOut(maxIn, maxOut)
|
|
|
|
|
|
b = b
|
2024-03-16 00:08:47 +01:00
|
|
|
|
.withMaxConnsPerPeer(maxConnsPerPeer)
|
|
|
|
|
|
.withYamux()
|
|
|
|
|
|
.withMplex(inTimeout, outTimeout)
|
|
|
|
|
|
.withNoise()
|
|
|
|
|
|
.withTcpTransport(transportFlags)
|
|
|
|
|
|
.withNameResolver(nameResolver)
|
|
|
|
|
|
.withSignedPeerRecord(sendSignedPeerRecord)
|
2024-10-28 09:17:46 +01:00
|
|
|
|
.withCircuitRelay(circuitRelay)
|
2024-03-16 00:08:47 +01:00
|
|
|
|
.withAutonat()
|
|
|
|
|
|
|
|
|
|
|
|
if peerStoreCapacity.isSome():
|
|
|
|
|
|
b = b.withPeerStore(peerStoreCapacity.get())
|
|
|
|
|
|
else:
|
|
|
|
|
|
let defaultPeerStoreCapacity = int(maxConnections) * 5
|
|
|
|
|
|
b = b.withPeerStore(defaultPeerStoreCapacity)
|
|
|
|
|
|
if agentString.isSome():
|
|
|
|
|
|
b = b.withAgentVersion(agentString.get())
|
|
|
|
|
|
if privKey.isSome():
|
|
|
|
|
|
b = b.withPrivateKey(privKey.get())
|
|
|
|
|
|
if wsAddress.isSome():
|
|
|
|
|
|
b = b.withAddresses(@[wsAddress.get(), address])
|
|
|
|
|
|
|
|
|
|
|
|
if wssEnabled:
|
|
|
|
|
|
b = b.withWssTransport(secureKeyPath, secureCertPath)
|
2023-01-31 17:26:22 +01:00
|
|
|
|
else:
|
2024-03-16 00:08:47 +01:00
|
|
|
|
b = b.withWsTransport()
|
|
|
|
|
|
else:
|
|
|
|
|
|
b = b.withAddress(address)
|
2021-11-02 10:29:11 +00:00
|
|
|
|
|
2026-06-04 16:54:44 +05:30
|
|
|
|
if rendezvous.isSome():
|
|
|
|
|
|
b = b.withRendezVous(rendezvous.get())
|
2023-06-01 21:43:10 +02:00
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
|
b.build()
|