nwaku/waku/common/wakubridge.nim

157 lines
5.1 KiB
Nim

import
std/[strutils, tables],
chronos, confutils, chronicles, chronicles/topics_registry, metrics,
stew/shims/net as stewNet, json_rpc/rpcserver,
# Waku v1 imports
eth/[keys, p2p], eth/common/utils,
eth/p2p/[enode, whispernodes],
../v1/protocol/waku_protocol,
./utils/nat,
../v1/node/rpc/wakusim,
../v1/node/rpc/waku,
../v1/node/rpc/key_storage,
../v1/node/waku_helpers,
# Waku v2 imports
libp2p/crypto/crypto,
../v2/protocol/waku_filter/waku_filter_types,
../v2/node/wakunode2,
../v2/node/jsonrpc/[debug_api,
filter_api,
relay_api,
store_api],
# Common cli config
./config_bridge
const clientIdV1 = "nim-waku v1 node"
proc startWakuV1(config: WakuNodeConf, rng: ref BrHmacDrbgContext):
EthereumNode =
let
(ipExt, _, _) = setupNat(config.nat, clientIdV1,
Port(config.devp2pTcpPort + config.portsShift),
Port(config.udpPort + config.portsShift))
# TODO: EthereumNode should have a better split of binding address and
# external address. Also, can't have different ports as it stands now.
address = if ipExt.isNone():
Address(ip: parseIpAddress("0.0.0.0"),
tcpPort: Port(config.devp2pTcpPort + config.portsShift),
udpPort: Port(config.udpPort + config.portsShift))
else:
Address(ip: ipExt.get(),
tcpPort: Port(config.devp2pTcpPort + config.portsShift),
udpPort: Port(config.udpPort + config.portsShift))
# Set-up node
var node = newEthereumNode(config.nodekeyv1, address, 1, nil, clientIdV1,
addAllCapabilities = false, rng = rng)
node.addCapability Waku # Always enable Waku protocol
# Set up the Waku configuration.
# This node is being set up as a bridge so it gets configured as a node with
# a full bloom filter so that it will receive and forward all messages.
# TODO: What is the PoW setting now?
let wakuConfig = WakuConfig(powRequirement: config.wakuPow,
bloom: some(fullBloom()), isLightNode: false,
maxMsgSize: waku_protocol.defaultMaxMsgSize,
topics: none(seq[waku_protocol.Topic]))
node.configureWaku(wakuConfig)
# Optionally direct connect with a set of nodes
if config.staticnodesv1.len > 0: connectToNodes(node, config.staticnodesv1)
elif config.fleetv1 == prod: connectToNodes(node, WhisperNodes)
elif config.fleetv1 == staging: connectToNodes(node, WhisperNodesStaging)
elif config.fleetv1 == test: connectToNodes(node, WhisperNodesTest)
let connectedFut = node.connectToNetwork(@[],
true, # Always enable listening
false # Disable discovery (only discovery v4 is currently supported)
)
connectedFut.callback = proc(data: pointer) {.gcsafe.} =
{.gcsafe.}:
if connectedFut.failed:
fatal "connectToNetwork failed", msg = connectedFut.readError.msg
quit(1)
return node
proc startWakuV2(config: WakuNodeConf): Future[WakuNode] {.async.} =
let
(extIp, extTcpPort, _) = setupNat(config.nat, clientId,
Port(uint16(config.libp2pTcpPort) + config.portsShift),
Port(uint16(config.udpPort) + config.portsShift))
node = WakuNode.init(config.nodeKeyv2, config.listenAddress,
Port(uint16(config.libp2pTcpPort) + config.portsShift), extIp, extTcpPort)
await node.start()
if config.store:
mountStore(node)
if config.filter:
mountFilter(node)
if config.relay:
mountRelay(node, config.topics.split(" "))
if config.staticnodesv2.len > 0:
waitFor connectToNodes(node, config.staticnodesv2)
if config.storenode != "":
setStorePeer(node, config.storenode)
if config.filternode != "":
setFilterPeer(node, config.filternode)
return node
when isMainModule:
proc startV2Rpc(node: WakuNode, rpcServer: RpcHttpServer, conf: WakuNodeConf) =
installDebugApiHandlers(node, rpcServer)
# Install enabled API handlers:
if conf.relay:
let topicCache = newTable[string, seq[WakuMessage]]()
installRelayApiHandlers(node, rpcServer, topicCache)
if conf.filter:
let messageCache = newTable[ContentTopic, seq[WakuMessage]]()
installFilterApiHandlers(node, rpcServer, messageCache)
if conf.store:
installStoreApiHandlers(node, rpcServer)
rpcServer.start()
let
rng = keys.newRng()
let conf = WakuNodeConf.load()
if conf.logLevel != LogLevel.NONE:
setLogLevel(conf.logLevel)
let
nodev1 = startWakuV1(conf, rng)
nodev2 = waitFor startWakuV2(conf)
if conf.rpc:
let ta = initTAddress(conf.rpcAddress,
Port(conf.rpcPort + conf.portsShift))
var rpcServer = newRpcHttpServer([ta])
# Waku v1 RPC
let keys = newKeyStorage()
setupWakuRPC(nodev1, keys, rpcServer, rng)
setupWakuSimRPC(nodev1, rpcServer)
# Waku v2 rpc
startV2Rpc(nodev2, rpcServer, conf)
rpcServer.start()
when defined(insecure):
if conf.metricsServer:
let
address = conf.metricsServerAddress
port = conf.metricsServerPort + conf.portsShift
info "Starting metrics HTTP server", address, port
metrics.startHttpServer($address, Port(port))
runForever()