NagyZoltanPeter 284a0816cc
chore: use chronos' TokenBucket (#3670)
* Adapt using chronos' TokenBucket. Removed TokenBucket and test. bump nim-chronos -> nim-libp2p/nim-lsquic/nim-jwt -> adapt to latest libp2p changes
* Fix libp2p/utility reports unlisted exception can occure from close of socket in waitForService - -d:ssl compile flag caused it
* Adapt request_limiter to new chronos' TokenBucket replenish algorithm to keep original intent of use
* Fix filter dos protection test
* Fix peer manager tests due change caused by new libp2p
* Adjust store test rate limit to eliminate CI test flakyness of timing
* Adjust store test rate limit to eliminate CI test flakyness of timing - lightpush/legacy_lightpush/filter
* Rework filter dos protection test to avoid CI crazy timing causing flakyness in test results compared to local runs
* Rework lightpush dos protection test to avoid CI crazy timing causing flakyness in test results compared to local runs
* Rework lightpush and legacy lightpush rate limit tests to eliminate timing effect in CI that cause longer awaits thus result in minting new tokens unlike local runs
2026-01-07 17:48:19 +01:00

229 lines
6.8 KiB
Nim
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{.push raises: [].}
import
std/[options, net, math],
results,
chronicles,
libp2p/crypto/crypto,
libp2p/builders,
libp2p/nameresolving/nameresolver,
libp2p/transports/wstransport,
libp2p/protocols/connectivity/relay/relay
import
../waku_enr,
../discovery/waku_discv5,
../waku_node,
../node/peer_manager,
../common/rate_limit/setting,
../common/utils/parse_size_units
type
WakuNodeBuilder* = object # General
nodeRng: Option[ref crypto.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 crypto.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 crypto.HmacDrbgContext
if builder.nodeRng.isNone():
rng = crypto.newRng()
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},
rng = rng,
maxConnections = builder.switchMaxConnections.get(builders.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(builders.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)