mirror of
https://github.com/status-im/status-go.git
synced 2025-02-17 17:28:38 +00:00
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"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/status-im/status-go/cmd/statusd/debug"
|
"github.com/status-im/status-go/cmd/statusd/debug"
|
||||||
"github.com/status-im/status-go/geth/api"
|
"github.com/status-im/status-go/geth/api"
|
||||||
|
"github.com/status-im/status-go/geth/common"
|
||||||
"github.com/status-im/status-go/geth/params"
|
"github.com/status-im/status-go/geth/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,7 +26,8 @@ var (
|
|||||||
nodeKeyFile = flag.String("nodekey", "", "P2P node key file (private key)")
|
nodeKeyFile = flag.String("nodekey", "", "P2P node key file (private key)")
|
||||||
dataDir = flag.String("datadir", params.DataDir, "Data directory for the databases and keystore")
|
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)")
|
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")
|
swarmEnabled = flag.Bool("swarm", false, "Swarm protocol enabled")
|
||||||
httpEnabled = flag.Bool("http", false, "HTTP RPC endpoint enabled (default: false)")
|
httpEnabled = flag.Bool("http", false, "HTTP RPC endpoint enabled (default: false)")
|
||||||
httpPort = flag.Int("httpport", params.HTTPPort, "HTTP RPC server's listening port")
|
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"`)
|
logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`)
|
||||||
logFile = flag.String("logfile", "", "Path to the log file")
|
logFile = flag.String("logfile", "", "Path to the log file")
|
||||||
version = flag.Bool("version", false, "Print version")
|
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)")
|
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")
|
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
|
// shh stuff
|
||||||
identityFile = flag.String("shh.identityfile", "", "Protocol identity file (private key used for asymmetric encryption)")
|
identityFile = flag.String("shh.identityfile", "", "Protocol identity file (private key used for asymmetric encryption)")
|
||||||
@ -74,6 +78,9 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle interrupt signals
|
||||||
|
go haltOnInterruptSignal(backend.NodeManager())
|
||||||
|
|
||||||
// wait till node is started
|
// wait till node is started
|
||||||
<-started
|
<-started
|
||||||
|
|
||||||
@ -132,6 +139,20 @@ func makeNodeConfig() (*params.NodeConfig, error) {
|
|||||||
nodeConfig.LightEthConfig.Enabled = *lesEnabled
|
nodeConfig.LightEthConfig.Enabled = *lesEnabled
|
||||||
nodeConfig.SwarmConfig.Enabled = *swarmEnabled
|
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 {
|
if *whisperEnabled {
|
||||||
return whisperConfig(nodeConfig)
|
return whisperConfig(nodeConfig)
|
||||||
}
|
}
|
||||||
@ -184,3 +205,28 @@ Options:
|
|||||||
fmt.Fprintf(os.Stderr, usage) // nolint: gas
|
fmt.Fprintf(os.Stderr, usage) // nolint: gas
|
||||||
flag.PrintDefaults()
|
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"
|
nodeConfig.HTTPHost = "0.0.0.0"
|
||||||
|
|
||||||
if *standalone {
|
|
||||||
nodeConfig.BootClusterConfig.Enabled = false
|
|
||||||
nodeConfig.BootClusterConfig.BootNodes = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodeConfig, nil
|
return nodeConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +48,7 @@ type NodeManager struct {
|
|||||||
|
|
||||||
// NewNodeManager makes new instance of node manager
|
// NewNodeManager makes new instance of node manager
|
||||||
func NewNodeManager() *NodeManager {
|
func NewNodeManager() *NodeManager {
|
||||||
m := &NodeManager{}
|
return &NodeManager{}
|
||||||
go HaltOnInterruptSignal(m) // allow interrupting running nodes
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartNode start Status node, fails if node is already started
|
// 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/node"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
"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/mailserver"
|
||||||
"github.com/ethereum/go-ethereum/whisper/notifications"
|
"github.com/ethereum/go-ethereum/whisper/notifications"
|
||||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||||
@ -93,11 +91,11 @@ func defaultEmbeddedNodeConfig(config *params.NodeConfig) *node.Config {
|
|||||||
Name: config.Name,
|
Name: config.Name,
|
||||||
Version: config.Version,
|
Version: config.Version,
|
||||||
P2P: p2p.Config{
|
P2P: p2p.Config{
|
||||||
NoDiscovery: true,
|
NoDiscovery: !config.Discovery,
|
||||||
DiscoveryV5: true,
|
DiscoveryV5: true,
|
||||||
DiscoveryV5Addr: ":0",
|
DiscoveryV5Addr: ":0",
|
||||||
BootstrapNodes: makeBootstrapNodes(),
|
BootstrapNodes: nil,
|
||||||
BootstrapNodesV5: makeBootstrapNodesV5(),
|
BootstrapNodesV5: nil,
|
||||||
ListenAddr: config.ListenAddr,
|
ListenAddr: config.ListenAddr,
|
||||||
NAT: nat.Any(),
|
NAT: nat.Any(),
|
||||||
MaxPeers: config.MaxPeers,
|
MaxPeers: config.MaxPeers,
|
||||||
@ -117,9 +115,8 @@ func defaultEmbeddedNodeConfig(config *params.NodeConfig) *node.Config {
|
|||||||
nc.HTTPPort = config.HTTPPort
|
nc.HTTPPort = config.HTTPPort
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.BootClusterConfig.Enabled {
|
if config.Discovery {
|
||||||
nc.P2P.BootstrapNodes = nil
|
nc.P2P.BootstrapNodes = makeBootstrapNodes(config.BootClusterConfig.BootNodes)
|
||||||
nc.P2P.BootstrapNodesV5 = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nc
|
return nc
|
||||||
@ -215,11 +212,7 @@ func makeWSHost(config *params.NodeConfig) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// makeBootstrapNodes returns default (hence bootstrap) list of peers
|
// makeBootstrapNodes returns default (hence bootstrap) list of peers
|
||||||
func makeBootstrapNodes() []*discover.Node {
|
func makeBootstrapNodes(enodes []string) []*discover.Node {
|
||||||
// on desktops params.TestnetBootnodes and params.MainBootnodes,
|
|
||||||
// on mobile client we deliberately keep this list empty
|
|
||||||
enodes := []string{}
|
|
||||||
|
|
||||||
var bootstrapNodes []*discover.Node
|
var bootstrapNodes []*discover.Node
|
||||||
for _, enode := range enodes {
|
for _, enode := range enodes {
|
||||||
bootstrapNodes = append(bootstrapNodes, discover.MustParseNode(enode))
|
bootstrapNodes = append(bootstrapNodes, discover.MustParseNode(enode))
|
||||||
@ -227,15 +220,3 @@ func makeBootstrapNodes() []*discover.Node {
|
|||||||
|
|
||||||
return bootstrapNodes
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
osSignal "os/signal"
|
|
||||||
|
|
||||||
"github.com/status-im/status-go/geth/common"
|
"github.com/status-im/status-go/geth/common"
|
||||||
"github.com/status-im/status-go/geth/log"
|
|
||||||
"github.com/status-im/status-go/geth/signal"
|
"github.com/status-im/status-go/geth/signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,23 +23,3 @@ func HaltOnPanic() {
|
|||||||
common.Fatalf(err) // os.exit(1) is called internally
|
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.
|
// remote peer identification as well as network traffic encryption.
|
||||||
NodeKeyFile string
|
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 is an IP address and port of this node (e.g. 127.0.0.1:30303).
|
||||||
ListenAddr string
|
ListenAddr string
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user