diff --git a/Makefile b/Makefile index a670a2c88..ae4ffc7aa 100644 --- a/Makefile +++ b/Makefile @@ -99,8 +99,8 @@ proxy: ##@build Build proxy for rendezvous servers using status-go deps go build -i -o $(GOBIN)/proxy -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/proxy/ @echo "Compilation done." -mailserver-canary: ##@build Build mailserver canary using status-go deps - go build -i -o $(GOBIN)/mailserver-canary -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/mailserver-canary/ +node-canary: ##@build Build P2P node canary using status-go deps + go build -i -o $(GOBIN)/node-canary -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/node-canary/ @echo "Compilation done." statusgo-cross: statusgo-android statusgo-ios diff --git a/cmd/mailserver-canary/README.md b/cmd/mailserver-canary/README.md deleted file mode 100644 index a77eb40e4..000000000 --- a/cmd/mailserver-canary/README.md +++ /dev/null @@ -1,16 +0,0 @@ -Canary service -====================== - -The mailserver canary service's goal is to provide feedback on whether a specified mailserver is responding -correctly to historic messages request. It sends a request for 1 message in a specified chat room (defaults -to #status) to the mailserver within a specified time window (default is last 24 hours) and succeeds if the -mailserver responds with an acknowledgement to the request message (using the request's hash value as a -match). - -## How to run it - -```shell -make mailserver-canary - -./build/bin/mailserver-canary -log=INFO --mailserver=enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:30504 -``` \ No newline at end of file diff --git a/cmd/node-canary/README.md b/cmd/node-canary/README.md new file mode 100644 index 000000000..aed283752 --- /dev/null +++ b/cmd/node-canary/README.md @@ -0,0 +1,20 @@ +Canary service +====================== + +The P2P node canary service's goal is to provide feedback on whether a specified node is responding +correctly. It can: + +- test whether a static peer is responding correctly; +- test whether a mailserver responds to historic messages request. It sends a request for 1 message in a specified chat room (defaults to #status) to the mailserver within a specified time window (default is last 24 hours) and succeeds if the mailserver responds with an acknowledgement to the request message (using the request's hash value as a match). + +## How to run it + +```shell +make node-canary + +./build/bin/node-canary -log=INFO --mailserver=enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:30504 + +./build/bin/node-canary -log=INFO --staticnode=enode://9c2b82304d988cd78bf290a09b6f81c6ae89e71f9c0f69c41d21bd5cabbd1019522d5d73d7771ea933adf0727de5e847c89e751bd807ba1f7f6fc3a0cd88d997@47.52.91.239:30305 +``` + +It will return with exit code 0 if the enode responded correctly, and a positive number otherwise. diff --git a/cmd/mailserver-canary/main.go b/cmd/node-canary/main.go similarity index 69% rename from cmd/mailserver-canary/main.go rename to cmd/node-canary/main.go index 26dc0564d..32f266dc3 100644 --- a/cmd/mailserver-canary/main.go +++ b/cmd/node-canary/main.go @@ -1,4 +1,4 @@ -// mailserver-canary tests whether a mailserver enode responds to a historic messages request. +// node-canary tests whether a P2P peer is responding correctly. package main import ( @@ -35,32 +35,51 @@ const ( var logger = log.New("package", "status-go/cmd/mailserver-canary") var ( - enodeAddr = flag.String("mailserver", "", "mailserver enode address (e.g. enode://1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40@167.99.209.61:30504)") - publicChannel = flag.String("channel", "status", "The public channel name to retrieve historic messages from") - period = flag.Int("period", 24*60*60, "How far in the past to request messages from mailserver, in seconds") - minPow = flag.Float64("shh.pow", params.WhisperMinimumPoW, "PoW for messages to be added to queue, in float format") - ttl = flag.Int("shh.ttl", params.WhisperTTL, "Time to live for messages, in seconds") - homePath = flag.String("home-dir", ".", "Home directory where state is stored") - logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`) - logFile = flag.String("logfile", "", "Path to the log file") - logWithoutColors = flag.Bool("log-without-color", false, "Disables log colors") + staticEnodeAddr = flag.String("staticnode", "", "static node enode address to test (e.g. enode://3f04db09bedc8d85a198de94c84da73aa7782fafc61b28c525ec5cca5a6cc16be7ebbb5cd001780f71d8408d35a2f6326faa1e524d9d8875294172ebec988743@172.16.238.10:30303)") + mailserverEnodeAddr = flag.String("mailserver", "", "mailserver enode address to test (e.g. enode://1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40@167.99.209.61:30504)") + publicChannel = flag.String("channel", "status", "The public channel name to retrieve historic messages from (used with 'mailserver' flag)") + period = flag.Int("period", 24*60*60, "How far in the past to request messages from mailserver, in seconds") + minPow = flag.Float64("shh.pow", params.WhisperMinimumPoW, "PoW for messages to be added to queue, in float format") + ttl = flag.Int("shh.ttl", params.WhisperTTL, "Time to live for messages, in seconds") + homePath = flag.String("home-dir", ".", "Home directory where state is stored") + logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`) + logFile = flag.String("logfile", "", "Path to the log file") + logWithoutColors = flag.Bool("log-without-color", false, "Disables log colors") ) func main() { - if enodeAddr == nil { - logger.Crit("No mailserver address specified", "enodeAddr", *enodeAddr) - os.Exit(1) + var err error + var staticParsedNode, mailserverParsedNode *discv5.Node + if *staticEnodeAddr != "" { + staticParsedNode, err = discv5.ParseNode(*staticEnodeAddr) + if err != nil { + logger.Crit("Invalid static address specified", "staticEnodeAddr", *staticEnodeAddr, "error", err) + os.Exit(1) + } } - mailserverParsedNode, err := discv5.ParseNode(*enodeAddr) - if err != nil { - logger.Crit("Invalid mailserver address specified", "enodeAddr", *enodeAddr, "error", err) - os.Exit(1) + if *mailserverEnodeAddr != "" { + mailserverParsedNode, err = discv5.ParseNode(*mailserverEnodeAddr) + if err != nil { + logger.Crit("Invalid mailserver address specified", "mailserverEnodeAddr", *mailserverEnodeAddr, "error", err) + os.Exit(1) + } } - verifyMailserverBehavior(mailserverParsedNode) - logger.Info("Mailserver responded correctly", "address", enodeAddr) - os.Exit(0) + if staticParsedNode != nil { + verifyStaticNodeBehavior(staticParsedNode) + logger.Info("Connected to static node correctly", "address", *staticEnodeAddr) + os.Exit(0) + } + + if mailserverParsedNode != nil { + verifyMailserverBehavior(mailserverParsedNode) + logger.Info("Mailserver responded correctly", "address", *mailserverEnodeAddr) + os.Exit(0) + } + + logger.Crit("No address specified") + os.Exit(1) } func init() { @@ -97,8 +116,8 @@ func verifyMailserverBehavior(mailserverNode *discv5.Node) { } // add mailserver peer to client - clientErrCh := helpers.WaitForPeerAsync(clientNode.Server(), *enodeAddr, p2p.PeerEventTypeAdd, 5*time.Second) - err = clientNode.AddPeer(*enodeAddr) + clientErrCh := helpers.WaitForPeerAsync(clientNode.Server(), *mailserverEnodeAddr, p2p.PeerEventTypeAdd, 5*time.Second) + err = clientNode.AddPeer(*mailserverEnodeAddr) if err != nil { logger.Error("Failed to add mailserver peer to client", "error", err) os.Exit(1) @@ -175,6 +194,34 @@ func verifyMailserverBehavior(mailserverNode *discv5.Node) { } } +func verifyStaticNodeBehavior(staticNode *discv5.Node) { + clientBackend, err := startClientNode() + if err != nil { + logger.Error("Node start failed", "error", err) + os.Exit(1) + } + defer func() { _ = clientBackend.StopNode() }() + + clientNode := clientBackend.StatusNode() + + // wait for peer to be added to client + clientErrCh := helpers.WaitForPeerAsync(clientNode.Server(), *staticEnodeAddr, p2p.PeerEventTypeAdd, 5*time.Second) + err = <-clientErrCh + if err != nil { + logger.Error("Error detected while waiting for static peer to be added", "error", err) + os.Exit(1) + } + + // wait to check if peer remains connected to client + clientErrCh = helpers.WaitForPeerAsync(clientNode.Server(), *staticEnodeAddr, p2p.PeerEventTypeDrop, 5*time.Second) + err = <-clientErrCh + peers := clientNode.GethNode().Server().Peers() + if len(peers) != 1 { + logger.Error("Failed to add static peer", "error", err) + os.Exit(1) + } +} + // makeNodeConfig parses incoming CLI options and returns node configuration object func makeNodeConfig() (*params.NodeConfig, error) { err := error(nil) @@ -208,13 +255,19 @@ func makeNodeConfig() (*params.NodeConfig, error) { nodeConfig.ListenAddr = "" nodeConfig.NoDiscovery = true + if *staticEnodeAddr != "" { + nodeConfig.ClusterConfig.Enabled = true + nodeConfig.ClusterConfig.StaticNodes = []string{ + *staticEnodeAddr, + } + } return whisperConfig(nodeConfig) } // whisperConfig creates node configuration object from flags func whisperConfig(nodeConfig *params.NodeConfig) (*params.NodeConfig, error) { - whisperConfig := nodeConfig.WhisperConfig + whisperConfig := &nodeConfig.WhisperConfig whisperConfig.Enabled = true whisperConfig.LightClient = true whisperConfig.MinimumPoW = *minPow