2021-04-13 18:54:06 +00:00
|
|
|
package waku
|
2021-03-18 23:21:45 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-10-04 22:38:27 +00:00
|
|
|
"crypto/ecdsa"
|
2021-04-19 00:03:16 +00:00
|
|
|
"database/sql"
|
2021-03-18 23:21:45 +00:00
|
|
|
"encoding/hex"
|
2021-04-13 18:54:06 +00:00
|
|
|
"errors"
|
2021-03-18 23:21:45 +00:00
|
|
|
"fmt"
|
2021-10-04 22:38:27 +00:00
|
|
|
"io/ioutil"
|
2021-03-18 23:21:45 +00:00
|
|
|
"net"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
2021-06-24 13:02:53 +00:00
|
|
|
"time"
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2021-03-23 14:46:16 +00:00
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
2021-09-30 23:03:19 +00:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
2021-04-13 18:54:06 +00:00
|
|
|
dssql "github.com/ipfs/go-ds-sql"
|
2022-02-21 15:23:52 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
2022-01-18 18:17:06 +00:00
|
|
|
"go.uber.org/zap"
|
2021-10-03 21:45:07 +00:00
|
|
|
|
2021-04-13 18:54:06 +00:00
|
|
|
"github.com/libp2p/go-libp2p"
|
2021-10-04 22:38:27 +00:00
|
|
|
libp2pcrypto "github.com/libp2p/go-libp2p-core/crypto"
|
2021-11-16 14:22:01 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/discovery"
|
2022-05-27 13:25:06 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2021-10-15 02:15:02 +00:00
|
|
|
"github.com/libp2p/go-libp2p/config"
|
2021-10-04 22:38:27 +00:00
|
|
|
|
2021-04-13 18:54:06 +00:00
|
|
|
"github.com/libp2p/go-libp2p-peerstore/pstoreds"
|
2021-10-08 13:50:56 +00:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
2021-04-22 13:07:22 +00:00
|
|
|
"github.com/multiformats/go-multiaddr"
|
2021-10-05 02:13:54 +00:00
|
|
|
rendezvous "github.com/status-im/go-waku-rendezvous"
|
2022-05-27 13:25:06 +00:00
|
|
|
"github.com/status-im/go-waku/logging"
|
2021-06-28 13:20:23 +00:00
|
|
|
"github.com/status-im/go-waku/waku/metrics"
|
2021-04-13 18:54:06 +00:00
|
|
|
"github.com/status-im/go-waku/waku/persistence"
|
|
|
|
"github.com/status-im/go-waku/waku/persistence/sqlite"
|
2021-11-16 14:22:01 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/dnsdisc"
|
2021-03-18 23:21:45 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/node"
|
2021-09-30 16:01:53 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/protocol/filter"
|
|
|
|
"github.com/status-im/go-waku/waku/v2/protocol/lightpush"
|
2021-04-28 20:10:44 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/protocol/relay"
|
2021-09-30 16:01:53 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/protocol/store"
|
2021-11-02 09:54:34 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/rpc"
|
2022-01-18 18:17:06 +00:00
|
|
|
"github.com/status-im/go-waku/waku/v2/utils"
|
2021-03-18 23:21:45 +00:00
|
|
|
)
|
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
func failOnErr(err error, msg string) {
|
2021-04-13 18:54:06 +00:00
|
|
|
if err != nil {
|
2022-01-18 18:17:06 +00:00
|
|
|
utils.Logger().Fatal(msg, zap.Error(err))
|
2021-04-13 18:54:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-17 16:19:42 +00:00
|
|
|
func freePort() (int, error) {
|
|
|
|
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
l, err := net.ListenTCP("tcp", addr)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
port := l.Addr().(*net.TCPAddr).Port
|
|
|
|
err = l.Close()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return port, nil
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:18:53 +00:00
|
|
|
// Execute starts a go-waku node with settings determined by the Options parameter
|
2021-10-03 21:45:07 +00:00
|
|
|
func Execute(options Options) {
|
2021-10-04 22:38:27 +00:00
|
|
|
if options.GenerateKey {
|
|
|
|
if err := writePrivateKeyToFile(options.KeyFile, options.Overwrite); err != nil {
|
|
|
|
failOnErr(err, "nodekey error")
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-10-15 02:15:02 +00:00
|
|
|
hostAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", options.Address, options.Port))
|
|
|
|
failOnErr(err, "invalid host address")
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2021-10-04 22:38:27 +00:00
|
|
|
prvKey, err := getPrivKey(options)
|
|
|
|
failOnErr(err, "nodekey error")
|
2021-04-13 18:54:06 +00:00
|
|
|
|
2022-05-27 19:55:35 +00:00
|
|
|
p2pPrvKey := utils.EcdsaPrivKeyToSecp256k1PrivKey(prvKey)
|
|
|
|
id, err := peer.IDFromPublicKey(p2pPrvKey.GetPublic())
|
2022-05-27 13:25:06 +00:00
|
|
|
failOnErr(err, "deriving peer ID from private key")
|
|
|
|
logger := utils.Logger().With(logging.HostID("node", id))
|
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.DBPath == "" && options.UseDB {
|
|
|
|
failOnErr(errors.New("dbpath can't be null"), "")
|
|
|
|
}
|
2021-06-28 13:20:23 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
var db *sql.DB
|
|
|
|
if options.UseDB {
|
|
|
|
db, err = sqlite.NewDB(options.DBPath)
|
|
|
|
failOnErr(err, "Could not connect to DB")
|
2022-05-30 18:48:22 +00:00
|
|
|
logger.Debug("using database: ", zap.String("path", options.DBPath))
|
|
|
|
|
|
|
|
} else {
|
|
|
|
db, err = sqlite.NewDB(":memory:")
|
|
|
|
failOnErr(err, "Could not create in-memory DB")
|
|
|
|
logger.Debug("using in-memory database")
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-04-22 13:07:22 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
ctx := context.Background()
|
2021-04-19 00:03:16 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
var metricsServer *metrics.Server
|
|
|
|
if options.Metrics.Enable {
|
2022-05-30 15:55:30 +00:00
|
|
|
metricsServer = metrics.NewMetricsServer(options.Metrics.Address, options.Metrics.Port, logger)
|
2021-10-03 21:45:07 +00:00
|
|
|
go metricsServer.Start()
|
|
|
|
}
|
2021-04-19 00:03:16 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
nodeOpts := []node.WakuNodeOption{
|
2022-05-27 13:25:06 +00:00
|
|
|
node.WithLogger(logger),
|
2021-10-03 21:45:07 +00:00
|
|
|
node.WithPrivateKey(prvKey),
|
2021-11-17 16:19:42 +00:00
|
|
|
node.WithHostAddress(hostAddr),
|
2021-10-03 21:45:07 +00:00
|
|
|
node.WithKeepAlive(time.Duration(options.KeepAlive) * time.Second),
|
|
|
|
}
|
2021-04-19 00:03:16 +00:00
|
|
|
|
2021-10-15 02:15:02 +00:00
|
|
|
if options.AdvertiseAddress != "" {
|
|
|
|
advertiseAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", options.AdvertiseAddress, options.Port))
|
2021-11-17 16:19:42 +00:00
|
|
|
failOnErr(err, "Invalid advertise address")
|
|
|
|
|
|
|
|
if advertiseAddr.Port == 0 {
|
|
|
|
for {
|
|
|
|
p, err := freePort()
|
|
|
|
if err == nil {
|
|
|
|
advertiseAddr.Port = p
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-22 00:48:46 +00:00
|
|
|
nodeOpts = append(nodeOpts, node.WithAdvertiseAddress(advertiseAddr))
|
|
|
|
}
|
|
|
|
|
|
|
|
if options.Dns4DomainName != "" {
|
|
|
|
nodeOpts = append(nodeOpts, node.WithDns4Domain(options.Dns4DomainName))
|
2021-10-15 02:15:02 +00:00
|
|
|
}
|
|
|
|
|
2022-03-22 13:12:58 +00:00
|
|
|
libp2pOpts := node.DefaultLibP2POptions
|
|
|
|
if options.AdvertiseAddress == "" {
|
|
|
|
libp2pOpts = append(libp2pOpts, libp2p.NATPortMap()) // Attempt to open ports using uPNP for NATed hosts.)
|
|
|
|
}
|
|
|
|
|
|
|
|
if options.Websocket.Enable {
|
|
|
|
nodeOpts = append(nodeOpts, node.WithWebsockets(options.Websocket.Address, options.Websocket.Port))
|
|
|
|
}
|
|
|
|
|
|
|
|
if options.Websocket.Secure {
|
|
|
|
nodeOpts = append(nodeOpts, node.WithSecureWebsockets(options.Websocket.Address, options.Websocket.Port, options.Websocket.CertPath, options.Websocket.KeyPath))
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-04-19 00:03:16 +00:00
|
|
|
|
2021-10-14 18:17:01 +00:00
|
|
|
if options.ShowAddresses {
|
2021-10-15 02:15:02 +00:00
|
|
|
printListeningAddresses(ctx, nodeOpts, options)
|
2021-10-14 18:17:01 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.UseDB {
|
|
|
|
// Create persistent peerstore
|
|
|
|
queries, err := sqlite.NewQueries("peerstore", db)
|
|
|
|
failOnErr(err, "Peerstore")
|
2021-10-01 17:43:03 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
datastore := dssql.NewDatastore(db, queries)
|
|
|
|
opts := pstoreds.DefaultOpts()
|
|
|
|
peerStore, err := pstoreds.NewPeerstore(ctx, datastore, opts)
|
|
|
|
failOnErr(err, "Peerstore")
|
2021-10-01 17:43:03 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
libp2pOpts = append(libp2pOpts, libp2p.Peerstore(peerStore))
|
|
|
|
}
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
nodeOpts = append(nodeOpts, node.WithLibP2POptions(libp2pOpts...))
|
2021-10-01 17:49:50 +00:00
|
|
|
|
2022-02-21 15:23:52 +00:00
|
|
|
if options.Relay.Enable {
|
2021-10-03 21:45:07 +00:00
|
|
|
var wakurelayopts []pubsub.Option
|
|
|
|
wakurelayopts = append(wakurelayopts, pubsub.WithPeerExchange(options.Relay.PeerExchange))
|
2021-12-06 08:43:00 +00:00
|
|
|
nodeOpts = append(nodeOpts, node.WithWakuRelayAndMinPeers(options.Relay.MinRelayPeersToPublish, wakurelayopts...))
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-06-10 12:59:51 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.RendezvousServer.Enable {
|
2021-10-14 14:14:55 +00:00
|
|
|
db, err := persistence.NewRendezVousLevelDB(options.RendezvousServer.DBPath)
|
2021-10-03 21:45:07 +00:00
|
|
|
failOnErr(err, "RendezvousDB")
|
|
|
|
storage := rendezvous.NewStorage(db)
|
|
|
|
nodeOpts = append(nodeOpts, node.WithRendezvousServer(storage))
|
|
|
|
}
|
2021-04-13 18:54:06 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.Filter.Enable {
|
2021-12-08 13:00:20 +00:00
|
|
|
nodeOpts = append(nodeOpts, node.WithWakuFilter(!options.Filter.DisableFullNode, filter.WithTimeout(time.Duration(options.Filter.Timeout)*time.Second)))
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-06-28 14:14:28 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.Store.Enable {
|
2022-06-13 18:30:35 +00:00
|
|
|
if options.Store.PersistMessages {
|
|
|
|
nodeOpts = append(nodeOpts, node.WithWakuStoreAndRetentionPolicy(options.Store.ShouldResume, options.Store.RetentionMaxDaysDuration(), options.Store.RetentionMaxMessages))
|
|
|
|
dbStore, err := persistence.NewDBStore(logger, persistence.WithDB(db), persistence.WithRetentionPolicy(options.Store.RetentionMaxMessages, options.Store.RetentionMaxDaysDuration()))
|
|
|
|
failOnErr(err, "DBStore")
|
|
|
|
nodeOpts = append(nodeOpts, node.WithMessageProvider(dbStore))
|
|
|
|
} else {
|
|
|
|
nodeOpts = append(nodeOpts, node.WithWakuStore(false, false))
|
|
|
|
}
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-09-30 16:01:53 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.LightPush.Enable {
|
|
|
|
nodeOpts = append(nodeOpts, node.WithLightPush())
|
|
|
|
}
|
2021-04-12 17:59:41 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.Rendezvous.Enable {
|
2021-11-16 14:22:01 +00:00
|
|
|
nodeOpts = append(nodeOpts, node.WithRendezvous(pubsub.WithDiscoveryOpts(discovery.Limit(45), discovery.TTL(time.Duration(20)*time.Second))))
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2022-05-05 19:17:35 +00:00
|
|
|
var discoveredNodes []dnsdisc.DiscoveredNode
|
|
|
|
if options.DNSDiscovery.Enable {
|
|
|
|
if options.DNSDiscovery.URL != "" {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Info("attempting DNS discovery with ", zap.String("URL", options.DNSDiscovery.URL))
|
2022-05-05 19:17:35 +00:00
|
|
|
nodes, err := dnsdisc.RetrieveNodes(ctx, options.DNSDiscovery.URL, dnsdisc.WithNameserver(options.DNSDiscovery.Nameserver))
|
|
|
|
if err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Warn("dns discovery error ", zap.Error(err))
|
2022-05-05 19:17:35 +00:00
|
|
|
} else {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Info("found dns entries ", zap.Any("qty", len(nodes)))
|
2022-05-05 19:17:35 +00:00
|
|
|
discoveredNodes = nodes
|
|
|
|
}
|
|
|
|
} else {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Fatal("DNS discovery URL is required")
|
2022-05-05 19:17:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-17 16:19:42 +00:00
|
|
|
if options.DiscV5.Enable {
|
|
|
|
var bootnodes []*enode.Node
|
2022-02-21 15:23:52 +00:00
|
|
|
for _, addr := range options.DiscV5.Nodes.Value() {
|
2021-11-17 16:19:42 +00:00
|
|
|
bootnode, err := enode.Parse(enode.ValidSchemes, addr)
|
|
|
|
if err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Fatal("parsing ENR", zap.Error(err))
|
2021-11-17 16:19:42 +00:00
|
|
|
}
|
|
|
|
bootnodes = append(bootnodes, bootnode)
|
|
|
|
}
|
2022-05-05 19:17:35 +00:00
|
|
|
|
|
|
|
for _, n := range discoveredNodes {
|
|
|
|
if n.ENR != nil {
|
|
|
|
bootnodes = append(bootnodes, n.ENR)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-17 16:19:42 +00:00
|
|
|
nodeOpts = append(nodeOpts, node.WithDiscoveryV5(options.DiscV5.Port, bootnodes, options.DiscV5.AutoUpdate, pubsub.WithDiscoveryOpts(discovery.Limit(45), discovery.TTL(time.Duration(20)*time.Second))))
|
|
|
|
}
|
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
wakuNode, err := node.New(ctx, nodeOpts...)
|
2021-04-15 21:23:07 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
failOnErr(err, "Wakunode")
|
2021-09-30 16:01:53 +00:00
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
addPeers(wakuNode, options.Rendezvous.Nodes.Value(), string(rendezvous.RendezvousID_v001))
|
|
|
|
addPeers(wakuNode, options.Store.Nodes.Value(), string(store.StoreID_v20beta4))
|
|
|
|
addPeers(wakuNode, options.LightPush.Nodes.Value(), string(lightpush.LightPushID_v20beta1))
|
|
|
|
addPeers(wakuNode, options.Filter.Nodes.Value(), string(filter.FilterID_v20beta1))
|
2021-10-05 02:13:54 +00:00
|
|
|
|
2021-10-06 15:42:57 +00:00
|
|
|
if err = wakuNode.Start(); err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Fatal("starting waku node", zap.Error(err))
|
2021-10-06 15:42:57 +00:00
|
|
|
}
|
2021-10-05 02:13:54 +00:00
|
|
|
|
2021-11-17 16:19:42 +00:00
|
|
|
if options.DiscV5.Enable {
|
|
|
|
if err = wakuNode.DiscV5().Start(); err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Fatal("starting discovery v5", zap.Error(err))
|
2021-11-17 16:19:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-21 15:23:52 +00:00
|
|
|
if len(options.Relay.Topics.Value()) == 0 {
|
|
|
|
options.Relay.Topics = *cli.NewStringSlice(relay.DefaultWakuTopic)
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-09-30 16:01:53 +00:00
|
|
|
|
2022-02-21 15:23:52 +00:00
|
|
|
if options.Relay.Enable {
|
|
|
|
for _, nodeTopic := range options.Relay.Topics.Value() {
|
2022-04-25 19:31:26 +00:00
|
|
|
nodeTopic := nodeTopic
|
2022-02-18 17:49:11 +00:00
|
|
|
sub, err := wakuNode.Relay().SubscribeToTopic(ctx, nodeTopic)
|
2021-10-30 14:29:34 +00:00
|
|
|
failOnErr(err, "Error subscring to topic")
|
2022-04-25 19:31:26 +00:00
|
|
|
wakuNode.Broadcaster().Unregister(&nodeTopic, sub.C)
|
2021-10-30 14:29:34 +00:00
|
|
|
}
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2022-02-21 15:23:52 +00:00
|
|
|
for _, n := range options.StaticNodes.Value() {
|
2021-10-03 21:45:07 +00:00
|
|
|
go func(node string) {
|
|
|
|
err = wakuNode.DialPeer(ctx, node)
|
|
|
|
if err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Error("dialing peer", zap.Error(err))
|
2021-03-18 23:21:45 +00:00
|
|
|
}
|
2021-10-03 21:45:07 +00:00
|
|
|
}(n)
|
|
|
|
}
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2022-05-05 19:17:35 +00:00
|
|
|
if len(discoveredNodes) != 0 {
|
|
|
|
for _, n := range discoveredNodes {
|
|
|
|
for _, m := range n.Addresses {
|
|
|
|
go func(ctx context.Context, m multiaddr.Multiaddr) {
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, time.Duration(3)*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
err = wakuNode.DialPeerWithMultiAddress(ctx, m)
|
|
|
|
if err != nil {
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Error("dialing peer ", zap.Error(err))
|
2022-05-05 19:17:35 +00:00
|
|
|
}
|
|
|
|
}(ctx, m)
|
2021-09-30 23:03:19 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-09-30 23:03:19 +00:00
|
|
|
|
2021-11-02 09:54:34 +00:00
|
|
|
var rpcServer *rpc.WakuRpc
|
|
|
|
if options.RPCServer.Enable {
|
2022-05-30 15:55:30 +00:00
|
|
|
rpcServer = rpc.NewWakuRpc(wakuNode, options.RPCServer.Address, options.RPCServer.Port, options.RPCServer.Admin, options.RPCServer.Private, logger)
|
2021-11-19 14:17:38 +00:00
|
|
|
rpcServer.Start()
|
2021-11-02 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
2022-05-30 18:48:22 +00:00
|
|
|
logger.Info("Node setup complete")
|
2022-05-26 12:23:10 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
// Wait for a SIGINT or SIGTERM signal
|
|
|
|
ch := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
<-ch
|
2022-05-27 13:25:06 +00:00
|
|
|
logger.Info("Received signal, shutting down...")
|
2021-04-19 00:03:16 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
// shut the node down
|
|
|
|
wakuNode.Stop()
|
2021-06-28 13:20:23 +00:00
|
|
|
|
2021-11-02 09:54:34 +00:00
|
|
|
if options.RPCServer.Enable {
|
|
|
|
err := rpcServer.Stop(ctx)
|
|
|
|
failOnErr(err, "RPCClose")
|
|
|
|
}
|
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.Metrics.Enable {
|
2021-10-18 12:43:17 +00:00
|
|
|
err = metricsServer.Stop(ctx)
|
|
|
|
failOnErr(err, "MetricsClose")
|
2021-10-03 21:45:07 +00:00
|
|
|
}
|
2021-03-18 23:21:45 +00:00
|
|
|
|
2021-10-03 21:45:07 +00:00
|
|
|
if options.UseDB {
|
|
|
|
err = db.Close()
|
|
|
|
failOnErr(err, "DBClose")
|
|
|
|
}
|
2021-03-18 23:21:45 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
func addPeers(wakuNode *node.WakuNode, addresses []string, protocols ...string) {
|
2021-09-30 16:01:53 +00:00
|
|
|
for _, addrString := range addresses {
|
|
|
|
if addrString == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
addr, err := multiaddr.NewMultiaddr(addrString)
|
2021-10-03 21:45:07 +00:00
|
|
|
failOnErr(err, "invalid multiaddress")
|
2021-09-30 16:01:53 +00:00
|
|
|
|
2022-04-25 19:31:26 +00:00
|
|
|
_, err = wakuNode.AddPeer(addr, protocols...)
|
2021-10-03 21:45:07 +00:00
|
|
|
failOnErr(err, "error adding peer")
|
2021-09-30 16:01:53 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-04 22:38:27 +00:00
|
|
|
|
|
|
|
func loadPrivateKeyFromFile(path string) (*ecdsa.PrivateKey, error) {
|
|
|
|
src, err := ioutil.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
dst := make([]byte, hex.DecodedLen(len(src)))
|
|
|
|
_, err = hex.Decode(dst, src)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
p, err := libp2pcrypto.UnmarshalSecp256k1PrivateKey(dst)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-05-27 19:55:35 +00:00
|
|
|
pBytes, err := p.Raw()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-10-04 22:38:27 +00:00
|
|
|
|
2022-05-27 19:55:35 +00:00
|
|
|
return crypto.ToECDSA(pBytes)
|
2021-10-04 22:38:27 +00:00
|
|
|
}
|
|
|
|
|
2021-12-08 14:21:30 +00:00
|
|
|
func checkForPrivateKeyFile(path string, overwrite bool) error {
|
2021-10-04 22:38:27 +00:00
|
|
|
_, err := os.Stat(path)
|
|
|
|
|
2021-12-08 14:21:30 +00:00
|
|
|
if err == nil && !overwrite {
|
2021-10-04 22:38:27 +00:00
|
|
|
return fmt.Errorf("%s already exists. Use --overwrite to overwrite the file", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-12-08 14:21:30 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func generatePrivateKey() ([]byte, error) {
|
2021-10-04 22:38:27 +00:00
|
|
|
key, err := crypto.GenerateKey()
|
|
|
|
if err != nil {
|
2021-12-08 14:21:30 +00:00
|
|
|
return nil, err
|
2021-10-04 22:38:27 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 19:55:35 +00:00
|
|
|
b := key.D.Bytes()
|
2021-10-04 22:38:27 +00:00
|
|
|
|
|
|
|
output := make([]byte, hex.EncodedLen(len(b)))
|
|
|
|
hex.Encode(output, b)
|
|
|
|
|
2021-12-08 14:21:30 +00:00
|
|
|
return output, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func writePrivateKeyToFile(path string, overwrite bool) error {
|
|
|
|
if err := checkForPrivateKeyFile(path, overwrite); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
output, err := generatePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-10-04 22:38:27 +00:00
|
|
|
return ioutil.WriteFile(path, output, 0600)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getPrivKey(options Options) (*ecdsa.PrivateKey, error) {
|
|
|
|
var prvKey *ecdsa.PrivateKey
|
|
|
|
var err error
|
2021-10-05 02:13:54 +00:00
|
|
|
if options.NodeKey != "" {
|
|
|
|
if prvKey, err = crypto.HexToECDSA(options.NodeKey); err != nil {
|
2021-10-04 22:38:27 +00:00
|
|
|
return nil, fmt.Errorf("error converting key into valid ecdsa key: %w", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
keyString := os.Getenv("GOWAKU-NODEKEY")
|
|
|
|
if keyString != "" {
|
2021-10-05 02:13:54 +00:00
|
|
|
if prvKey, err = crypto.HexToECDSA(keyString); err != nil {
|
2021-10-04 22:38:27 +00:00
|
|
|
return nil, fmt.Errorf("error converting key into valid ecdsa key: %w", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if _, err := os.Stat(options.KeyFile); err == nil {
|
2021-10-05 02:13:54 +00:00
|
|
|
if prvKey, err = loadPrivateKeyFromFile(options.KeyFile); err != nil {
|
2021-10-04 22:38:27 +00:00
|
|
|
return nil, fmt.Errorf("could not read keyfile: %w", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if os.IsNotExist(err) {
|
2021-10-05 02:13:54 +00:00
|
|
|
if prvKey, err = crypto.GenerateKey(); err != nil {
|
2021-10-04 22:38:27 +00:00
|
|
|
return nil, fmt.Errorf("error generating key: %w", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return nil, fmt.Errorf("could not read keyfile: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return prvKey, nil
|
|
|
|
}
|
2021-10-14 18:17:01 +00:00
|
|
|
|
2021-10-15 02:15:02 +00:00
|
|
|
func printListeningAddresses(ctx context.Context, nodeOpts []node.WakuNodeOption, options Options) {
|
2021-10-14 18:17:01 +00:00
|
|
|
params := new(node.WakuNodeParameters)
|
|
|
|
for _, opt := range nodeOpts {
|
|
|
|
err := opt(params)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2021-10-15 02:15:02 +00:00
|
|
|
|
|
|
|
var libp2pOpts []config.Option
|
2021-11-17 16:19:42 +00:00
|
|
|
libp2pOpts = append(libp2pOpts,
|
|
|
|
params.Identity(),
|
|
|
|
libp2p.ListenAddrs(params.MultiAddresses()...),
|
|
|
|
)
|
2021-10-15 02:15:02 +00:00
|
|
|
|
2021-11-17 16:19:42 +00:00
|
|
|
addrFactory := params.AddressFactory()
|
|
|
|
if addrFactory != nil {
|
|
|
|
libp2pOpts = append(libp2pOpts, libp2p.AddrsFactory(addrFactory))
|
2021-10-15 02:15:02 +00:00
|
|
|
}
|
|
|
|
|
2022-03-22 13:12:58 +00:00
|
|
|
h, err := libp2p.New(libp2pOpts...)
|
2021-10-14 18:17:01 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
hostInfo, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", h.ID().Pretty()))
|
2021-10-15 02:15:02 +00:00
|
|
|
|
2021-10-14 18:17:01 +00:00
|
|
|
for _, addr := range h.Addrs() {
|
|
|
|
fmt.Println(addr.Encapsulate(hostInfo))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|