go-waku/cmd/waku/node.go

646 lines
19 KiB
Go
Raw Normal View History

2023-07-06 21:40:57 +00:00
package main
import (
"context"
"crypto/ecdsa"
2021-04-19 00:03:16 +00:00
"database/sql"
2022-07-25 12:24:42 +00:00
"encoding/json"
2023-05-08 15:19:44 +00:00
"errors"
"fmt"
"net"
"os"
"os/signal"
"sync"
"syscall"
"time"
2023-05-24 15:34:35 +00:00
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
"github.com/pbnjay/memory"
"github.com/waku-org/go-waku/waku/persistence/sqlite"
2023-07-06 21:40:57 +00:00
dbutils "github.com/waku-org/go-waku/waku/persistence/utils"
2022-11-25 21:24:34 +00:00
wmetrics "github.com/waku-org/go-waku/waku/v2/metrics"
"github.com/waku-org/go-waku/waku/v2/peers"
2023-03-09 15:48:25 +00:00
"github.com/waku-org/go-waku/waku/v2/rendezvous"
2022-11-25 21:24:34 +00:00
2022-07-25 12:24:42 +00:00
"github.com/ethereum/go-ethereum/accounts/keystore"
2021-03-23 14:46:16 +00:00
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p/enode"
dssql "github.com/ipfs/go-ds-sql"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"github.com/libp2p/go-libp2p"
2021-10-15 02:15:02 +00:00
"github.com/libp2p/go-libp2p/config"
2022-10-19 19:39:32 +00:00
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
2023-02-16 16:17:52 +00:00
"github.com/libp2p/go-libp2p/core/protocol"
2022-08-25 20:36:04 +00:00
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
pubsub "github.com/libp2p/go-libp2p-pubsub"
2022-10-19 19:39:32 +00:00
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds"
2022-08-25 20:36:04 +00:00
ws "github.com/libp2p/go-libp2p/p2p/transport/websocket"
2021-04-22 13:07:22 +00:00
"github.com/multiformats/go-multiaddr"
"github.com/waku-org/go-waku/cmd/waku/rest"
"github.com/waku-org/go-waku/cmd/waku/rpc"
"github.com/waku-org/go-waku/logging"
"github.com/waku-org/go-waku/waku/metrics"
"github.com/waku-org/go-waku/waku/persistence"
"github.com/waku-org/go-waku/waku/v2/dnsdisc"
"github.com/waku-org/go-waku/waku/v2/node"
"github.com/waku-org/go-waku/waku/v2/protocol/filter"
"github.com/waku-org/go-waku/waku/v2/protocol/legacy_filter"
"github.com/waku-org/go-waku/waku/v2/protocol/lightpush"
"github.com/waku-org/go-waku/waku/v2/protocol/peer_exchange"
"github.com/waku-org/go-waku/waku/v2/protocol/relay"
"github.com/waku-org/go-waku/waku/v2/protocol/store"
"github.com/waku-org/go-waku/waku/v2/utils"
)
func failOnErr(err error, msg string) {
if err != nil {
utils.Logger().Fatal(msg, zap.Error(err))
}
}
2023-03-09 15:48:25 +00:00
func requiresDB(options Options) bool {
2023-07-27 17:04:08 +00:00
return options.Store.Enable || options.Rendezvous.Enable
2023-03-09 15:48:25 +00:00
}
2023-05-24 15:34:35 +00:00
func scalePerc(value float64) float64 {
if value > 100 {
return 100
}
if value < 0.1 {
return 0.1
}
return value
}
const dialTimeout = 7 * time.Second
2021-10-09 18:18:53 +00:00
// Execute starts a go-waku node with settings determined by the Options parameter
func Execute(options Options) {
if options.GenerateKey {
2022-07-25 12:24:42 +00:00
if err := writePrivateKeyToFile(options.KeyFile, []byte(options.KeyPasswd), 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")
prvKey, err := getPrivKey(options)
failOnErr(err, "nodekey error")
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))
var db *sql.DB
2023-01-04 17:58:14 +00:00
var migrationFn func(*sql.DB) error
2023-03-09 15:48:25 +00:00
if requiresDB(options) {
2023-07-06 21:40:57 +00:00
db, migrationFn, err = dbutils.ExtractDBAndMigration(options.Store.DatabaseURL)
2023-01-04 17:58:14 +00:00
failOnErr(err, "Could not connect to DB")
}
2021-04-22 13:07:22 +00:00
ctx := context.Background()
2021-04-19 00:03:16 +00:00
var metricsServer *metrics.Server
if options.Metrics.Enable {
metricsServer = metrics.NewMetricsServer(options.Metrics.Address, options.Metrics.Port, logger)
go metricsServer.Start()
wmetrics.RecordVersion(ctx, node.Version, node.GitCommit)
}
2021-04-19 00:03:16 +00:00
lvl, err := zapcore.ParseLevel(options.LogLevel)
if err != nil {
failOnErr(err, "log level error")
}
nodeOpts := []node.WakuNodeOption{
2022-05-27 13:25:06 +00:00
node.WithLogger(logger),
node.WithLogLevel(lvl),
node.WithPrivateKey(prvKey),
2021-11-17 16:19:42 +00:00
node.WithHostAddress(hostAddr),
node.WithKeepAlive(options.KeepAlive),
}
if len(options.AdvertiseAddresses) != 0 {
nodeOpts = append(nodeOpts, node.WithAdvertiseAddresses(options.AdvertiseAddresses...))
2022-03-22 00:48:46 +00:00
}
2023-05-08 15:19:44 +00:00
if options.ExtIP != "" {
ip := net.ParseIP(options.ExtIP)
if ip == nil {
failOnErr(errors.New("invalid IP address"), "could not set external IP address")
}
nodeOpts = append(nodeOpts, node.WithExternalIP(ip))
}
2023-07-06 21:40:57 +00:00
if options.DNS4DomainName != "" {
nodeOpts = append(nodeOpts, node.WithDns4Domain(options.DNS4DomainName))
2023-05-15 15:49:51 +00:00
}
2022-03-22 13:12:58 +00:00
libp2pOpts := node.DefaultLibP2POptions
2023-05-24 15:34:35 +00:00
memPerc := scalePerc(options.ResourceScalingMemoryPercent)
fdPerc := scalePerc(options.ResourceScalingFDPercent)
limits := rcmgr.DefaultLimits // Default memory limit: 1/8th of total memory, minimum 128MB, maximum 1GB
scaledLimits := limits.Scale(int64(float64(memory.TotalMemory())*memPerc/100), int(float64(getNumFDs())*fdPerc/100))
resourceManager, err := rcmgr.NewResourceManager(rcmgr.NewFixedLimiter(scaledLimits))
failOnErr(err, "setting resource limits")
libp2pOpts = append(libp2pOpts, libp2p.ResourceManager(resourceManager))
libp2p.SetDefaultServiceLimits(&limits)
if len(options.AdvertiseAddresses) == 0 {
2022-03-22 13:12:58 +00:00
libp2pOpts = append(libp2pOpts, libp2p.NATPortMap()) // Attempt to open ports using uPNP for NATed hosts.)
}
// Node can be a circuit relay server
if options.CircuitRelay {
libp2pOpts = append(libp2pOpts, libp2p.EnableRelayService())
}
2022-10-26 13:28:28 +00:00
if options.UserAgent != "" {
libp2pOpts = append(libp2pOpts, libp2p.UserAgent(options.UserAgent))
}
2022-03-22 13:12:58 +00:00
if options.Websocket.Enable {
2022-08-25 20:36:04 +00:00
nodeOpts = append(nodeOpts, node.WithWebsockets(options.Websocket.Address, options.Websocket.WSPort))
2022-03-22 13:12:58 +00:00
}
if options.Websocket.Secure {
2022-08-25 20:36:04 +00:00
nodeOpts = append(nodeOpts, node.WithSecureWebsockets(options.Websocket.Address, options.Websocket.WSSPort, options.Websocket.CertPath, options.Websocket.KeyPath))
}
2021-04-19 00:03:16 +00:00
if options.ShowAddresses {
2021-10-15 02:15:02 +00:00
printListeningAddresses(ctx, nodeOpts, options)
return
}
2022-11-25 20:54:11 +00:00
if options.Store.Enable && options.PersistPeers {
// Create persistent peerstore
queries, err := sqlite.NewQueries("peerstore", db)
failOnErr(err, "Peerstore")
2022-11-25 20:54:11 +00:00
datastore := dssql.NewDatastore(db, queries)
opts := pstoreds.DefaultOpts()
peerStore, err := pstoreds.NewPeerstore(ctx, datastore, opts)
failOnErr(err, "Peerstore")
nodeOpts = append(nodeOpts, node.WithPeerStore(peerStore))
}
nodeOpts = append(nodeOpts, node.WithLibP2POptions(libp2pOpts...))
2022-12-09 03:08:04 +00:00
nodeOpts = append(nodeOpts, node.WithNTP())
2021-10-01 17:49:50 +00:00
if options.Relay.Enable {
var wakurelayopts []pubsub.Option
wakurelayopts = append(wakurelayopts, pubsub.WithPeerExchange(options.Relay.PeerExchange))
nodeOpts = append(nodeOpts, node.WithWakuRelayAndMinPeers(options.Relay.MinRelayPeersToPublish, wakurelayopts...))
}
2021-06-10 12:59:51 +00:00
2023-04-13 19:28:46 +00:00
nodeOpts = append(nodeOpts, node.WithWakuFilterLightNode())
if options.Filter.Enable {
2023-04-13 19:28:46 +00:00
nodeOpts = append(nodeOpts, node.WithWakuFilterFullNode(filter.WithTimeout(options.Filter.Timeout)))
}
if options.Filter.UseV1 {
nodeOpts = append(nodeOpts, node.WithLegacyWakuFilter(!options.Filter.DisableFullNode, legacy_filter.WithTimeout(options.Filter.Timeout)))
}
2021-06-28 14:14:28 +00:00
2023-03-09 15:48:25 +00:00
var dbStore *persistence.DBStore
if requiresDB(options) {
dbStore, err = persistence.NewDBStore(logger,
2023-01-04 17:58:14 +00:00
persistence.WithDB(db),
2023-03-09 15:48:25 +00:00
persistence.WithMigrations(migrationFn), // TODO: refactor migrations out of DBStore, or merge DBStore with rendezvous DB
2023-01-04 17:58:14 +00:00
persistence.WithRetentionPolicy(options.Store.RetentionMaxMessages, options.Store.RetentionTime),
)
failOnErr(err, "DBStore")
nodeOpts = append(nodeOpts, node.WithMessageProvider(dbStore))
}
2023-03-09 15:48:25 +00:00
if options.Store.Enable {
2023-07-15 16:09:00 +00:00
nodeOpts = append(nodeOpts, node.WithWakuStore())
2023-03-09 15:48:25 +00:00
nodeOpts = append(nodeOpts, node.WithMessageProvider(dbStore))
}
if options.LightPush.Enable {
nodeOpts = append(nodeOpts, node.WithLightPush())
}
2021-04-12 17:59:41 +00:00
2022-05-05 19:17:35 +00:00
var discoveredNodes []dnsdisc.DiscoveredNode
if options.DNSDiscovery.Enable {
if len(options.DNSDiscovery.URLs.Value()) != 0 {
for _, url := range options.DNSDiscovery.URLs.Value() {
logger.Info("attempting DNS discovery with ", zap.String("URL", url))
nodes, err := dnsdisc.RetrieveNodes(ctx, url, dnsdisc.WithNameserver(options.DNSDiscovery.Nameserver))
if err != nil {
logger.Warn("dns discovery error ", zap.Error(err))
} else {
var discPeerInfo []peer.AddrInfo
for _, n := range nodes {
discPeerInfo = append(discPeerInfo, n.PeerInfo)
}
logger.Info("found dns entries ", zap.Any("nodes", discPeerInfo))
discoveredNodes = append(discoveredNodes, nodes...)
}
2022-05-05 19:17:35 +00:00
}
} 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
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)
}
}
nodeOpts = append(nodeOpts, node.WithDiscoveryV5(options.DiscV5.Port, bootnodes, options.DiscV5.AutoUpdate))
2021-11-17 16:19:42 +00:00
}
2022-10-23 13:13:43 +00:00
if options.PeerExchange.Enable {
nodeOpts = append(nodeOpts, node.WithPeerExchange())
}
2023-03-09 15:48:25 +00:00
if options.Rendezvous.Enable {
rdb := rendezvous.NewDB(ctx, db, logger)
2023-07-27 17:04:08 +00:00
nodeOpts = append(nodeOpts, node.WithRendezvous(rdb))
2023-03-09 15:48:25 +00:00
}
2022-09-11 21:08:58 +00:00
checkForRLN(logger, options, &nodeOpts)
2022-07-05 21:28:34 +00:00
2023-01-06 22:37:57 +00:00
wakuNode, err := node.New(nodeOpts...)
2021-04-15 21:23:07 +00:00
utils.Logger().Info("Version details ", zap.String("version", node.Version), zap.String("commit", node.GitCommit))
failOnErr(err, "Wakunode")
2023-04-13 19:28:46 +00:00
if options.Filter.UseV1 {
addStaticPeers(wakuNode, options.Filter.NodesV1, legacy_filter.FilterID_v20beta1)
}
2021-10-05 02:13:54 +00:00
2023-01-06 22:37:57 +00:00
if err = wakuNode.Start(ctx); 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
for _, d := range discoveredNodes {
wakuNode.Host().Peerstore().AddAddrs(d.PeerID, d.PeerInfo.Addrs, peerstore.PermanentAddrTTL)
}
addStaticPeers(wakuNode, options.Store.Nodes, store.StoreID_v20beta4)
addStaticPeers(wakuNode, options.LightPush.Nodes, lightpush.LightPushID_v20beta1)
addStaticPeers(wakuNode, options.Rendezvous.Nodes, rendezvous.RendezvousID)
addStaticPeers(wakuNode, options.Filter.Nodes, filter.FilterSubscribeID_v20beta1)
2023-06-01 12:26:03 +00:00
if len(options.Relay.Topics.Value()) == 0 {
options.Relay.Topics = *cli.NewStringSlice(relay.DefaultWakuTopic)
}
2023-07-27 17:04:08 +00:00
var wg sync.WaitGroup
if options.Relay.Enable {
for _, nodeTopic := range options.Relay.Topics.Value() {
nodeTopic := nodeTopic
sub, err := wakuNode.Relay().SubscribeToTopic(ctx, nodeTopic)
failOnErr(err, "Error subscring to topic")
2023-05-05 09:49:15 +00:00
sub.Unsubscribe()
2023-06-23 15:50:32 +00:00
2023-07-27 17:04:08 +00:00
if len(options.Rendezvous.Nodes) != 0 {
2023-06-23 15:50:32 +00:00
// Register the node in rendezvous point
2023-07-27 17:04:08 +00:00
var rp []peer.ID
for _, n := range options.Rendezvous.Nodes {
peerID, err := utils.GetPeerID(n)
if err != nil {
failOnErr(err, "registering rendezvous nodes")
}
rp = append(rp, peerID)
}
iter := rendezvous.NewRendezvousPointIterator(rp)
wg.Add(1)
go func(nodeTopic string) {
t := time.NewTicker(rendezvous.RegisterDefaultTTL)
defer t.Stop()
defer wg.Done()
for {
select {
case <-ctx.Done():
return
case <-t.C:
// Register in rendezvous points periodically
wakuNode.Rendezvous().RegisterWithTopic(ctx, nodeTopic, iter.RendezvousPoints())
}
}
}(nodeTopic)
2023-06-23 15:50:32 +00:00
2023-07-27 17:04:08 +00:00
wg.Add(1)
2023-06-23 15:50:32 +00:00
go func(nodeTopic string) {
2023-07-27 17:04:08 +00:00
defer wg.Done()
2023-06-23 15:50:32 +00:00
desiredOutDegree := wakuNode.Relay().Params().D
t := time.NewTicker(7 * time.Second)
defer t.Stop()
for {
select {
case <-ctx.Done():
return
case <-t.C:
peerCnt := len(wakuNode.Relay().PubSub().ListPeers(nodeTopic))
peersToFind := desiredOutDegree - peerCnt
if peersToFind <= 0 {
continue
}
2023-07-27 17:04:08 +00:00
rp := <-iter.Next(ctx)
if rp == nil {
continue
}
2023-06-23 15:50:32 +00:00
ctx, cancel := context.WithTimeout(ctx, 7*time.Second)
2023-07-27 17:04:08 +00:00
wakuNode.Rendezvous().DiscoverWithTopic(ctx, nodeTopic, rp, peersToFind)
2023-06-23 15:50:32 +00:00
cancel()
}
}
}(nodeTopic)
}
}
for _, protectedTopic := range options.Relay.ProtectedTopics {
err := wakuNode.Relay().AddSignedTopicValidator(protectedTopic.Topic, protectedTopic.PublicKey)
failOnErr(err, "Error adding signed topic validator")
}
}
for _, n := range options.StaticNodes {
go func(ctx context.Context, node multiaddr.Multiaddr) {
ctx, cancel := context.WithTimeout(ctx, dialTimeout)
defer cancel()
err = wakuNode.DialPeerWithMultiAddress(ctx, node)
if err != nil {
2022-05-27 13:25:06 +00:00
logger.Error("dialing peer", zap.Error(err))
}
}(ctx, n)
}
if options.DiscV5.Enable {
if err = wakuNode.DiscV5().Start(ctx); err != nil {
logger.Fatal("starting discovery v5", zap.Error(err))
}
}
// retrieve and connect to peer exchange peers
if options.PeerExchange.Enable && options.PeerExchange.Node != nil {
logger.Info("retrieving peer info via peer exchange protocol")
2023-07-06 21:40:57 +00:00
peerID, err := wakuNode.AddPeer(*options.PeerExchange.Node, peers.Static, peer_exchange.PeerExchangeID_v20alpha1)
if err != nil {
logger.Error("adding peer exchange peer", logging.MultiAddrs("node", *options.PeerExchange.Node), zap.Error(err))
} else {
desiredOutDegree := wakuNode.Relay().Params().D
2023-07-06 21:40:57 +00:00
if err = wakuNode.PeerExchange().Request(ctx, desiredOutDegree, peer_exchange.WithPeer(peerID)); err != nil {
logger.Error("requesting peers via peer exchange", zap.Error(err))
}
}
}
2022-05-05 19:17:35 +00:00
if len(discoveredNodes) != 0 {
for _, n := range discoveredNodes {
go func(ctx context.Context, info peer.AddrInfo) {
ctx, cancel := context.WithTimeout(ctx, dialTimeout)
defer cancel()
err = wakuNode.DialPeerWithInfo(ctx, info)
if err != nil {
logger.Error("dialing peer", logging.HostID("peer", info.ID), zap.Error(err))
}
}(ctx, n.PeerInfo)
}
}
if options.Store.Enable && len(options.Store.ResumeNodes) != 0 {
// TODO: extract this to a function and run it when you go offline
// TODO: determine if a store is listening to a topic
var peerIDs []peer.ID
for _, n := range options.Store.ResumeNodes {
pID, err := wakuNode.AddPeer(n, peers.Static, store.StoreID_v20beta4)
if err != nil {
logger.Warn("adding peer to peerstore", logging.MultiAddrs("peer", n), zap.Error(err))
}
peerIDs = append(peerIDs, pID)
}
for _, t := range options.Relay.Topics.Value() {
wg.Add(1)
go func(topic string) {
defer wg.Done()
ctxWithTimeout, ctxCancel := context.WithTimeout(ctx, 20*time.Second)
defer ctxCancel()
if _, err := wakuNode.Store().Resume(ctxWithTimeout, topic, peerIDs); err != nil {
logger.Error("Could not resume history", zap.Error(err))
}
}(t)
}
}
var rpcServer *rpc.WakuRpc
if options.RPCServer.Enable {
rpcServer = rpc.NewWakuRpc(wakuNode, options.RPCServer.Address, options.RPCServer.Port, options.RPCServer.Admin, options.RPCServer.Private, options.PProf, options.RPCServer.RelayCacheCapacity, logger)
rpcServer.Start()
}
var restServer *rest.WakuRest
if options.RESTServer.Enable {
wg.Add(1)
restServer = rest.NewWakuRest(wakuNode, options.RESTServer.Address, options.RESTServer.Port, options.RESTServer.Admin, options.RESTServer.Private, options.PProf, options.RESTServer.RelayCacheCapacity, logger)
restServer.Start(ctx, &wg)
}
wg.Wait()
logger.Info("Node setup complete")
// 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
// shut the node down
wakuNode.Stop()
if options.RPCServer.Enable {
err := rpcServer.Stop(ctx)
failOnErr(err, "RPCClose")
}
if options.RESTServer.Enable {
err := restServer.Stop(ctx)
failOnErr(err, "RESTClose")
}
if options.Metrics.Enable {
2021-10-18 12:43:17 +00:00
err = metricsServer.Stop(ctx)
failOnErr(err, "MetricsClose")
}
2022-11-25 20:54:11 +00:00
if options.Store.Enable {
err = db.Close()
failOnErr(err, "DBClose")
}
}
func addStaticPeers(wakuNode *node.WakuNode, addresses []multiaddr.Multiaddr, protocols ...protocol.ID) {
for _, addr := range addresses {
_, err := wakuNode.AddPeer(addr, peers.Static, protocols...)
failOnErr(err, "error adding peer")
}
}
2022-07-25 12:24:42 +00:00
func loadPrivateKeyFromFile(path string, passwd string) (*ecdsa.PrivateKey, error) {
2023-02-16 16:17:52 +00:00
src, err := os.ReadFile(path)
if err != nil {
return nil, err
}
2022-07-25 12:24:42 +00:00
var encryptedK keystore.CryptoJSON
err = json.Unmarshal(src, &encryptedK)
if err != nil {
return nil, err
}
2022-07-25 12:24:42 +00:00
pKey, err := keystore.DecryptDataV3(encryptedK, passwd)
2022-05-27 19:55:35 +00:00
if err != nil {
return nil, err
}
2022-07-25 12:24:42 +00:00
return crypto.ToECDSA(pKey)
}
2022-08-09 00:02:08 +00:00
func checkForFileExistence(path string, overwrite bool) error {
_, err := os.Stat(path)
2021-12-08 14:21:30 +00:00
if err == nil && !overwrite {
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) {
key, err := crypto.GenerateKey()
if err != nil {
2021-12-08 14:21:30 +00:00
return nil, err
}
2022-07-25 12:24:42 +00:00
return key.D.Bytes(), nil
2021-12-08 14:21:30 +00:00
}
2022-07-25 12:24:42 +00:00
func writePrivateKeyToFile(path string, passwd []byte, overwrite bool) error {
2022-08-09 00:02:08 +00:00
if err := checkForFileExistence(path, overwrite); err != nil {
2021-12-08 14:21:30 +00:00
return err
}
2022-07-25 12:24:42 +00:00
key, err := generatePrivateKey()
if err != nil {
return err
}
encryptedK, err := keystore.EncryptDataV3(key, passwd, keystore.StandardScryptN, keystore.StandardScryptP)
if err != nil {
return err
}
output, err := json.Marshal(encryptedK)
2021-12-08 14:21:30 +00:00
if err != nil {
return err
}
2023-02-16 16:17:52 +00:00
return os.WriteFile(path, output, 0600)
}
func getPrivKey(options Options) (*ecdsa.PrivateKey, error) {
var prvKey *ecdsa.PrivateKey
// get private key from nodeKey or keyFile
if options.NodeKey != nil {
prvKey = options.NodeKey
} else {
if _, err := os.Stat(options.KeyFile); err == nil {
if prvKey, err = loadPrivateKeyFromFile(options.KeyFile, options.KeyPasswd); err != nil {
return nil, fmt.Errorf("could not read keyfile: %w", err)
}
} else {
if os.IsNotExist(err) {
if prvKey, err = crypto.GenerateKey(); err != nil {
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-15 02:15:02 +00:00
func printListeningAddresses(ctx context.Context, nodeOpts []node.WakuNodeOption, options Options) {
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
2022-08-25 20:36:04 +00:00
if options.Websocket.Secure {
transports := libp2p.ChainOptions(
libp2p.Transport(tcp.NewTCPTransport),
libp2p.Transport(ws.New, ws.WithTLSConfig(params.TLSConfig())),
)
libp2pOpts = append(libp2pOpts, transports)
}
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...)
if err != nil {
panic(err)
}
2023-07-07 15:51:15 +00:00
hostAddrs := utils.EncapsulatePeerID(h.ID(), h.Addrs()...)
for _, addr := range hostAddrs {
fmt.Println(addr)
}
}