mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-13 16:25:00 +00:00
chore(wakucanary): add canary tool (#1205)
* chore(wakucanary): create folder structure * chore(wakucanary): spawn waku node * chore(wakucanary): get supported protocols from lp2p * chore(wakucanary): add timeout + refactor * chore(wakucanary): fix comments v1 * chore(wakucanary): update readme * chore(wakucanary): static->relay, abbr, logLevel, filter issue, colon * chore(wakucanary): fix typos
This commit is contained in:
parent
f282621a1c
commit
a36de4036b
5
Makefile
5
Makefile
@ -158,6 +158,11 @@ example2: | build deps
|
||||
echo -e $(BUILD_MSG) "build/$@" && \
|
||||
$(ENV_SCRIPT) nim example2 $(NIM_PARAMS) waku.nims
|
||||
|
||||
# Waku tooling targets
|
||||
wakucanary: | build deps
|
||||
echo -e $(BUILD_MSG) "build/$@" && \
|
||||
$(ENV_SCRIPT) nim wakucanary $(NIM_PARAMS) waku.nims
|
||||
|
||||
|
||||
installganache:
|
||||
ifeq ($(ONCHAIN_RLN), true)
|
||||
|
@ -55,6 +55,10 @@ make test
|
||||
Examples can be found in the examples folder. For Waku v2, there is a fully
|
||||
featured chat example.
|
||||
|
||||
### Tools
|
||||
|
||||
Different tools and their corresponding how-to guides can be found in the `tools` folder.
|
||||
|
||||
### Bugs, Questions & Features
|
||||
|
||||
For an inquiry, or if you would like to propose new features, feel free to [open a general issue](https://github.com/status-im/nim-waku/issues/new/).
|
||||
|
39
tools/README.md
Normal file
39
tools/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
## waku canary tool
|
||||
|
||||
Attempts to dial a peer and asserts it supports a given set of protocols.
|
||||
|
||||
```console
|
||||
Usage:
|
||||
|
||||
wakucanary [OPTIONS]...
|
||||
|
||||
The following options are available:
|
||||
|
||||
-a, --address Multiaddress of the peer node to attempt to dial.
|
||||
-t, --timeout Timeout to consider that the connection failed [=chronos.seconds(10)].
|
||||
-p, --protocol Protocol required to be supported: store,relay,lightpush,filter (can be used
|
||||
multiple times).
|
||||
-l, --log-level Sets the log level [=LogLevel.DEBUG].
|
||||
```
|
||||
|
||||
The tool can be built as:
|
||||
|
||||
```console
|
||||
$ make wakucanary
|
||||
```
|
||||
|
||||
And used as follows. A reachable node that supports both `store` and `filter` protocols.
|
||||
|
||||
|
||||
```console
|
||||
$ ./build/wakucanary --address=/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD --protocol=store --protocol=filter
|
||||
$ echo $?
|
||||
0
|
||||
```
|
||||
|
||||
A node that can't be reached.
|
||||
```console
|
||||
$ ./build/wakucanary --address=/ip4/8.210.222.231/tcp/1000/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD --protocol=store --protocol=filter
|
||||
$ echo $?
|
||||
1
|
||||
```
|
133
tools/wakucanary/wakucanary.nim
Normal file
133
tools/wakucanary/wakucanary.nim
Normal file
@ -0,0 +1,133 @@
|
||||
import
|
||||
std/[strutils, sequtils, tables],
|
||||
confutils,
|
||||
chronos,
|
||||
stew/shims/net,
|
||||
chronicles/topics_registry
|
||||
import
|
||||
libp2p/protocols/ping,
|
||||
libp2p/crypto/[crypto, secp]
|
||||
import
|
||||
../../waku/v2/node/peer_manager/peer_manager,
|
||||
../../waku/v2/utils/peers,
|
||||
../../waku/v2/node/wakunode2,
|
||||
../../waku/v2/node/waku_payload,
|
||||
../../waku/v2/utils/peers
|
||||
|
||||
# protocols and their tag
|
||||
const ProtocolsTable = {
|
||||
"store": "/vac/waku/store/",
|
||||
"relay": "/vac/waku/relay/",
|
||||
"lightpush": "/vac/waku/lightpush/",
|
||||
"filter": "/vac/waku/filter/",
|
||||
}.toTable
|
||||
|
||||
# cli flags
|
||||
type
|
||||
WakuCanaryConf* = object
|
||||
address* {.
|
||||
desc: "Multiaddress of the peer node to attempt to dial",
|
||||
defaultValue: "",
|
||||
name: "address",
|
||||
abbr: "a" }: string
|
||||
|
||||
timeout* {.
|
||||
desc: "Timeout to consider that the connection failed",
|
||||
defaultValue: chronos.seconds(10),
|
||||
name: "timeout",
|
||||
abbr: "t" }: chronos.Duration
|
||||
|
||||
protocols* {.
|
||||
desc: "Protocol required to be supported: store,relay,lightpush,filter (can be used multiple times)",
|
||||
name: "protocol",
|
||||
abbr: "p" }: seq[string]
|
||||
|
||||
logLevel* {.
|
||||
desc: "Sets the log level",
|
||||
defaultValue: LogLevel.DEBUG,
|
||||
name: "log-level",
|
||||
abbr: "l" .}: LogLevel
|
||||
|
||||
|
||||
proc parseCmdArg*(T: type chronos.Duration, p: TaintedString): T =
|
||||
try:
|
||||
result = chronos.seconds(parseInt(p))
|
||||
except CatchableError as e:
|
||||
raise newException(ConfigurationError, "Invalid timeout value")
|
||||
|
||||
proc completeCmdArg*(T: type chronos.Duration, val: TaintedString): seq[string] =
|
||||
return @[]
|
||||
|
||||
# checks if rawProtocols (skipping version) are supported in nodeProtocols
|
||||
proc areProtocolsSupported(
|
||||
rawProtocols: seq[string],
|
||||
nodeProtocols: seq[string]): bool =
|
||||
|
||||
var numOfSupportedProt: int = 0
|
||||
|
||||
for nodeProtocol in nodeProtocols:
|
||||
for rawProtocol in rawProtocols:
|
||||
let protocolTag = ProtocolsTable[rawProtocol]
|
||||
if nodeProtocol.startsWith(protocolTag):
|
||||
info "Supported protocol ok", expected=protocolTag, supported=nodeProtocol
|
||||
numOfSupportedProt += 1
|
||||
break
|
||||
|
||||
if numOfSupportedProt == rawProtocols.len:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
proc main(): Future[int] {.async.} =
|
||||
let conf: WakuCanaryConf = WakuCanaryConf.load()
|
||||
|
||||
if conf.logLevel != LogLevel.NONE:
|
||||
setLogLevel(conf.logLevel)
|
||||
|
||||
# ensure input protocols are valid
|
||||
for p in conf.protocols:
|
||||
if p notin ProtocolsTable:
|
||||
error "invalid protocol", protocol=p, valid=ProtocolsTable
|
||||
raise newException(ConfigurationError, "Invalid cli flag values" & p)
|
||||
|
||||
info "Cli flags",
|
||||
address=conf.address,
|
||||
timeout=conf.timeout,
|
||||
protocols=conf.protocols,
|
||||
logLevel=conf.logLevel
|
||||
|
||||
let
|
||||
peer: RemotePeerInfo = parseRemotePeerInfo(conf.address)
|
||||
rng = crypto.newRng()
|
||||
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
||||
node = WakuNode.new(
|
||||
nodeKey,
|
||||
ValidIpAddress.init("0.0.0.0"),
|
||||
Port(60000))
|
||||
|
||||
await node.start()
|
||||
|
||||
let timedOut = not await node.connectToNodes(@[peer]).withTimeout(conf.timeout)
|
||||
if timedOut:
|
||||
error "Timedout after", timeout=conf.timeout
|
||||
|
||||
let lp2pPeerStore = node.switch.peerStore
|
||||
let conStatus = node.peerManager.peerStore.connectionBook[peer.peerId]
|
||||
|
||||
if conStatus in [Connected, CanConnect]:
|
||||
let nodeProtocols = lp2pPeerStore[ProtoBook][peer.peerId]
|
||||
if not areProtocolsSupported(conf.protocols, nodeProtocols):
|
||||
error "Not all protocols are supported", expected=conf.protocols, supported=nodeProtocols
|
||||
return 1
|
||||
elif conStatus == CannotConnect:
|
||||
error "Could not connect", peerId = peer.peerId
|
||||
return 1
|
||||
return 0
|
||||
|
||||
when isMainModule:
|
||||
let status = waitFor main()
|
||||
if status == 0:
|
||||
info "The node is reachable and supports all specified protocols"
|
||||
else:
|
||||
error "The node has some problems (see logs)"
|
||||
quit status
|
@ -99,3 +99,7 @@ task chat2bridge, "Build chat2-matterbridge":
|
||||
|
||||
buildBinary name, "examples/v2/matterbridge/", "-d:chronicles_log_level=DEBUG"
|
||||
|
||||
### Waku Tooling
|
||||
task wakucanary, "Build waku-canary tool":
|
||||
let name = "wakucanary"
|
||||
buildBinary name, "tools/wakucanary/", "-d:chronicles_log_level=DEBUG -d:chronicles_runtime_filtering:on"
|
Loading…
x
Reference in New Issue
Block a user