Prepare wnode-status to support MailServer (#477)

This commit is contained in:
Adam Babik 2017-12-04 17:11:14 +01:00 committed by GitHub
parent bddf15d74f
commit ac76e4731f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 229 additions and 359 deletions

View File

@ -2,12 +2,41 @@ package main
import ( import (
"errors" "errors"
"flag"
"fmt" "fmt"
"path/filepath" "path/filepath"
"github.com/status-im/status-go/geth/params" "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", params.ListenAddr, "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)")
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 // makeNodeConfig creates node configuration object from flags
func makeNodeConfig() (*params.NodeConfig, error) { func makeNodeConfig() (*params.NodeConfig, error) {
devMode := !*prodMode devMode := !*prodMode
@ -16,52 +45,45 @@ func makeNodeConfig() (*params.NodeConfig, error) {
return nil, err return nil, err
} }
// TODO(divan): move this logic into params package? nodeConfig.ListenAddr = *listenAddr
if *nodeKeyFile != "" {
nodeConfig.NodeKeyFile = *nodeKeyFile
}
// disable log nodeConfig.LogLevel = *logLevel
nodeConfig.LogLevel = "CRIT" if filepath.IsAbs(*logFile) {
nodeConfig.LogFile = "" nodeConfig.LogFile = *logFile
} else if *logFile != "" {
nodeConfig.LogFile = filepath.Join(*dataDir, *logFile)
}
// disable les and swarm for wnode // disable les and swarm for wnode
nodeConfig.LightEthConfig.Enabled = false nodeConfig.LightEthConfig.Enabled = false
nodeConfig.SwarmConfig.Enabled = false nodeConfig.SwarmConfig.Enabled = false
nodeConfig.RPCEnabled = *httpEnabled
// whisper configuration // whisper configuration
whisperConfig := nodeConfig.WhisperConfig whisperConfig := nodeConfig.WhisperConfig
whisperConfig.Enabled = true whisperConfig.Enabled = true
whisperConfig.IdentityFile = *identity whisperConfig.IdentityFile = *identity
whisperConfig.PasswordFile = *password whisperConfig.PasswordFile = *passwordFile
whisperConfig.EchoMode = *echo whisperConfig.EnablePushNotification = *enablePN
whisperConfig.BootstrapNode = *bootstrap whisperConfig.EnableMailServer = *enableMailServer
whisperConfig.ForwarderNode = *forward whisperConfig.MinimumPoW = *minPow
whisperConfig.NotificationServerNode = *notify
whisperConfig.MailServerNode = *mailserver
whisperConfig.Port = *port
whisperConfig.TTL = *ttl whisperConfig.TTL = *ttl
whisperConfig.MinimumPoW = *pow
if whisperConfig.MailServerNode && whisperConfig.PasswordFile == "" { if whisperConfig.EnableMailServer && whisperConfig.PasswordFile == "" {
return nil, errors.New("mail server requires -password to be specified") return nil, errors.New("mail server requires -password to be specified")
} }
if whisperConfig.NotificationServerNode && whisperConfig.IdentityFile == "" { if whisperConfig.EnablePushNotification && whisperConfig.IdentityFile == "" {
return nil, errors.New("notification server requires either -identity file to be specified") return nil, errors.New("notification server requires -identity file to be specified")
} }
if whisperConfig.PasswordFile != "" { if whisperConfig.PasswordFile != "" {
if err := verifyPasswordFile(whisperConfig); err != nil { if _, err := whisperConfig.ReadPasswordFile(); err != nil {
return nil, fmt.Errorf("read password file: %v", err) return nil, fmt.Errorf("read password file: %v", err)
} }
} }
if whisperConfig.IdentityFile != "" { if whisperConfig.IdentityFile != "" {
if err := verifyIdentityFile(whisperConfig); err != nil { if _, err := whisperConfig.ReadIdentityFile(); err != nil {
return nil, fmt.Errorf("read identity file: %v", err) return nil, fmt.Errorf("read identity file: %v", err)
} }
} }
@ -69,45 +91,20 @@ func makeNodeConfig() (*params.NodeConfig, error) {
// firebase configuration // firebase configuration
firebaseConfig := whisperConfig.FirebaseConfig firebaseConfig := whisperConfig.FirebaseConfig
firebaseConfig.AuthorizationKeyFile = *firebaseAuth firebaseConfig.AuthorizationKeyFile = *firebaseAuth
if len(firebaseConfig.AuthorizationKeyFile) > 0 { // make sure authorization key can be loaded if firebaseConfig.AuthorizationKeyFile != "" {
if firebaseConfig.AuthorizationKeyFile, err = filepath.Abs(firebaseConfig.AuthorizationKeyFile); err != nil {
return nil, err
}
if _, err := firebaseConfig.ReadAuthorizationKeyFile(); err != nil { if _, err := firebaseConfig.ReadAuthorizationKeyFile(); err != nil {
return nil, err return nil, err
} }
} }
// RPC configuration // RPC configuration
// TODO(adam): clarify all these IPC/RPC/HTTPHost
if !*httpEnabled { if !*httpEnabled {
nodeConfig.HTTPHost = "" // HTTP RPC is disabled nodeConfig.HTTPHost = "" // HTTP RPC is disabled
} }
nodeConfig.HTTPPort = *httpPort nodeConfig.HTTPPort = *httpPort
nodeConfig.IPCEnabled = *ipcEnabled nodeConfig.IPCEnabled = *ipcEnabled
nodeConfig.RPCEnabled = *httpEnabled
return nodeConfig, nil return nodeConfig, nil
} }
// verifyPasswordFile verifies that we can load password file
func verifyPasswordFile(config *params.WhisperConfig) error {
// TODO(divan): why do we need it here?
absPath, err := filepath.Abs(config.PasswordFile)
if err != nil {
return err
}
config.PasswordFile = absPath
_, err = config.ReadPasswordFile()
return err
}
// verifyIdentityFile verifies that we can load identity file
func verifyIdentityFile(config *params.WhisperConfig) error {
// TODO(divan): why do we need it here?
absPath, err := filepath.Abs(config.IdentityFile)
if err != nil {
return err
}
config.IdentityFile = absPath
_, err = config.ReadIdentityFile()
return err
}

View File

@ -9,30 +9,6 @@ import (
"github.com/status-im/status-go/geth/params" "github.com/status-im/status-go/geth/params"
) )
var (
prodMode = flag.Bool("production", false, "Whether production settings should be loaded")
nodeKeyFile = flag.String("nodekey", "", "P2P node key file (private key)")
dataDir = flag.String("datadir", "wnode-status-data", "Data directory for the databases and keystore")
networkID = flag.Int("networkid", params.RopstenNetworkID, "Network identifier (integer, 1=Homestead, 3=Ropsten, 4=Rinkeby)")
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 enpoint enabled")
// wnode specific flags
echo = flag.Bool("echo", true, "Echo mode, prints some arguments for diagnostics")
bootstrap = flag.Bool("bootstrap", true, "Don't actively connect to peers, wait for incoming connections")
notify = flag.Bool("notify", false, "Node is capable of sending Push Notifications")
forward = flag.Bool("forward", false, "Only forward messages, neither send nor decrypt messages")
mailserver = flag.Bool("mailserver", false, "Delivers expired messages on demand")
identity = flag.String("identity", "", "Protocol identity file (private key used for asymmetric encryption)")
password = flag.String("password", "", "Password file (password is used for symmetric encryption)")
port = flag.Int("port", params.WhisperPort, "Whisper node's listening port")
pow = 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")
injectAccounts = flag.Bool("injectaccounts", true, "Whether test account should be injected or not")
firebaseAuth = flag.String("firebaseauth", "", "FCM Authorization Key used for sending Push Notifications")
)
func main() { func main() {
flag.Parse() flag.Parse()
@ -77,8 +53,6 @@ func main() {
// printHeader prints command header // printHeader prints command header
func printHeader(config *params.NodeConfig) { func printHeader(config *params.NodeConfig) {
fmt.Println("Starting Whisper/5 node..") fmt.Println("Starting Whisper V5 node...")
if config.WhisperConfig.EchoMode { fmt.Printf("Config: %s\n", config.WhisperConfig)
fmt.Printf("Whisper Config: %s\n", config.WhisperConfig)
}
} }

View File

@ -74,5 +74,5 @@ func (ld LogDeliveryService) SendState(state whisper.MessageState) {
} }
encodedStat := base64.StdEncoding.EncodeToString(statdata) encodedStat := base64.StdEncoding.EncodeToString(statdata)
log.Info("Message delivery notification", "state", encodedStat) log.Debug("Message delivery notification", "state", encodedStat)
} }

View File

@ -100,7 +100,7 @@ func defaultEmbeddedNodeConfig(config *params.NodeConfig) *node.Config {
DiscoveryV5Addr: ":0", DiscoveryV5Addr: ":0",
BootstrapNodes: makeBootstrapNodes(), BootstrapNodes: makeBootstrapNodes(),
BootstrapNodesV5: makeBootstrapNodesV5(), BootstrapNodesV5: makeBootstrapNodesV5(),
ListenAddr: ":0", ListenAddr: config.ListenAddr,
NAT: nat.Any(), NAT: nat.Any(),
MaxPeers: config.MaxPeers, MaxPeers: config.MaxPeers,
MaxPendingPeers: config.MaxPendingPeers, MaxPendingPeers: config.MaxPendingPeers,
@ -195,22 +195,25 @@ func activateShhService(stack *node.Node, config *params.NodeConfig, deliverySer
} }
// enable mail service // enable mail service
if whisperConfig.MailServerNode { if whisperConfig.EnableMailServer {
password, err := whisperConfig.ReadPasswordFile() password, err := whisperConfig.ReadPasswordFile()
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Info("Register MailServer")
var mailServer mailserver.WMailServer var mailServer mailserver.WMailServer
whisperService.RegisterServer(&mailServer) whisperService.RegisterServer(&mailServer)
mailServer.Init(whisperService, whisperConfig.DataDir, string(password), whisperConfig.MinimumPoW) mailServer.Init(whisperService, whisperConfig.DataDir, string(password), whisperConfig.MinimumPoW)
} }
// enable notification service // enable notification service
if whisperConfig.NotificationServerNode { if whisperConfig.EnablePushNotification {
log.Info("Register PushNotification server")
var notificationServer notifications.NotificationServer var notificationServer notifications.NotificationServer
whisperService.RegisterNotificationServer(&notificationServer) whisperService.RegisterNotificationServer(&notificationServer)
notificationServer.Init(whisperService, whisperConfig) notificationServer.Init(whisperService, whisperConfig)
} }

View File

@ -88,34 +88,24 @@ type WhisperConfig struct {
// Enabled flag specifies whether protocol is enabled // Enabled flag specifies whether protocol is enabled
Enabled bool Enabled bool
// IdentityFile path to private key, that will be loaded as identity into Whisper // IdentityFile path to private key, that will be loaded as identity into Whisper.
// Currently, it's used by Push Notification service.
IdentityFile string IdentityFile string
// PasswordFile path to password file, for non-interactive password entry // PasswordFile path to password file.
// (if no account file selected, then this password is used for symmetric encryption) // Currently, it's used by MailServer.
PasswordFile string PasswordFile string
// EchoMode if mode is on, prints some arguments for diagnostics // EnableMailServer is mode when node is capable of delivering expired messages on demand
EchoMode bool EnableMailServer bool
// BootstrapNode whether node doesn't actively connect to peers, and waits for incoming connections // EnablePushNotification is mode when node is capable of sending Push (and probably other kinds) Notifications
BootstrapNode bool EnablePushNotification bool
// ForwarderNode is mode when node only forwards messages, neither sends nor decrypts messages
ForwarderNode bool
// MailServerNode is mode when node is capable of delivering expired messages on demand
MailServerNode bool
// NotificationServerNode is mode when node is capable of sending Push (and probably other kinds) Notifications
NotificationServerNode bool
// DataDir is the file system folder Whisper should use for any data storage needs. // DataDir is the file system folder Whisper should use for any data storage needs.
// For instance, MailServer will use this directory to store its data.
DataDir string DataDir string
// Port Whisper node's listening port
Port int
// MinimumPoW minimum PoW for Whisper messages // MinimumPoW minimum PoW for Whisper messages
MinimumPoW float64 MinimumPoW float64
@ -241,6 +231,9 @@ type NodeConfig struct {
// remote peer identification as well as network traffic encryption. // remote peer identification as well as network traffic encryption.
NodeKeyFile string NodeKeyFile string
// ListenAddr is an IP address and port of this node (e.g. 127.0.0.1:30303).
ListenAddr string
// Name sets the instance name of the node. It must not contain the / character. // Name sets the instance name of the node. It must not contain the / character.
Name string `validate:"excludes=/"` Name string `validate:"excludes=/"`
@ -323,6 +316,7 @@ func NewNodeConfig(dataDir string, networkID uint64, devMode bool) (*NodeConfig,
RPCEnabled: RPCEnabledDefault, RPCEnabled: RPCEnabledDefault,
HTTPHost: HTTPHost, HTTPHost: HTTPHost,
HTTPPort: HTTPPort, HTTPPort: HTTPPort,
ListenAddr: ListenAddr,
APIModules: APIModules, APIModules: APIModules,
WSHost: WSHost, WSHost: WSHost,
WSPort: WSPort, WSPort: WSPort,
@ -342,7 +336,6 @@ func NewNodeConfig(dataDir string, networkID uint64, devMode bool) (*NodeConfig,
}, },
WhisperConfig: &WhisperConfig{ WhisperConfig: &WhisperConfig{
Enabled: true, Enabled: true,
Port: WhisperPort,
MinimumPoW: WhisperMinimumPoW, MinimumPoW: WhisperMinimumPoW,
TTL: WhisperTTL, TTL: WhisperTTL,
FirebaseConfig: &FirebaseConfig{ FirebaseConfig: &FirebaseConfig{

View File

@ -2,6 +2,7 @@ package params_test
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -13,7 +14,6 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
gethparams "github.com/ethereum/go-ethereum/params" gethparams "github.com/ethereum/go-ethereum/params"
"github.com/status-im/status-go/geth/params" "github.com/status-im/status-go/geth/params"
. "github.com/status-im/status-go/testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -429,34 +429,21 @@ func TestLoadNodeConfig(t *testing.T) {
} }
func TestConfigWriteRead(t *testing.T) { func TestConfigWriteRead(t *testing.T) {
configReadWrite := func(networkId uint64, refFile string) { tmpDir, err := ioutil.TempDir(os.TempDir(), "geth-config-tests")
tmpDir, err := ioutil.TempDir(os.TempDir(), "geth-config-tests") require.Nil(t, err)
require.Nil(t, err) defer os.RemoveAll(tmpDir) // nolint: errcheck
defer os.RemoveAll(tmpDir) // nolint: errcheck
nodeConfig, err := params.NewNodeConfig(tmpDir, networkId, true) nodeConfig, err := params.NewNodeConfig(tmpDir, params.RopstenNetworkID, true)
require.Nil(t, err, "cannot create new config object") require.Nil(t, err, "cannot create new config object")
err = nodeConfig.Save() err = nodeConfig.Save()
require.Nil(t, err, "cannot persist configuration") require.Nil(t, err, "cannot persist configuration")
loadedConfigData, err := ioutil.ReadFile(filepath.Join(nodeConfig.DataDir, "config.json")) loadedConfigData, err := ioutil.ReadFile(filepath.Join(nodeConfig.DataDir, "config.json"))
require.Nil(t, err, "cannot read configuration from disk") require.Nil(t, err, "cannot read configuration from disk")
require.Contains(t, string(loadedConfigData), fmt.Sprintf(`"DevMode": %t`, true))
refConfigData := LoadFromFile(refFile) require.Contains(t, string(loadedConfigData), fmt.Sprintf(`"NetworkId": %d`, params.RopstenNetworkID))
require.Contains(t, string(loadedConfigData), fmt.Sprintf(`"DataDir": "%s"`, tmpDir))
// Ease updating new config data.
//ioutil.WriteFile(fmt.Sprintf("/tmp/chainId.%d.json", networkId), []byte(loadedConfigData), 0777)
refConfigData = strings.Replace(refConfigData, "$TMPDIR", nodeConfig.DataDir, -1)
refConfigData = strings.Replace(refConfigData, "$VERSION", params.Version, -1)
require.Equal(t, strings.TrimSpace(string(refConfigData[:])), strings.TrimSpace(string(loadedConfigData[:])))
}
configReadWrite(params.RinkebyNetworkID, "testdata/config.rinkeby.json")
configReadWrite(params.RopstenNetworkID, "testdata/config.ropsten.json")
configReadWrite(params.MainNetworkID, "testdata/config.mainnet.json")
} }
// TestNodeConfigValidate checks validation of individual fields. // TestNodeConfigValidate checks validation of individual fields.

View File

@ -23,6 +23,9 @@ const (
// HTTPPort is HTTP-RPC port (replaced in unit tests) // HTTPPort is HTTP-RPC port (replaced in unit tests)
HTTPPort = 8545 HTTPPort = 8545
// ListenAddr is an IP address and port of this node (e.g. 127.0.0.1:30303).
ListenAddr = ":0"
// APIModules is a list of modules to expose via any type of RPC (HTTP, IPC, in-proc) // APIModules is a list of modules to expose via any type of RPC (HTTP, IPC, in-proc)
APIModules = "db,eth,net,web3,shh,personal,admin" APIModules = "db,eth,net,web3,shh,personal,admin"
@ -67,9 +70,6 @@ const (
// WhisperDataDir is directory where Whisper data is stored, relative to DataDir // WhisperDataDir is directory where Whisper data is stored, relative to DataDir
WhisperDataDir = "wnode" WhisperDataDir = "wnode"
// WhisperPort is Whisper node listening port
WhisperPort = 30379
// WhisperMinimumPoW amount of work for Whisper message to be added to sending queue // WhisperMinimumPoW amount of work for Whisper message to be added to sending queue
WhisperMinimumPoW = 0.001 WhisperMinimumPoW = 0.001

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,10 +3,13 @@
"version": "0.9.8", "version": "0.9.8",
"description": "JavaScript tests for RPC API (Whisper/5, Swarm)", "description": "JavaScript tests for RPC API (Whisper/5, Swarm)",
"main": "index.js", "main": "index.js",
"engines": {
"node": ">=8.9.0"
},
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"chai": "^3.5.0", "chai": "^4.1.2",
"mocha": "^3.5.0", "mocha": "^3.5.3",
"requirejs": "^2.3.4", "requirejs": "^2.3.4",
"web3": "https://github.com/status-im/web3.js#status-develop" "web3": "https://github.com/status-im/web3.js#status-develop"
}, },

View File

@ -104,7 +104,7 @@ func scriptsReadmeMd() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "scripts/README.md", size: 133, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "scripts/README.md", size: 133, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -124,7 +124,7 @@ func scriptsWeb3Js() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "scripts/web3.js", size: 497689, mode: os.FileMode(420), modTime: time.Unix(1510978249, 0)} info := bindataFileInfo{name: "scripts/web3.js", size: 497689, mode: os.FileMode(420), modTime: time.Unix(1511731628, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -144,7 +144,7 @@ func configChtJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/cht.json", size: 7418, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "config/cht.json", size: 7418, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -164,7 +164,7 @@ func configPublicChainAccountsJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 165, mode: os.FileMode(420), modTime: time.Unix(1510977604, 0)} info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 165, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -184,7 +184,7 @@ func configStatusChainAccountsJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 330, mode: os.FileMode(420), modTime: time.Unix(1510977604, 0)} info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 330, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -204,7 +204,7 @@ func configStatusChainGenesisJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/status-chain-genesis.json", size: 612, mode: os.FileMode(420), modTime: time.Unix(1510977643, 0)} info := bindataFileInfo{name: "config/status-chain-genesis.json", size: 612, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -224,7 +224,7 @@ func configTestDataJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(420), modTime: time.Unix(1510977604, 0)} info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -244,7 +244,7 @@ func keysFirebaseauthkey() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -264,7 +264,7 @@ func keysTestAccount1StatusChainPk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(420), modTime: time.Unix(1510857258, 0)} info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -284,7 +284,7 @@ func keysTestAccount1Pk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -304,7 +304,7 @@ func keysTestAccount2StatusChainPk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(420), modTime: time.Unix(1510857258, 0)} info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -324,7 +324,7 @@ func keysTestAccount2Pk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -344,7 +344,7 @@ func keysTestAccount3BeforeEip55Pk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(420), modTime: time.Unix(1510857258, 0)} info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -364,7 +364,7 @@ func keysWnodekey() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/wnodekey", size: 65, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "keys/wnodekey", size: 65, mode: os.FileMode(420), modTime: time.Unix(1511267822, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -384,7 +384,7 @@ func keysWnodepassword() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/wnodepassword", size: 9, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "keys/wnodepassword", size: 9, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -404,7 +404,7 @@ func testdataJailCommandsJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/jail/commands.js", size: 7677, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/jail/commands.js", size: 7677, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -424,7 +424,7 @@ func testdataJailStatusJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/jail/status.js", size: 3402, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/jail/status.js", size: 3402, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -444,7 +444,7 @@ func testdataJailTxSendContextNoMessageIdJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/jail/tx-send/context-no-message-id.js", size: 1793, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/jail/tx-send/context-no-message-id.js", size: 1793, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -464,7 +464,7 @@ func testdataJailTxSendMessageIdNoContextJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/jail/tx-send/message-id-no-context.js", size: 1875, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/jail/tx-send/message-id-no-context.js", size: 1875, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -484,7 +484,7 @@ func testdataJailTxSendNoMessageIdOrContextJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/jail/tx-send/no-message-id-or-context.js", size: 1354, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/jail/tx-send/no-message-id-or-context.js", size: 1354, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -504,7 +504,7 @@ func testdataJailTxSendTxSendJs() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/jail/tx-send/tx-send.js", size: 3343, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/jail/tx-send/tx-send.js", size: 3343, mode: os.FileMode(420), modTime: time.Unix(1505738069, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -524,7 +524,7 @@ func testdataNodeTestSol() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "testdata/node/test.sol", size: 119, mode: os.FileMode(420), modTime: time.Unix(1510539850, 0)} info := bindataFileInfo{name: "testdata/node/test.sol", size: 119, mode: os.FileMode(420), modTime: time.Unix(1505683992, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }

114
static/tests/mailserver.js Normal file
View File

@ -0,0 +1,114 @@
const crypto = require('crypto');
const { spawn } = require('child_process');
const { expect } = require('chai');
const Web3 = require('web3');
describe('Whisper MailServer', () => {
const identityA = '0x04eedbaafd6adf4a9233a13e7b1c3c14461fffeba2e9054b8d456ce5f6ebeafadcbf3dce3716253fbc391277fa5a086b60b283daf61fb5b1f26895f456c2f31ae3';
const identityB = '0x0490161b00f2c47542d28c2e8908e77159b1720dccceb6393d7c001850122efc3b1709bcea490fd8f5634ba1a145aa0722d86b9330b0e39a8d493cb981fd459da2';
const topic = `0x${crypto.randomBytes(4).toString('hex')}`;
const sharedSymKey = '0x6c32583c0bc13ef90a10b36ed6f66baaa0e537d0677619993bfd72c819cba6f3';
describe('NodeA', () => {
let nodeA;
let nodeAProcess;
before(() => {
nodeAProcess = spawn(
'./build/bin/wnode-status',
['-datadir', 'wnode-data-1', '-http', '-httpport', '8590']
);
nodeA = new Web3(new Web3.providers.HttpProvider('http://localhost:8590'));
});
after((done) => {
nodeAProcess.kill('SIGTERM');
nodeAProcess.on('exit', (code, signal) => {
expect(code).to.be.null;
expect(signal).to.equal('SIGTERM');
done();
});
});
it('Should be online', () => {
expect(nodeA).to.not.be.null;
expect(nodeA.isConnected()).to.be.true;
});
it('Should use Whisper V5', () => {
expect(nodeA.shh.version()).to.equal('5.0');
});
it('Should send a message', () => {
const symKeyId = nodeA.shh.addSymKey(sharedSymKey);
const result = nodeA.shh.post({
symKeyID: symKeyId,
topic: topic,
payload: nodeA.toHex('hello!'),
ttl: 60,
powTime: 10,
powTarget: 2.5
});
expect(result).to.be.true;
});
});
describe('NodeB', () => {
let nodeBProcess;
let nodeB;
before(() => {
nodeBProcess = spawn(
'./build/bin/wnode-status',
['-datadir', 'wnode-data-2', '-http', '-httpport', '8591']
);
nodeB = new Web3(new Web3.providers.HttpProvider('http://localhost:8591'));
});
after((done) => {
nodeBProcess.kill('SIGTERM');
nodeBProcess.on('exit', (code, signal) => {
expect(code).to.be.null;
expect(signal).to.equal('SIGTERM');
done();
});
});
it('Should be online', () => {
expect(nodeB).to.not.be.null;
expect(nodeB.isConnected()).to.be.true;
});
it('Should use Whisper V5', () => {
expect(nodeB.shh.version()).to.equal('5.0');
});
it('Should request and receive old messages', (done) => {
const symKeyId = nodeB.shh.addSymKey(sharedSymKey);
nodeB.shh.newMessageFilter({
topics: [topic],
symKeyID: symKeyId,
allowP2P: true
}, (err, data) => {
if (!err) {
done(err);
return;
}
done();
}, (err) => {
done(err)
});
// (optional)
// nodeB.shh.addMailServer({ ... });
// send a request for old messages
// nodeB.shh.requestMessages({
// start: timestamp,
// end: timestamp,
// mailServerID: (optional)
// });
});
});
});

View File

@ -3,7 +3,7 @@ var expect = chai.expect;
var assert = chai.assert; var assert = chai.assert;
var Web3 = require('web3'); var Web3 = require('web3');
describe('Whisper Tests', function () { describe.skip('Whisper Tests', function () {
var node1 = new Web3(); var node1 = new Web3();
var node2 = new Web3(); var node2 = new Web3();
var web3 = node1; var web3 = node1;