mirror of https://github.com/waku-org/nwaku.git
214 lines
6.1 KiB
Nim
214 lines
6.1 KiB
Nim
{.push raises: [].}
|
||
|
||
import
|
||
std/[options, net],
|
||
results,
|
||
chronicles,
|
||
libp2p/crypto/crypto,
|
||
libp2p/builders,
|
||
libp2p/nameresolving/nameresolver,
|
||
libp2p/transports/wstransport,
|
||
libp2p/protocols/connectivity/relay/client,
|
||
libp2p/protocols/connectivity/relay/relay
|
||
import
|
||
../waku_enr,
|
||
../discovery/waku_discv5,
|
||
../waku_node,
|
||
../node/peer_manager,
|
||
../common/rate_limit/setting
|
||
|
||
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: Option[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[seq[string]]
|
||
|
||
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),
|
||
): WakuNodeBuilderResult {.
|
||
deprecated: "use 'builder.withNetworkConfiguration()' instead"
|
||
.} =
|
||
let netConfig =
|
||
?NetConfig.init(
|
||
bindIp = bindIp,
|
||
bindPort = bindPort,
|
||
extIp = extIp,
|
||
extPort = extPort,
|
||
extMultiAddrs = extMultiAddrs,
|
||
wsBindPort = wsBindPort,
|
||
wsEnabled = wsEnabled,
|
||
wssEnabled = wssEnabled,
|
||
wakuFlags = wakuFlags,
|
||
dns4DomainName = dns4DomainName,
|
||
)
|
||
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, maxRelayPeers = none(int), shardAware = false
|
||
) =
|
||
builder.maxRelayPeers = maxRelayPeers
|
||
builder.shardAware = shardAware
|
||
|
||
proc withColocationLimit*(builder: var WakuNodeBuilder, colocationLimit: int) =
|
||
builder.colocationLimit = colocationLimit
|
||
|
||
proc withRateLimit*(builder: var WakuNodeBuilder, limits: seq[string]) =
|
||
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")
|
||
|
||
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 = builder.maxRelayPeers,
|
||
colocationLimit = builder.colocationLimit,
|
||
shardedPeerManagement = builder.shardAware,
|
||
)
|
||
|
||
var node: WakuNode
|
||
try:
|
||
node = WakuNode.new(
|
||
netConfig = builder.netConfig.get(),
|
||
enr = builder.record.get(),
|
||
switch = switch,
|
||
peerManager = peerManager,
|
||
rng = rng,
|
||
)
|
||
except Exception:
|
||
return err("failed to build WakuNode instance: " & getCurrentExceptionMsg())
|
||
|
||
if builder.rateLimitSettings.isSome():
|
||
?node.setRateLimits(builder.rateLimitSettings.get())
|
||
|
||
ok(node)
|