Manage discovery from flags and refactor handling interrupt signals (#557)
This commit is contained in:
parent
cb0a889245
commit
e214e1e270
|
@ -5,11 +5,14 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/status-im/status-go/cmd/statusd/debug"
|
||||
"github.com/status-im/status-go/geth/api"
|
||||
"github.com/status-im/status-go/geth/common"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
|
@ -23,7 +26,8 @@ var (
|
|||
nodeKeyFile = flag.String("nodekey", "", "P2P node key file (private key)")
|
||||
dataDir = flag.String("datadir", params.DataDir, "Data directory for the databases and keystore")
|
||||
networkID = flag.Int("networkid", params.RopstenNetworkID, "Network identifier (integer, 1=Homestead, 3=Ropsten, 4=Rinkeby, 777=StatusChain)")
|
||||
whisperEnabled = flag.Bool("shh", false, "SHH protocol enabled")
|
||||
lesEnabled = flag.Bool("les", false, "LES protocol enabled (default is disabled)")
|
||||
whisperEnabled = flag.Bool("shh", false, "Whisper protocol enabled (default is disabled)")
|
||||
swarmEnabled = flag.Bool("swarm", false, "Swarm protocol enabled")
|
||||
httpEnabled = flag.Bool("http", false, "HTTP RPC endpoint enabled (default: false)")
|
||||
httpPort = flag.Int("httpport", params.HTTPPort, "HTTP RPC server's listening port")
|
||||
|
@ -33,10 +37,10 @@ var (
|
|||
logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`)
|
||||
logFile = flag.String("logfile", "", "Path to the log file")
|
||||
version = flag.Bool("version", false, "Print version")
|
||||
lesEnabled = flag.Bool("les", true, "LES protocol enabled")
|
||||
|
||||
listenAddr = flag.String("listenaddr", ":30303", "IP address and port of this node (e.g. 127.0.0.1:30303)")
|
||||
standalone = flag.Bool("standalone", true, "Don't actively connect to peers, wait for incoming connections")
|
||||
bootnodes = flag.String("bootnodes", "", "A list of bootnodes separated by comma")
|
||||
|
||||
// shh stuff
|
||||
identityFile = flag.String("shh.identityfile", "", "Protocol identity file (private key used for asymmetric encryption)")
|
||||
|
@ -74,6 +78,9 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
// handle interrupt signals
|
||||
go haltOnInterruptSignal(backend.NodeManager())
|
||||
|
||||
// wait till node is started
|
||||
<-started
|
||||
|
||||
|
@ -132,6 +139,20 @@ func makeNodeConfig() (*params.NodeConfig, error) {
|
|||
nodeConfig.LightEthConfig.Enabled = *lesEnabled
|
||||
nodeConfig.SwarmConfig.Enabled = *swarmEnabled
|
||||
|
||||
if *standalone {
|
||||
nodeConfig.BootClusterConfig.Enabled = false
|
||||
nodeConfig.BootClusterConfig.BootNodes = nil
|
||||
} else {
|
||||
nodeConfig.Discovery = true
|
||||
}
|
||||
|
||||
// Even if standalone is true and discovery is disabled,
|
||||
// it's possible to use bootnodes in NodeManager.PopulateStaticPeers().
|
||||
// TODO(adam): research if we need NodeManager.PopulateStaticPeers() at all.
|
||||
if *bootnodes != "" {
|
||||
nodeConfig.BootClusterConfig.BootNodes = strings.Split(*bootnodes, ",")
|
||||
}
|
||||
|
||||
if *whisperEnabled {
|
||||
return whisperConfig(nodeConfig)
|
||||
}
|
||||
|
@ -184,3 +205,28 @@ Options:
|
|||
fmt.Fprintf(os.Stderr, usage) // nolint: gas
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
// haltOnInterruptSignal catches interrupt signal (SIGINT) and
|
||||
// stops the node. It times out after 5 seconds
|
||||
// if the node can not be stopped.
|
||||
func haltOnInterruptSignal(nodeManager common.NodeManager) {
|
||||
signalCh := make(chan os.Signal, 1)
|
||||
signal.Notify(signalCh, os.Interrupt)
|
||||
defer signal.Stop(signalCh)
|
||||
<-signalCh
|
||||
|
||||
log.Println("Got interrupt, shutting down...")
|
||||
|
||||
nodeStopped, err := nodeManager.StopNode()
|
||||
if err != nil {
|
||||
log.Printf("Failed to stop node: %v", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-nodeStopped:
|
||||
case <-time.After(time.Second * 5):
|
||||
log.Printf("Stopping node timed out")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,11 +64,6 @@ func whisperConfig(nodeConfig *params.NodeConfig) (*params.NodeConfig, error) {
|
|||
}
|
||||
nodeConfig.HTTPHost = "0.0.0.0"
|
||||
|
||||
if *standalone {
|
||||
nodeConfig.BootClusterConfig.Enabled = false
|
||||
nodeConfig.BootClusterConfig.BootNodes = nil
|
||||
}
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -48,10 +48,7 @@ type NodeManager struct {
|
|||
|
||||
// NewNodeManager makes new instance of node manager
|
||||
func NewNodeManager() *NodeManager {
|
||||
m := &NodeManager{}
|
||||
go HaltOnInterruptSignal(m) // allow interrupting running nodes
|
||||
|
||||
return m
|
||||
return &NodeManager{}
|
||||
}
|
||||
|
||||
// StartNode start Status node, fails if node is already started
|
||||
|
|
|
@ -17,9 +17,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
gethparams "github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/whisper/mailserver"
|
||||
"github.com/ethereum/go-ethereum/whisper/notifications"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||
|
@ -93,11 +91,11 @@ func defaultEmbeddedNodeConfig(config *params.NodeConfig) *node.Config {
|
|||
Name: config.Name,
|
||||
Version: config.Version,
|
||||
P2P: p2p.Config{
|
||||
NoDiscovery: true,
|
||||
NoDiscovery: !config.Discovery,
|
||||
DiscoveryV5: true,
|
||||
DiscoveryV5Addr: ":0",
|
||||
BootstrapNodes: makeBootstrapNodes(),
|
||||
BootstrapNodesV5: makeBootstrapNodesV5(),
|
||||
BootstrapNodes: nil,
|
||||
BootstrapNodesV5: nil,
|
||||
ListenAddr: config.ListenAddr,
|
||||
NAT: nat.Any(),
|
||||
MaxPeers: config.MaxPeers,
|
||||
|
@ -117,9 +115,8 @@ func defaultEmbeddedNodeConfig(config *params.NodeConfig) *node.Config {
|
|||
nc.HTTPPort = config.HTTPPort
|
||||
}
|
||||
|
||||
if !config.BootClusterConfig.Enabled {
|
||||
nc.P2P.BootstrapNodes = nil
|
||||
nc.P2P.BootstrapNodesV5 = nil
|
||||
if config.Discovery {
|
||||
nc.P2P.BootstrapNodes = makeBootstrapNodes(config.BootClusterConfig.BootNodes)
|
||||
}
|
||||
|
||||
return nc
|
||||
|
@ -215,11 +212,7 @@ func makeWSHost(config *params.NodeConfig) string {
|
|||
}
|
||||
|
||||
// makeBootstrapNodes returns default (hence bootstrap) list of peers
|
||||
func makeBootstrapNodes() []*discover.Node {
|
||||
// on desktops params.TestnetBootnodes and params.MainBootnodes,
|
||||
// on mobile client we deliberately keep this list empty
|
||||
enodes := []string{}
|
||||
|
||||
func makeBootstrapNodes(enodes []string) []*discover.Node {
|
||||
var bootstrapNodes []*discover.Node
|
||||
for _, enode := range enodes {
|
||||
bootstrapNodes = append(bootstrapNodes, discover.MustParseNode(enode))
|
||||
|
@ -227,15 +220,3 @@ func makeBootstrapNodes() []*discover.Node {
|
|||
|
||||
return bootstrapNodes
|
||||
}
|
||||
|
||||
// makeBootstrapNodesV5 returns default (hence bootstrap) list of peers
|
||||
func makeBootstrapNodesV5() []*discv5.Node {
|
||||
enodes := gethparams.DiscoveryV5Bootnodes
|
||||
|
||||
var bootstrapNodes []*discv5.Node
|
||||
for _, enode := range enodes {
|
||||
bootstrapNodes = append(bootstrapNodes, discv5.MustParseNode(enode))
|
||||
}
|
||||
|
||||
return bootstrapNodes
|
||||
}
|
||||
|
|
|
@ -2,11 +2,8 @@ package node
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
osSignal "os/signal"
|
||||
|
||||
"github.com/status-im/status-go/geth/common"
|
||||
"github.com/status-im/status-go/geth/log"
|
||||
"github.com/status-im/status-go/geth/signal"
|
||||
)
|
||||
|
||||
|
@ -26,23 +23,3 @@ func HaltOnPanic() {
|
|||
common.Fatalf(err) // os.exit(1) is called internally
|
||||
}
|
||||
}
|
||||
|
||||
// HaltOnInterruptSignal stops node and panics if you press Ctrl-C enough times
|
||||
func HaltOnInterruptSignal(nodeManager *NodeManager) {
|
||||
sigc := make(chan os.Signal, 1)
|
||||
osSignal.Notify(sigc, os.Interrupt)
|
||||
defer osSignal.Stop(sigc)
|
||||
<-sigc
|
||||
if nodeManager.node == nil {
|
||||
return
|
||||
}
|
||||
log.Info("Got interrupt, shutting down...")
|
||||
go nodeManager.node.Stop() // nolint: errcheck
|
||||
for i := 3; i > 0; i-- {
|
||||
<-sigc
|
||||
if i > 1 {
|
||||
log.Info(fmt.Sprintf("Already shutting down, interrupt %d more times for panic.", i-1))
|
||||
}
|
||||
}
|
||||
panic("interrupted!")
|
||||
}
|
||||
|
|
|
@ -230,6 +230,9 @@ type NodeConfig struct {
|
|||
// remote peer identification as well as network traffic encryption.
|
||||
NodeKeyFile string
|
||||
|
||||
// Discovery set to true will enabled discovery protocol.
|
||||
Discovery bool
|
||||
|
||||
// ListenAddr is an IP address and port of this node (e.g. 127.0.0.1:30303).
|
||||
ListenAddr string
|
||||
|
||||
|
|
Loading…
Reference in New Issue