2017-05-16 14:09:52 +02:00
|
|
|
package node
|
2016-09-11 13:44:14 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2016-12-07 22:07:08 +01:00
|
|
|
"os"
|
2017-03-28 11:04:52 +02:00
|
|
|
"path/filepath"
|
2021-06-16 22:19:45 +02:00
|
|
|
|
2020-01-02 10:10:19 +01:00
|
|
|
"github.com/syndtr/goleveldb/leveldb"
|
|
|
|
|
2019-08-20 17:38:40 +02:00
|
|
|
"github.com/ethereum/go-ethereum/accounts"
|
2018-03-20 19:35:28 +01:00
|
|
|
"github.com/ethereum/go-ethereum/log"
|
2016-09-11 13:44:14 +02:00
|
|
|
"github.com/ethereum/go-ethereum/node"
|
2017-05-02 16:35:37 +02:00
|
|
|
"github.com/ethereum/go-ethereum/p2p"
|
2018-04-10 08:44:09 +02:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/discv5"
|
2018-11-14 08:03:58 +01:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
2017-03-10 01:16:32 +01:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
2020-01-02 10:10:19 +01:00
|
|
|
|
2019-11-23 18:57:05 +01:00
|
|
|
"github.com/status-im/status-go/eth-node/crypto"
|
2018-06-08 13:29:50 +02:00
|
|
|
"github.com/status-im/status-go/params"
|
2016-09-11 13:44:14 +02:00
|
|
|
)
|
|
|
|
|
2018-04-16 14:36:09 +02:00
|
|
|
// Errors related to node and services creation.
|
2016-12-07 22:07:08 +01:00
|
|
|
var (
|
2018-09-13 18:31:29 +02:00
|
|
|
ErrNodeMakeFailureFormat = "error creating p2p node: %s"
|
2020-01-08 12:12:23 +01:00
|
|
|
ErrWakuServiceRegistrationFailure = errors.New("failed to register the Waku service")
|
2021-06-16 22:19:45 +02:00
|
|
|
ErrWakuV2ServiceRegistrationFailure = errors.New("failed to register the WakuV2 service")
|
2018-09-13 18:31:29 +02:00
|
|
|
ErrLightEthRegistrationFailure = errors.New("failed to register the LES service")
|
|
|
|
ErrLightEthRegistrationFailureUpstreamEnabled = errors.New("failed to register the LES service, upstream is also configured")
|
|
|
|
ErrPersonalServiceRegistrationFailure = errors.New("failed to register the personal api service")
|
|
|
|
ErrStatusServiceRegistrationFailure = errors.New("failed to register the Status service")
|
|
|
|
ErrPeerServiceRegistrationFailure = errors.New("failed to register the Peer service")
|
2016-12-07 22:07:08 +01:00
|
|
|
)
|
2016-09-11 13:44:14 +02:00
|
|
|
|
2018-03-20 19:35:28 +01:00
|
|
|
// All general log messages in this package should be routed through this logger.
|
2018-06-08 13:29:50 +02:00
|
|
|
var logger = log.New("package", "status-go/node")
|
2018-03-20 19:35:28 +01:00
|
|
|
|
2018-09-13 18:31:29 +02:00
|
|
|
// MakeNode creates a geth node entity
|
2019-08-20 17:38:40 +02:00
|
|
|
func MakeNode(config *params.NodeConfig, accs *accounts.Manager, db *leveldb.DB) (*node.Node, error) {
|
2018-04-16 14:36:09 +02:00
|
|
|
// If DataDir is empty, it means we want to create an ephemeral node
|
|
|
|
// keeping data only in memory.
|
|
|
|
if config.DataDir != "" {
|
|
|
|
// make sure data directory exists
|
|
|
|
if err := os.MkdirAll(filepath.Clean(config.DataDir), os.ModePerm); err != nil {
|
|
|
|
return nil, fmt.Errorf("make node: make data directory: %v", err)
|
|
|
|
}
|
2017-05-16 14:09:52 +02:00
|
|
|
|
2018-04-16 14:36:09 +02:00
|
|
|
// make sure keys directory exists
|
|
|
|
if err := os.MkdirAll(filepath.Clean(config.KeyStoreDir), os.ModePerm); err != nil {
|
|
|
|
return nil, fmt.Errorf("make node: make keys directory: %v", err)
|
|
|
|
}
|
2017-04-28 10:49:15 +02:00
|
|
|
}
|
2017-03-28 11:04:52 +02:00
|
|
|
|
2018-09-13 18:31:29 +02:00
|
|
|
stackConfig, err := newGethNodeConfig(config)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2016-09-11 13:44:14 +02:00
|
|
|
}
|
|
|
|
|
2017-01-26 01:39:20 +01:00
|
|
|
stack, err := node.New(stackConfig)
|
2016-09-11 13:44:14 +02:00
|
|
|
if err != nil {
|
2018-07-21 17:32:53 +02:00
|
|
|
return nil, fmt.Errorf(ErrNodeMakeFailureFormat, err.Error())
|
2016-09-11 13:44:14 +02:00
|
|
|
}
|
|
|
|
|
2019-07-21 07:41:30 +02:00
|
|
|
return stack, nil
|
|
|
|
}
|
|
|
|
|
2018-09-13 18:31:29 +02:00
|
|
|
// newGethNodeConfig returns default stack configuration for mobile client node
|
|
|
|
func newGethNodeConfig(config *params.NodeConfig) (*node.Config, error) {
|
2021-07-12 13:18:46 +02:00
|
|
|
// NOTE: I haven't changed anything related to this parameters, but
|
2021-07-07 08:11:09 +02:00
|
|
|
// it seems they were previously ignored if set to 0, but now they seem
|
|
|
|
// to be used, so they need to be set to something
|
|
|
|
maxPeers := 100
|
|
|
|
maxPendingPeers := 100
|
|
|
|
|
|
|
|
if config.MaxPeers != 0 {
|
|
|
|
maxPeers = config.MaxPeers
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.MaxPendingPeers != 0 {
|
|
|
|
maxPendingPeers = config.MaxPendingPeers
|
|
|
|
}
|
|
|
|
|
2017-07-13 08:54:10 +02:00
|
|
|
nc := &node.Config{
|
2017-05-16 05:24:56 +02:00
|
|
|
DataDir: config.DataDir,
|
|
|
|
KeyStoreDir: config.KeyStoreDir,
|
|
|
|
UseLightweightKDF: true,
|
2017-05-16 14:09:52 +02:00
|
|
|
NoUSB: true,
|
2017-05-16 05:24:56 +02:00
|
|
|
Name: config.Name,
|
|
|
|
Version: config.Version,
|
|
|
|
P2P: p2p.Config{
|
2021-07-07 08:11:09 +02:00
|
|
|
NoDiscovery: true, // we always use only v5 server
|
2023-02-23 17:07:18 +01:00
|
|
|
ListenAddr: config.ListenAddr,
|
2021-07-07 08:11:09 +02:00
|
|
|
NAT: nat.Any(),
|
|
|
|
MaxPeers: maxPeers,
|
|
|
|
MaxPendingPeers: maxPendingPeers,
|
2017-05-16 05:24:56 +02:00
|
|
|
},
|
2018-10-12 14:58:32 +02:00
|
|
|
HTTPModules: config.FormatAPIModules(),
|
2017-05-16 05:24:56 +02:00
|
|
|
}
|
2017-07-13 08:54:10 +02:00
|
|
|
|
2018-10-11 12:29:59 +02:00
|
|
|
if config.IPCEnabled {
|
|
|
|
// use well-known defaults
|
|
|
|
if config.IPCFile == "" {
|
|
|
|
config.IPCFile = "geth.ipc"
|
|
|
|
}
|
|
|
|
|
|
|
|
nc.IPCPath = config.IPCFile
|
|
|
|
}
|
|
|
|
|
2018-09-21 16:09:31 +02:00
|
|
|
if config.HTTPEnabled {
|
2017-07-13 08:54:10 +02:00
|
|
|
nc.HTTPHost = config.HTTPHost
|
|
|
|
nc.HTTPPort = config.HTTPPort
|
2018-10-12 14:58:32 +02:00
|
|
|
nc.HTTPVirtualHosts = config.HTTPVirtualHosts
|
|
|
|
nc.HTTPCors = config.HTTPCors
|
2017-07-13 08:54:10 +02:00
|
|
|
}
|
|
|
|
|
2018-09-13 18:31:29 +02:00
|
|
|
if config.ClusterConfig.Enabled {
|
2018-04-10 08:44:09 +02:00
|
|
|
nc.P2P.BootstrapNodesV5 = parseNodesV5(config.ClusterConfig.BootNodes)
|
2018-04-20 14:23:18 +02:00
|
|
|
nc.P2P.StaticNodes = parseNodes(config.ClusterConfig.StaticNodes)
|
2017-12-07 13:07:45 +01:00
|
|
|
}
|
2018-09-13 18:31:29 +02:00
|
|
|
|
|
|
|
if config.NodeKey != "" {
|
|
|
|
sk, err := crypto.HexToECDSA(config.NodeKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// override node's private key
|
|
|
|
nc.P2P.PrivateKey = sk
|
|
|
|
}
|
|
|
|
|
|
|
|
return nc, nil
|
|
|
|
}
|
|
|
|
|
2018-11-14 08:03:58 +01:00
|
|
|
// parseNodes creates list of enode.Node out of enode strings.
|
|
|
|
func parseNodes(enodes []string) []*enode.Node {
|
|
|
|
var nodes []*enode.Node
|
|
|
|
for _, item := range enodes {
|
|
|
|
parsedPeer, err := enode.ParseV4(item)
|
2018-06-04 15:47:13 +02:00
|
|
|
if err == nil {
|
|
|
|
nodes = append(nodes, parsedPeer)
|
|
|
|
} else {
|
2018-11-14 08:03:58 +01:00
|
|
|
logger.Error("Failed to parse enode", "enode", item, "err", err)
|
2018-06-04 15:47:13 +02:00
|
|
|
}
|
|
|
|
|
2017-02-20 10:44:38 +01:00
|
|
|
}
|
2018-03-20 15:05:21 +01:00
|
|
|
return nodes
|
2017-02-20 10:44:38 +01:00
|
|
|
}
|
2018-04-10 08:44:09 +02:00
|
|
|
|
|
|
|
// parseNodesV5 creates list of discv5.Node out of enode strings.
|
|
|
|
func parseNodesV5(enodes []string) []*discv5.Node {
|
2018-06-04 15:47:13 +02:00
|
|
|
var nodes []*discv5.Node
|
|
|
|
for _, enode := range enodes {
|
|
|
|
parsedPeer, err := discv5.ParseNode(enode)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
nodes = append(nodes, parsedPeer)
|
|
|
|
} else {
|
|
|
|
logger.Error("Failed to parse enode", "enode", enode, "err", err)
|
|
|
|
}
|
2018-04-10 08:44:09 +02:00
|
|
|
}
|
|
|
|
return nodes
|
|
|
|
}
|
2018-06-13 13:24:04 +02:00
|
|
|
|
2018-11-14 08:03:58 +01:00
|
|
|
func parseNodesToNodeID(enodes []string) []enode.ID {
|
|
|
|
nodeIDs := make([]enode.ID, 0, len(enodes))
|
2018-07-25 16:48:02 +02:00
|
|
|
for _, node := range parseNodes(enodes) {
|
2018-11-14 08:03:58 +01:00
|
|
|
nodeIDs = append(nodeIDs, node.ID())
|
2018-07-25 16:48:02 +02:00
|
|
|
}
|
|
|
|
return nodeIDs
|
|
|
|
}
|