2023-04-05 12:27:11 +00:00
|
|
|
|
when (NimMajor, NimMinor) < (1, 4):
|
|
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
else:
|
|
|
|
|
{.push raises: [].}
|
|
|
|
|
|
|
|
|
|
import
|
|
|
|
|
std/options,
|
|
|
|
|
stew/results,
|
|
|
|
|
stew/shims/net,
|
|
|
|
|
chronicles,
|
|
|
|
|
libp2p/crypto/crypto,
|
|
|
|
|
libp2p/builders,
|
2023-06-23 13:30:28 +00:00
|
|
|
|
libp2p/nameresolving/nameresolver,
|
|
|
|
|
libp2p/transports/wstransport
|
2024-04-17 19:48:20 +00:00
|
|
|
|
import ../waku_enr, ../discovery/waku_discv5, ../waku_node, ../node/peer_manager
|
2023-04-05 12:27:11 +00:00
|
|
|
|
|
|
|
|
|
type
|
2024-03-15 23:08:47 +00:00
|
|
|
|
WakuNodeBuilder* = object # General
|
2023-04-05 12:27:11 +00:00
|
|
|
|
nodeRng: Option[ref crypto.HmacDrbgContext]
|
|
|
|
|
nodeKey: Option[crypto.PrivateKey]
|
|
|
|
|
netConfig: Option[NetConfig]
|
2023-06-22 20:58:14 +00:00
|
|
|
|
record: Option[enr.Record]
|
2023-04-05 12:27:11 +00:00
|
|
|
|
|
|
|
|
|
# Peer storage and peer manager
|
|
|
|
|
peerStorage: Option[PeerStorage]
|
|
|
|
|
peerStorageCapacity: Option[int]
|
2023-06-23 13:30:28 +00:00
|
|
|
|
|
|
|
|
|
# Peer manager config
|
|
|
|
|
maxRelayPeers: Option[int]
|
2024-01-02 13:01:18 +00:00
|
|
|
|
colocationLimit: int
|
2024-01-30 12:28:21 +00:00
|
|
|
|
shardAware: bool
|
2023-04-05 12:27:11 +00:00
|
|
|
|
|
|
|
|
|
# Libp2p switch
|
|
|
|
|
switchMaxConnections: Option[int]
|
|
|
|
|
switchNameResolver: Option[NameResolver]
|
|
|
|
|
switchAgentString: Option[string]
|
|
|
|
|
switchSslSecureKey: Option[string]
|
|
|
|
|
switchSslSecureCert: Option[string]
|
|
|
|
|
switchSendSignedPeerRecord: Option[bool]
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
2023-06-22 20:58:14 +00:00
|
|
|
|
proc withRecord*(builder: var WakuNodeBuilder, record: enr.Record) =
|
|
|
|
|
builder.record = some(record)
|
|
|
|
|
|
2023-04-05 12:27:11 +00:00
|
|
|
|
proc withNetworkConfiguration*(builder: var WakuNodeBuilder, config: NetConfig) =
|
|
|
|
|
builder.netConfig = some(config)
|
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
|
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,
|
|
|
|
|
)
|
2023-04-05 12:27:11 +00:00
|
|
|
|
builder.withNetworkConfiguration(netConfig)
|
|
|
|
|
ok()
|
|
|
|
|
|
|
|
|
|
## Peer storage and peer manager
|
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
|
proc withPeerStorage*(
|
|
|
|
|
builder: var WakuNodeBuilder, peerStorage: PeerStorage, capacity = none(int)
|
|
|
|
|
) =
|
2023-04-05 12:27:11 +00:00
|
|
|
|
if not peerStorage.isNil():
|
|
|
|
|
builder.peerStorage = some(peerStorage)
|
|
|
|
|
|
|
|
|
|
builder.peerStorageCapacity = capacity
|
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
|
proc withPeerManagerConfig*(
|
|
|
|
|
builder: var WakuNodeBuilder, maxRelayPeers = none(int), shardAware = false
|
|
|
|
|
) =
|
2023-06-23 13:30:28 +00:00
|
|
|
|
builder.maxRelayPeers = maxRelayPeers
|
2024-01-30 12:28:21 +00:00
|
|
|
|
builder.shardAware = shardAware
|
2023-06-23 13:30:28 +00:00
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
|
proc withColocationLimit*(builder: var WakuNodeBuilder, colocationLimit: int) =
|
2024-01-02 13:01:18 +00:00
|
|
|
|
builder.colocationLimit = colocationLimit
|
2023-04-05 12:27:11 +00:00
|
|
|
|
|
|
|
|
|
## Waku switch
|
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
|
proc withSwitchConfiguration*(
|
|
|
|
|
builder: var WakuNodeBuilder,
|
|
|
|
|
maxConnections = none(int),
|
|
|
|
|
nameResolver: NameResolver = nil,
|
|
|
|
|
sendSignedPeerRecord = false,
|
|
|
|
|
secureKey = none(string),
|
|
|
|
|
secureCert = none(string),
|
|
|
|
|
agentString = none(string),
|
|
|
|
|
) =
|
2023-04-05 12:27:11 +00:00
|
|
|
|
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")
|
|
|
|
|
|
2023-06-28 12:57:10 +00:00
|
|
|
|
if builder.record.isNone():
|
|
|
|
|
return err("node record is required")
|
|
|
|
|
|
2023-06-23 13:30:28 +00:00
|
|
|
|
var switch: Switch
|
|
|
|
|
try:
|
|
|
|
|
switch = newWakuSwitch(
|
|
|
|
|
privKey = builder.nodekey,
|
|
|
|
|
address = builder.netConfig.get().hostAddress,
|
|
|
|
|
wsAddress = builder.netConfig.get().wsHostAddress,
|
2023-07-15 14:41:26 +00:00
|
|
|
|
transportFlags = {ServerFlags.ReuseAddr, ServerFlags.TcpNoDelay},
|
2023-06-23 13:30:28 +00:00
|
|
|
|
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,
|
|
|
|
|
services = @[Service(getAutonatService(rng))],
|
|
|
|
|
)
|
|
|
|
|
except CatchableError:
|
|
|
|
|
return err("failed to create switch: " & getCurrentExceptionMsg())
|
|
|
|
|
|
|
|
|
|
let peerManager = PeerManager.new(
|
|
|
|
|
switch = switch,
|
|
|
|
|
storage = builder.peerStorage.get(nil),
|
2023-07-04 11:31:18 +00:00
|
|
|
|
maxRelayPeers = builder.maxRelayPeers,
|
2024-01-02 13:01:18 +00:00
|
|
|
|
colocationLimit = builder.colocationLimit,
|
2024-01-30 12:28:21 +00:00
|
|
|
|
shardedPeerManagement = builder.shardAware,
|
2023-06-23 13:30:28 +00:00
|
|
|
|
)
|
|
|
|
|
|
2023-04-05 12:27:11 +00:00
|
|
|
|
var node: WakuNode
|
|
|
|
|
try:
|
|
|
|
|
node = WakuNode.new(
|
|
|
|
|
netConfig = builder.netConfig.get(),
|
2023-06-28 12:57:10 +00:00
|
|
|
|
enr = builder.record.get(),
|
2023-06-23 13:30:28 +00:00
|
|
|
|
switch = switch,
|
|
|
|
|
peerManager = peerManager,
|
|
|
|
|
rng = rng,
|
2023-04-05 12:27:11 +00:00
|
|
|
|
)
|
|
|
|
|
except Exception:
|
|
|
|
|
return err("failed to build WakuNode instance: " & getCurrentExceptionMsg())
|
|
|
|
|
|
|
|
|
|
ok(node)
|