status-go/cmd/statusd/wnodecmd.go

182 lines
5.2 KiB
Go
Raw Normal View History

package main
import (
"errors"
"fmt"
"path/filepath"
"github.com/status-im/status-go/geth"
"github.com/status-im/status-go/geth/params"
"gopkg.in/urfave/cli.v1"
)
var (
WhisperEchoModeFlag = cli.BoolTFlag{
Name: "echo",
Usage: "Echo mode, prints some arguments for diagnostics (default: true)",
}
WhisperBootstrapNodeFlag = cli.BoolTFlag{
Name: "bootstrap",
Usage: "Don't actively connect to peers, wait for incoming connections (default: true)",
}
WhisperNotificationServerNodeFlag = cli.BoolFlag{
Name: "notify",
Usage: "Node is capable of sending Push Notifications",
}
WhisperForwarderNodeFlag = cli.BoolFlag{
Name: "forward",
Usage: "Only forward messages, neither send nor decrypt messages",
}
WhisperMailserverNodeFlag = cli.BoolFlag{
Name: "mailserver",
Usage: "Delivers expired messages on demand",
}
WhisperPassword = cli.StringFlag{
Name: "password",
Usage: "Password, will be used for topic keys, as Mail & Notification Server password",
}
WhisperPortFlag = cli.IntFlag{
Name: "port",
Usage: "Whisper node's listening port",
Value: params.WhisperPort,
}
WhisperPoWFlag = cli.Float64Flag{
Name: "pow",
Usage: "PoW for messages to be added to queue, in float format",
Value: params.WhisperMinimumPoW,
}
WhisperTTLFlag = cli.IntFlag{
Name: "ttl",
Usage: "Time to live for messages, in seconds",
Value: params.WhisperTTL,
}
WhisperInjectTestAccounts = cli.BoolTFlag{
Name: "injectaccounts",
Usage: "Whether test account should be injected or not (default: true)",
}
)
var (
wnodeCommand = cli.Command{
Action: wnode,
Name: "wnode",
Usage: "Starts Whisper/5 node",
Flags: []cli.Flag{
WhisperEchoModeFlag,
WhisperBootstrapNodeFlag,
WhisperNotificationServerNodeFlag,
WhisperForwarderNodeFlag,
WhisperMailserverNodeFlag,
WhisperPassword,
WhisperPoWFlag,
WhisperPortFlag,
WhisperTTLFlag,
WhisperInjectTestAccounts,
},
}
)
// version displays app version
func wnode(ctx *cli.Context) error {
config, err := makeWhisperNodeConfig(ctx)
if err != nil {
return fmt.Errorf("can not parse config: %v", err)
}
wnodePrintHeader(config)
// import test accounts
if ctx.BoolT(WhisperInjectTestAccounts.Name) {
geth.ImportTestAccount(filepath.Join(config.DataDir, "keystore"), "test-account1.pk")
geth.ImportTestAccount(filepath.Join(config.DataDir, "keystore"), "test-account2.pk")
}
if err := geth.CreateAndRunNode(config); err != nil {
return err
}
// inject test accounts into Whisper
if ctx.BoolT(WhisperInjectTestAccounts.Name) {
testConfig, _ := geth.LoadTestConfig()
injectAccountIntoWhisper(testConfig.Account1.Address, testConfig.Account1.Password)
injectAccountIntoWhisper(testConfig.Account2.Address, testConfig.Account2.Password)
}
// wait till node has been stopped
geth.NodeManagerInstance().Node().GethStack().Wait()
return nil
}
// wnodePrintHeader prints command header
func wnodePrintHeader(nodeConfig *params.NodeConfig) {
fmt.Println("Starting Whisper/5 node..")
whisperConfig := nodeConfig.WhisperConfig
if whisperConfig.EchoMode {
fmt.Printf("Whisper Config: %s\n", whisperConfig)
}
}
// makeWhisperNodeConfig parses incoming CLI options and returns node configuration object
func makeWhisperNodeConfig(ctx *cli.Context) (*params.NodeConfig, error) {
nodeConfig, err := makeNodeConfig(ctx)
if err != nil {
return nil, err
}
whisperConfig := nodeConfig.WhisperConfig
whisperConfig.Enabled = true
whisperConfig.EchoMode = ctx.BoolT(WhisperEchoModeFlag.Name)
whisperConfig.BootstrapNode = ctx.BoolT(WhisperBootstrapNodeFlag.Name)
whisperConfig.ForwarderNode = ctx.Bool(WhisperForwarderNodeFlag.Name)
whisperConfig.NotificationServerNode = ctx.Bool(WhisperNotificationServerNodeFlag.Name)
whisperConfig.MailServerNode = ctx.Bool(WhisperMailserverNodeFlag.Name)
whisperConfig.MailServerPassword = ctx.String(WhisperPassword.Name)
whisperConfig.NotificationServerPassword = ctx.String(WhisperPassword.Name) // the same for both mail and notification servers
whisperConfig.Port = ctx.Int(WhisperPortFlag.Name)
whisperConfig.TTL = ctx.Int(WhisperTTLFlag.Name)
whisperConfig.MinimumPoW = ctx.Float64(WhisperPoWFlag.Name)
if whisperConfig.MailServerNode && len(whisperConfig.MailServerPassword) == 0 {
return nil, errors.New("mail server requires --password to be specified")
}
if whisperConfig.NotificationServerNode && len(whisperConfig.NotificationServerPassword) == 0 {
return nil, errors.New("notification server requires --password to be specified")
}
return nodeConfig, nil
}
// injectAccountIntoWhisper adds key pair into Whisper. Similar to Select/Login,
// but allows multiple accounts to be injected.
func injectAccountIntoWhisper(address, password string) error {
nodeManager := geth.NodeManagerInstance()
keyStore, err := nodeManager.AccountKeyStore()
if err != nil {
return err
}
account, err := geth.ParseAccountString(address)
if err != nil {
return geth.ErrAddressToAccountMappingFailure
}
account, accountKey, err := keyStore.AccountDecryptedKey(account, password)
if err != nil {
return fmt.Errorf("%s: %v", geth.ErrAccountToKeyMappingFailure.Error(), err)
}
whisperService, err := nodeManager.WhisperService()
if err != nil {
return err
}
whisperService.AddKeyPair(accountKey.PrivateKey)
return nil
}