parent
83763e0401
commit
5a5c5d3a5c
3
Makefile
3
Makefile
|
@ -47,9 +47,6 @@ statusgo: ##@build Build status-go as statusd server
|
|||
go build -i -o $(GOBIN)/statusd -v $(shell build/testnet-flags.sh) ./cmd/statusd
|
||||
@echo "\nCompilation done.\nRun \"build/bin/statusd -h\" to view available commands."
|
||||
|
||||
wnode-status: ##@build Build wnode-status (Whisper 5 debug tool)
|
||||
go build -i -o $(GOBIN)/wnode-status -v $(shell build/testnet-flags.sh) ./cmd/wnode-status
|
||||
|
||||
statusgo-cross: statusgo-android statusgo-ios
|
||||
@echo "Full cross compilation done."
|
||||
@ls -ld $(GOBIN)/statusgo-*
|
||||
|
|
|
@ -33,6 +33,23 @@ var (
|
|||
logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`)
|
||||
logFile = flag.String("logfile", "", "Path to the log file")
|
||||
version = flag.Bool("version", false, "Print version")
|
||||
les = flag.Bool("les", false, "LES protocol")
|
||||
|
||||
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")
|
||||
|
||||
// shh stuff
|
||||
identityFile = flag.String("shh.identityfile", "", "Protocol identity file (private key used for asymmetric encryption)")
|
||||
passwordFile = flag.String("shh.passwordfile", "", "Password file (password is used for symmetric encryption)")
|
||||
minPow = flag.Float64("shh.pow", params.WhisperMinimumPoW, "PoW for messages to be added to queue, in float format")
|
||||
ttl = flag.Int("shh.ttl", params.WhisperTTL, "Time to live for messages, in seconds")
|
||||
|
||||
// MailServer
|
||||
enableMailServer = flag.Bool("shh.mailserver", false, "Delivers expired messages on demand")
|
||||
|
||||
// Push Notification
|
||||
enablePN = flag.Bool("shh.notify", false, "Node is capable of sending Push Notifications")
|
||||
firebaseAuth = flag.String("shh.firebaseauth", "", "FCM Authorization Key used for sending Push Notifications")
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -106,17 +123,23 @@ func makeNodeConfig() (*params.NodeConfig, error) {
|
|||
nodeConfig.LogFile = *logFile
|
||||
}
|
||||
|
||||
nodeConfig.LightEthConfig.Enabled = true
|
||||
nodeConfig.RPCEnabled = *httpEnabled
|
||||
nodeConfig.WhisperConfig.Enabled = *whisperEnabled
|
||||
|
||||
nodeConfig.HTTPPort = *httpPort
|
||||
nodeConfig.IPCEnabled = *ipcEnabled
|
||||
|
||||
nodeConfig.LightEthConfig.Enabled = *les
|
||||
nodeConfig.SwarmConfig.Enabled = *swarmEnabled
|
||||
|
||||
if *whisperEnabled {
|
||||
return whisperConfig(nodeConfig)
|
||||
}
|
||||
|
||||
// RPC configuration
|
||||
if !*httpEnabled {
|
||||
nodeConfig.HTTPHost = "" // HTTP RPC is disabled
|
||||
}
|
||||
nodeConfig.HTTPPort = *httpPort
|
||||
nodeConfig.IPCEnabled = *ipcEnabled
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
// makeNodeConfig creates node configuration object from flags
|
||||
func whisperConfig(nodeConfig *params.NodeConfig) (*params.NodeConfig, error) {
|
||||
|
||||
nodeConfig.ListenAddr = *listenAddr
|
||||
|
||||
nodeConfig.LogLevel = *logLevel
|
||||
|
||||
// whisper configuration
|
||||
whisperConfig := nodeConfig.WhisperConfig
|
||||
whisperConfig.Enabled = true
|
||||
whisperConfig.IdentityFile = *identityFile
|
||||
whisperConfig.EnablePushNotification = *enablePN
|
||||
whisperConfig.EnableMailServer = *enableMailServer
|
||||
whisperConfig.MinimumPoW = *minPow
|
||||
whisperConfig.TTL = *ttl
|
||||
|
||||
if whisperConfig.EnablePushNotification && whisperConfig.IdentityFile == "" {
|
||||
return nil, errors.New("notification server requires -identity file to be specified")
|
||||
}
|
||||
|
||||
if whisperConfig.IdentityFile != "" {
|
||||
if _, err := whisperConfig.ReadIdentityFile(); err != nil {
|
||||
return nil, fmt.Errorf("read identity file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if whisperConfig.EnableMailServer {
|
||||
if *passwordFile == "" {
|
||||
return nil, errors.New("passwordfile should be specified if MailServer is enabled")
|
||||
}
|
||||
|
||||
password, err := readFile(*passwordFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("password file: %v", err)
|
||||
}
|
||||
|
||||
whisperConfig.Password = string(password)
|
||||
}
|
||||
|
||||
// firebase configuration
|
||||
firebaseConfig := whisperConfig.FirebaseConfig
|
||||
firebaseConfig.AuthorizationKeyFile = *firebaseAuth
|
||||
if firebaseConfig.AuthorizationKeyFile != "" {
|
||||
if _, err := firebaseConfig.ReadAuthorizationKeyFile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// RPC configuration
|
||||
// TODO(adam): clarify all these IPC/RPC/HTTPHost
|
||||
if !*httpEnabled {
|
||||
nodeConfig.HTTPHost = "" // HTTP RPC is disabled
|
||||
}
|
||||
nodeConfig.HTTPHost = "0.0.0.0"
|
||||
|
||||
if *standalone {
|
||||
nodeConfig.BootClusterConfig.Enabled = false
|
||||
nodeConfig.BootClusterConfig.BootNodes = nil
|
||||
}
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
func readFile(path string) ([]byte, error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = bytes.TrimRight(data, "\n")
|
||||
|
||||
if len(data) == 0 {
|
||||
return nil, errors.New("file is empty")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
var (
|
||||
prodMode = flag.Bool("production", false, "Whether production settings should be loaded")
|
||||
dataDir = flag.String("datadir", "wnode-data", "Data directory for the databases and keystore")
|
||||
networkID = flag.Int("networkid", params.RopstenNetworkID, "Network identifier (integer, 1=Homestead, 3=Ropsten, 4=Rinkeby)")
|
||||
listenAddr = flag.String("listenaddr", ":30303", "IP address and port of this node (e.g. 127.0.0.1:30303)")
|
||||
httpEnabled = flag.Bool("http", false, "HTTP RPC enpoint enabled (default: false)")
|
||||
httpPort = flag.Int("httpport", params.HTTPPort, "HTTP RPC server's listening port")
|
||||
ipcEnabled = flag.Bool("ipc", false, "IPC RPC endpoint enabled")
|
||||
logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`)
|
||||
logFile = flag.String("logfile", "", "Path to the log file")
|
||||
|
||||
// Whisper
|
||||
identity = flag.String("identity", "", "Protocol identity file (private key used for asymmetric encryption)")
|
||||
passwordFile = flag.String("passwordfile", "", "Password file (password is used for symmetric encryption)")
|
||||
standalone = flag.Bool("standalone", true, "Don't actively connect to peers, wait for incoming connections")
|
||||
minPow = flag.Float64("pow", params.WhisperMinimumPoW, "PoW for messages to be added to queue, in float format")
|
||||
ttl = flag.Int("ttl", params.WhisperTTL, "Time to live for messages, in seconds")
|
||||
|
||||
// MailServer
|
||||
enableMailServer = flag.Bool("mailserver", false, "Delivers expired messages on demand")
|
||||
|
||||
// Push Notification
|
||||
enablePN = flag.Bool("notify", false, "Node is capable of sending Push Notifications")
|
||||
firebaseAuth = flag.String("firebaseauth", "", "FCM Authorization Key used for sending Push Notifications")
|
||||
|
||||
// Tesing and debug
|
||||
injectAccounts = flag.Bool("injectaccounts", false, "Whether test account should be injected or not")
|
||||
)
|
||||
|
||||
// makeNodeConfig creates node configuration object from flags
|
||||
func makeNodeConfig() (*params.NodeConfig, error) {
|
||||
devMode := !*prodMode
|
||||
nodeConfig, err := params.NewNodeConfig(*dataDir, uint64(*networkID), devMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeConfig.ListenAddr = *listenAddr
|
||||
|
||||
nodeConfig.LogLevel = *logLevel
|
||||
if filepath.IsAbs(*logFile) {
|
||||
nodeConfig.LogFile = *logFile
|
||||
} else if *logFile != "" {
|
||||
nodeConfig.LogFile = filepath.Join(*dataDir, *logFile)
|
||||
}
|
||||
|
||||
// disable les and swarm for wnode
|
||||
nodeConfig.LightEthConfig.Enabled = false
|
||||
nodeConfig.SwarmConfig.Enabled = false
|
||||
|
||||
// whisper configuration
|
||||
whisperConfig := nodeConfig.WhisperConfig
|
||||
whisperConfig.Enabled = true
|
||||
whisperConfig.IdentityFile = *identity
|
||||
whisperConfig.EnablePushNotification = *enablePN
|
||||
whisperConfig.EnableMailServer = *enableMailServer
|
||||
whisperConfig.MinimumPoW = *minPow
|
||||
whisperConfig.TTL = *ttl
|
||||
|
||||
if whisperConfig.EnablePushNotification && whisperConfig.IdentityFile == "" {
|
||||
return nil, errors.New("notification server requires -identity file to be specified")
|
||||
}
|
||||
|
||||
if whisperConfig.IdentityFile != "" {
|
||||
if _, err := whisperConfig.ReadIdentityFile(); err != nil {
|
||||
return nil, fmt.Errorf("read identity file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if whisperConfig.EnableMailServer {
|
||||
if *passwordFile == "" {
|
||||
return nil, errors.New("passwordfile should be specified if MailServer is enabled")
|
||||
}
|
||||
|
||||
password, err := readFile(*passwordFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("password file: %v", err)
|
||||
}
|
||||
|
||||
whisperConfig.Password = string(password)
|
||||
}
|
||||
|
||||
// firebase configuration
|
||||
firebaseConfig := whisperConfig.FirebaseConfig
|
||||
firebaseConfig.AuthorizationKeyFile = *firebaseAuth
|
||||
if firebaseConfig.AuthorizationKeyFile != "" {
|
||||
if _, err := firebaseConfig.ReadAuthorizationKeyFile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// RPC configuration
|
||||
// TODO(adam): clarify all these IPC/RPC/HTTPHost
|
||||
if !*httpEnabled {
|
||||
nodeConfig.HTTPHost = "" // HTTP RPC is disabled
|
||||
}
|
||||
nodeConfig.HTTPHost = "0.0.0.0"
|
||||
nodeConfig.HTTPPort = *httpPort
|
||||
nodeConfig.IPCEnabled = *ipcEnabled
|
||||
nodeConfig.RPCEnabled = *httpEnabled
|
||||
|
||||
if *standalone {
|
||||
nodeConfig.BootClusterConfig.Enabled = false
|
||||
nodeConfig.BootClusterConfig.BootNodes = nil
|
||||
}
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
func readFile(path string) ([]byte, error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = bytes.TrimRight(data, "\n")
|
||||
|
||||
if len(data) == 0 {
|
||||
return nil, errors.New("file is empty")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/status-im/status-go/geth/api"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
config, err := makeNodeConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Making config failed: %v", err)
|
||||
}
|
||||
|
||||
printHeader(config)
|
||||
|
||||
if *injectAccounts {
|
||||
if err := LoadTestAccounts(config.DataDir); err != nil {
|
||||
log.Fatalf("Failed to load test accounts: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
backend := api.NewStatusBackend()
|
||||
started, err := backend.StartNode(config)
|
||||
if err != nil {
|
||||
log.Fatalf("Node start failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// wait till node is started
|
||||
<-started
|
||||
|
||||
if *injectAccounts {
|
||||
if err := InjectTestAccounts(backend.NodeManager()); err != nil {
|
||||
log.Fatalf("Failed to inject accounts: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// wait till node has been stopped
|
||||
node, err := backend.NodeManager().Node()
|
||||
if err != nil {
|
||||
log.Fatalf("Getting node failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
node.Wait()
|
||||
}
|
||||
|
||||
// printHeader prints command header
|
||||
func printHeader(config *params.NodeConfig) {
|
||||
fmt.Println("Starting Whisper V5 node...")
|
||||
fmt.Printf("Config: %s\n", config.WhisperConfig)
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/status-im/status-go/geth/account"
|
||||
"github.com/status-im/status-go/geth/common"
|
||||
)
|
||||
|
||||
// LoadTestAccounts loads public key files for test accounts
|
||||
func LoadTestAccounts(dataDir string) error {
|
||||
files := []string{"test-account1.pk", "test-account2.pk"}
|
||||
dir := filepath.Join(dataDir, "keystore")
|
||||
for _, filename := range files {
|
||||
if err := common.ImportTestAccount(dir, filename); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InjectTestAccounts injects test accounts into running node
|
||||
func InjectTestAccounts(node common.NodeManager) error {
|
||||
nodeConfig, err := node.NodeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
testConfig, err := common.LoadTestConfig(int(nodeConfig.NetworkID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = injectAccountIntoWhisper(node, testConfig.Account1.Address,
|
||||
testConfig.Account1.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = injectAccountIntoWhisper(node, testConfig.Account2.Address,
|
||||
testConfig.Account2.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// injectAccountIntoWhisper adds key pair into Whisper. Similar to Select/Login,
|
||||
// but allows multiple accounts to be injected.
|
||||
func injectAccountIntoWhisper(node common.NodeManager, address, password string) error {
|
||||
keyStore, err := node.AccountKeyStore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
acct, err := common.ParseAccountString(address)
|
||||
if err != nil {
|
||||
return account.ErrAddressToAccountMappingFailure
|
||||
}
|
||||
|
||||
_, accountKey, err := keyStore.AccountDecryptedKey(acct, password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %v", account.ErrAccountToKeyMappingFailure.Error(), err)
|
||||
}
|
||||
|
||||
whisperService, err := node.WhisperService()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = whisperService.AddKeyPair(accountKey.PrivateKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue