mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-06-06 22:19:30 +00:00
Combines five dep-and-build changes that all flow from the libp2p v2.0.0
upgrade and the move to the extracted libp2p_mix / mix-rln plugin stack:
waku.nimble:
* libp2p: ff8d51857 -> c43199378 (release/v2.0.0 tip; sha-pinned until
vacp2p cuts a v2.0.0 tag).
* Drop the bare `zlib < 0.2` cap — no longer needed by the upgraded
libp2p.
* websock: bare ">= 0.4.0" — replaces the d4cd68b URL+SHA workaround
that pinned through a libp2p commit-specific websock SHA.
* nim-json-rpc: switch to chaitanyaprem/nim-json-rpc#f05fad25 — relaxes
websock cap to allow >=0.4.0. TODO: revert to status-im/nim-json-rpc
once status-im/nim-json-rpc#277 merges and a tag is cut.
* lsquic: bare ">= 0.4.1" (drops URL form).
* Add mix-rln-spam-protection-plugin pin (23b278b4) and nim-libp2p-mix
pin (50c4ab4f — PR #14 HEAD); the plugin pins the same libp2p_mix
SHA so the diamond dep collapses to a single source.
waku/factory/waku.nim:
* Explicit HPService.setup(switch) / AutonatService.setup(switch)
calls. libp2p v2.0.0's Service lifecycle refactor (libp2p#2462)
removed switch.start's auto-setup loop, so any caller that assigns
directly to switch.services (we do) is responsible for calling
setup() themselves. Without it, AutonatService.addressMapper stays
nil and peerInfo.expandAddrs SIGSEGVs during start(). Wrapped in
try/except for ServiceSetupError so a setup failure surfaces as a
logged error rather than a crash.
Build / scripts:
* scripts/build_rln_mix.sh removed and Makefile simplified — librln
is now a single shared archive built from zerokit's `stateless`
features (no separate librln_mix archive).
* simulations/mixnet/build_setup.sh + setup_credentials.nim updated
to use librln_v2.0.2.a directly and run RLN keystore setup before
nodes start.
Validated:
* Cold local-cache nimble setup --localdeps -y.
* wakunode2 and chat2mix link cleanly.
* Mixnet roundtrip sim: [PASS] bob received message from alice.
* RLN proof generation + verification on every in-path mix node:
5 gen_called == 5 verified, 0 SPAM_PROOF_* errors.
234 lines
6.9 KiB
Nim
234 lines
6.9 KiB
Nim
{.push raises: [].}
|
||
|
||
import
|
||
std/[options, net, math],
|
||
results,
|
||
chronicles,
|
||
libp2p/crypto/crypto,
|
||
libp2p/crypto/rng as libp2p_rng,
|
||
bearssl/rand,
|
||
libp2p/builders,
|
||
libp2p/nameresolving/nameresolver,
|
||
libp2p/transports/wstransport,
|
||
libp2p/protocols/connectivity/relay/relay,
|
||
brokers/broker_context
|
||
|
||
import
|
||
../waku_enr,
|
||
../discovery/waku_discv5,
|
||
../waku_node,
|
||
../node/waku_switch,
|
||
../node/peer_manager,
|
||
../common/rate_limit/setting,
|
||
../common/utils/parse_size_units
|
||
|
||
type
|
||
WakuNodeBuilder* = object # General
|
||
nodeRng: Option[ref HmacDrbgContext]
|
||
nodeKey: Option[crypto.PrivateKey]
|
||
netConfig: Option[NetConfig]
|
||
record: Option[enr.Record]
|
||
|
||
# Peer storage and peer manager
|
||
peerStorage: Option[PeerStorage]
|
||
peerStorageCapacity: Option[int]
|
||
|
||
# Peer manager config
|
||
maxRelayPeers: int
|
||
maxServicePeers: int
|
||
colocationLimit: int
|
||
shardAware: bool
|
||
|
||
# Libp2p switch
|
||
switchMaxConnections: Option[int]
|
||
switchNameResolver: Option[NameResolver]
|
||
switchAgentString: Option[string]
|
||
switchSslSecureKey: Option[string]
|
||
switchSslSecureCert: Option[string]
|
||
switchSendSignedPeerRecord: Option[bool]
|
||
circuitRelay: Relay
|
||
|
||
# Rate limit configs for non-relay req-resp protocols
|
||
rateLimitSettings: Option[ProtocolRateLimitSettings]
|
||
|
||
WakuNodeBuilderResult* = Result[void, string]
|
||
|
||
## Init
|
||
|
||
proc init*(T: type WakuNodeBuilder): WakuNodeBuilder =
|
||
WakuNodeBuilder()
|
||
|
||
## General
|
||
|
||
proc withRng*(builder: var WakuNodeBuilder, rng: ref HmacDrbgContext) =
|
||
builder.nodeRng = some(rng)
|
||
|
||
proc withNodeKey*(builder: var WakuNodeBuilder, nodeKey: crypto.PrivateKey) =
|
||
builder.nodeKey = some(nodeKey)
|
||
|
||
proc withRecord*(builder: var WakuNodeBuilder, record: enr.Record) =
|
||
builder.record = some(record)
|
||
|
||
proc withNetworkConfiguration*(builder: var WakuNodeBuilder, config: NetConfig) =
|
||
builder.netConfig = some(config)
|
||
|
||
proc withNetworkConfigurationDetails*(
|
||
builder: var WakuNodeBuilder,
|
||
bindIp: IpAddress,
|
||
bindPort: Port,
|
||
extIp = none(IpAddress),
|
||
extPort = none(Port),
|
||
extMultiAddrs = newSeq[MultiAddress](),
|
||
wsBindPort: Port = Port(8000),
|
||
wsEnabled: bool = false,
|
||
wssEnabled: bool = false,
|
||
wakuFlags = none(CapabilitiesBitfield),
|
||
dns4DomainName = none(string),
|
||
dnsNameServers = @[parseIpAddress("1.1.1.1"), parseIpAddress("1.0.0.1")],
|
||
): WakuNodeBuilderResult {.
|
||
deprecated: "use 'builder.withNetworkConfiguration()' instead"
|
||
.} =
|
||
let netConfig = ?NetConfig.init(
|
||
bindIp = bindIp,
|
||
bindPort = bindPort,
|
||
extIp = extIp,
|
||
extPort = extPort,
|
||
extMultiAddrs = extMultiAddrs,
|
||
wsBindPort = some(wsBindPort),
|
||
wsEnabled = wsEnabled,
|
||
wssEnabled = wssEnabled,
|
||
wakuFlags = wakuFlags,
|
||
dns4DomainName = dns4DomainName,
|
||
dnsNameServers = dnsNameServers,
|
||
)
|
||
builder.withNetworkConfiguration(netConfig)
|
||
ok()
|
||
|
||
## Peer storage and peer manager
|
||
|
||
proc withPeerStorage*(
|
||
builder: var WakuNodeBuilder, peerStorage: PeerStorage, capacity = none(int)
|
||
) =
|
||
if not peerStorage.isNil():
|
||
builder.peerStorage = some(peerStorage)
|
||
|
||
builder.peerStorageCapacity = capacity
|
||
|
||
proc withPeerManagerConfig*(
|
||
builder: var WakuNodeBuilder,
|
||
maxConnections: int,
|
||
relayServiceRatio: string,
|
||
shardAware = false,
|
||
) =
|
||
let (relayRatio, serviceRatio) = parseRelayServiceRatio(relayServiceRatio).get()
|
||
var relayPeers = int(ceil(float(maxConnections) * relayRatio))
|
||
var servicePeers = int(floor(float(maxConnections) * serviceRatio))
|
||
|
||
builder.maxServicePeers = servicePeers
|
||
builder.maxRelayPeers = relayPeers
|
||
builder.shardAware = shardAware
|
||
|
||
proc withColocationLimit*(builder: var WakuNodeBuilder, colocationLimit: int) =
|
||
builder.colocationLimit = colocationLimit
|
||
|
||
proc withRateLimit*(builder: var WakuNodeBuilder, limits: ProtocolRateLimitSettings) =
|
||
builder.rateLimitSettings = some(limits)
|
||
|
||
proc withCircuitRelay*(builder: var WakuNodeBuilder, circuitRelay: Relay) =
|
||
builder.circuitRelay = circuitRelay
|
||
|
||
## Waku switch
|
||
|
||
proc withSwitchConfiguration*(
|
||
builder: var WakuNodeBuilder,
|
||
maxConnections = none(int),
|
||
nameResolver: NameResolver = nil,
|
||
sendSignedPeerRecord = false,
|
||
secureKey = none(string),
|
||
secureCert = none(string),
|
||
agentString = none(string),
|
||
) =
|
||
builder.switchMaxConnections = maxConnections
|
||
builder.switchSendSignedPeerRecord = some(sendSignedPeerRecord)
|
||
builder.switchSslSecureKey = secureKey
|
||
builder.switchSslSecureCert = secureCert
|
||
builder.switchAgentString = agentString
|
||
|
||
if not nameResolver.isNil():
|
||
builder.switchNameResolver = some(nameResolver)
|
||
|
||
## Build
|
||
|
||
proc build*(builder: WakuNodeBuilder): Result[WakuNode, string] =
|
||
var rng: ref HmacDrbgContext
|
||
if builder.nodeRng.isNone():
|
||
rng = HmacDrbgContext.new()
|
||
else:
|
||
rng = builder.nodeRng.get()
|
||
|
||
if builder.nodeKey.isNone():
|
||
return err("node key is required")
|
||
|
||
if builder.netConfig.isNone():
|
||
return err("network configuration is required")
|
||
|
||
let netConfig = builder.netConfig.get()
|
||
if netConfig.dnsNameServers.len == 0:
|
||
return err("DNS name servers are required for WakuNode")
|
||
|
||
if builder.record.isNone():
|
||
return err("node record is required")
|
||
|
||
let circuitRelay =
|
||
if builder.circuitRelay.isNil():
|
||
Relay.new()
|
||
else:
|
||
builder.circuitRelay
|
||
|
||
var switch: Switch
|
||
try:
|
||
switch = newWakuSwitch(
|
||
privKey = builder.nodekey,
|
||
address = builder.netConfig.get().hostAddress,
|
||
wsAddress = builder.netConfig.get().wsHostAddress,
|
||
transportFlags = {ServerFlags.ReuseAddr, ServerFlags.TcpNoDelay},
|
||
# newWakuSwitch now expects libp2p `Rng`; wrap our BearSSL rng.
|
||
rng = libp2p_rng.newBearSslRng(rng),
|
||
maxConnections = builder.switchMaxConnections.get(waku_switch.MaxConnections),
|
||
wssEnabled = builder.netConfig.get().wssEnabled,
|
||
secureKeyPath = builder.switchSslSecureKey.get(""),
|
||
secureCertPath = builder.switchSslSecureCert.get(""),
|
||
nameResolver = builder.switchNameResolver.get(nil),
|
||
sendSignedPeerRecord = builder.switchSendSignedPeerRecord.get(false),
|
||
agentString = builder.switchAgentString,
|
||
peerStoreCapacity = builder.peerStorageCapacity,
|
||
circuitRelay = circuitRelay,
|
||
)
|
||
except CatchableError:
|
||
return err("failed to create switch: " & getCurrentExceptionMsg())
|
||
|
||
let peerManager = PeerManager.new(
|
||
switch = switch,
|
||
storage = builder.peerStorage.get(nil),
|
||
maxRelayPeers = some(builder.maxRelayPeers),
|
||
maxServicePeers = some(builder.maxServicePeers),
|
||
colocationLimit = builder.colocationLimit,
|
||
shardedPeerManagement = builder.shardAware,
|
||
maxConnections = builder.switchMaxConnections.get(waku_switch.MaxConnections),
|
||
)
|
||
|
||
var node: WakuNode
|
||
try:
|
||
node = WakuNode.new(
|
||
netConfig = netConfig,
|
||
enr = builder.record.get(),
|
||
switch = switch,
|
||
peerManager = peerManager,
|
||
rng = rng,
|
||
rateLimitSettings = builder.rateLimitSettings.get(DefaultProtocolRateLimit),
|
||
)
|
||
except Exception:
|
||
return err("failed to build WakuNode instance: " & getCurrentExceptionMsg())
|
||
|
||
ok(node)
|