status-go/e2e/whisper/whisper_mailbox_test.go

295 lines
8.1 KiB
Go

package whisper
import (
"encoding/json"
"strconv"
"testing"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/whisper/whisperv5"
"github.com/status-im/status-go/e2e"
"github.com/status-im/status-go/geth/api"
. "github.com/status-im/status-go/testing"
"github.com/stretchr/testify/suite"
)
type WhisperMailboxSuite struct {
suite.Suite
}
func TestWhisperMailboxTestSuite(t *testing.T) {
suite.Run(t, new(WhisperMailboxSuite))
}
func (s *WhisperMailboxSuite) TestRequestMessageFromMailboxAsync() {
//arrange
mailboxBackend, stop := s.startMailboxBackend()
defer stop()
mailboxNode, err := mailboxBackend.NodeManager().Node()
s.Require().NoError(err)
mailboxEnode := mailboxNode.Server().NodeInfo().Enode
sender, stop := s.startBackend()
defer stop()
node, err := sender.NodeManager().Node()
s.Require().NoError(err)
s.Require().NotEqual(mailboxEnode, node.Server().NodeInfo().Enode)
err = sender.NodeManager().AddPeer(mailboxEnode)
s.Require().NoError(err)
//wait async processes on adding peer
time.Sleep(time.Second)
w, err := sender.NodeManager().WhisperService()
s.Require().NoError(err)
//Mark mailbox node trusted
parsedNode, err := discover.ParseNode(mailboxNode.Server().NodeInfo().Enode)
s.Require().NoError(err)
mailboxPeer := parsedNode.ID[:]
mailboxPeerStr := parsedNode.ID.String()
err = w.AllowP2PMessagesFromPeer(mailboxPeer)
s.Require().NoError(err)
//Generate mailbox symkey
password := "status-offline-inbox"
MailServerKeyID, err := w.AddSymKeyFromPassword(password)
s.Require().NoError(err)
rpcClient := sender.NodeManager().RPCClient()
s.Require().NotNil(rpcClient)
//create topic
topic := whisperv5.BytesToTopic([]byte("topic name"))
//Add key pair to whisper
keyID, err := w.NewKeyPair()
s.Require().NoError(err)
key, err := w.GetPrivateKey(keyID)
s.Require().NoError(err)
pubkey := hexutil.Bytes(crypto.FromECDSAPub(&key.PublicKey))
//Create message filter
resp := rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_newMessageFilter", "params": [
{"privateKeyID": "` + keyID + `", "topics": [ "` + topic.String() + `"], "allowP2P":true}
],
"id": 1
}`)
msgFilterResp := newMessagesFilterResponse{}
err = json.Unmarshal([]byte(resp), &msgFilterResp)
messageFilterID := msgFilterResp.Result
s.Require().NoError(err)
s.Require().NotEqual("", messageFilterID)
//Threre are no messages at filter
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_getFilterMessages",
"params": ["` + messageFilterID + `"],
"id": 1}`)
messages := getFilterMessagesResponse{}
err = json.Unmarshal([]byte(resp), &messages)
s.Require().NoError(err)
s.Require().Equal(0, len(messages.Result))
//Post message
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_post",
"params": [
{
"pubKey": "` + pubkey.String() + `",
"topic": "` + topic.String() + `",
"payload": "0x73656e74206265666f72652066696c7465722077617320616374697665202873796d6d657472696329",
"powTarget": 0.001,
"powTime": 2
}
],
"id": 1}`)
postResp := baseRPCResponse{}
err = json.Unmarshal([]byte(resp), &postResp)
s.Require().NoError(err)
s.Require().Nil(postResp.Err)
//There are no messages, because it's a sender filter
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_getFilterMessages",
"params": ["` + messageFilterID + `"],
"id": 1}`)
err = json.Unmarshal([]byte(resp), &messages)
s.Require().NoError(err)
s.Require().Equal(0, len(messages.Result))
//act
//Request messages from mailbox
reqMessagesBody := `{
"jsonrpc": "2.0",
"id": 1,
"method": "shh_requestMessages",
"params": [{
"peer":"` + mailboxPeerStr + `",
"topic":"` + topic.String() + `",
"symKeyID":"` + MailServerKeyID + `",
"from":0,
"to":` + strconv.FormatInt(time.Now().UnixNano()/int64(time.Second), 10) + `
}]
}`
resp = rpcClient.CallRaw(reqMessagesBody)
reqMessagesResp := baseRPCResponse{}
err = json.Unmarshal([]byte(resp), &reqMessagesResp)
s.Require().NoError(err)
s.Require().Nil(postResp.Err)
//wait to receive message
time.Sleep(time.Second)
//And we receive message
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_getFilterMessages",
"params": ["` + messageFilterID + `"],
"id": 1}`)
err = json.Unmarshal([]byte(resp), &messages)
//assert
s.Require().NoError(err)
s.Require().Equal(1, len(messages.Result))
//check that there are no messages
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_getFilterMessages",
"params": ["` + messageFilterID + `"],
"id": 1}`)
err = json.Unmarshal([]byte(resp), &messages)
//assert
s.Require().NoError(err)
s.Require().Equal(0, len(messages.Result))
//Request each one messages from mailbox, using same params
resp = rpcClient.CallRaw(reqMessagesBody)
reqMessagesResp = baseRPCResponse{}
err = json.Unmarshal([]byte(resp), &reqMessagesResp)
s.Require().NoError(err)
s.Require().Nil(postResp.Err)
//wait to receive message
time.Sleep(time.Second)
//And we receive message
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_getFilterMessages",
"params": ["` + messageFilterID + `"],
"id": 1}`)
err = json.Unmarshal([]byte(resp), &messages)
//assert
s.Require().NoError(err)
s.Require().Equal(1, len(messages.Result))
time.Sleep(time.Second)
//Request each one messages from mailbox using enode
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"id": 2,
"method": "shh_requestMessages",
"params": [{
"enode":"` + mailboxEnode + `",
"topic":"` + topic.String() + `",
"symKeyID":"` + MailServerKeyID + `",
"from":0,
"to":` + strconv.FormatInt(time.Now().UnixNano()/int64(time.Second), 10) + `
}]
}`)
reqMessagesResp = baseRPCResponse{}
err = json.Unmarshal([]byte(resp), &reqMessagesResp)
s.Require().NoError(err)
s.Require().Nil(postResp.Err)
//wait to receive message
time.Sleep(time.Second)
//And we receive message
resp = rpcClient.CallRaw(`{
"jsonrpc": "2.0",
"method": "shh_getFilterMessages",
"params": ["` + messageFilterID + `"],
"id": 1}`)
err = json.Unmarshal([]byte(resp), &messages)
//assert
s.Require().NoError(err)
s.Require().Equal(1, len(messages.Result))
}
func (s *WhisperMailboxSuite) startBackend() (*api.StatusBackend, func()) {
//Start sender node
backend := api.NewStatusBackend()
nodeConfig, err := e2e.MakeTestNodeConfig(GetNetworkID())
s.Require().NoError(err)
s.Require().False(backend.IsNodeRunning())
nodeStarted, err := backend.StartNode(nodeConfig)
s.Require().NoError(err)
<-nodeStarted // wait till node is started
s.Require().True(backend.IsNodeRunning())
return backend, func() {
s.True(backend.IsNodeRunning())
backendStopped, err := backend.StopNode()
s.NoError(err)
<-backendStopped
s.False(backend.IsNodeRunning())
}
}
func (s *WhisperMailboxSuite) startMailboxBackend() (*api.StatusBackend, func()) {
//Start mailbox node
mailboxBackend := api.NewStatusBackend()
mailboxConfig, err := e2e.MakeTestNodeConfig(GetNetworkID())
s.Require().NoError(err)
mailboxConfig.LightEthConfig.Enabled = false
mailboxConfig.WhisperConfig.Enabled = true
mailboxConfig.KeyStoreDir = "../../.ethereumtest/mailbox/"
mailboxConfig.WhisperConfig.EnableMailServer = true
mailboxConfig.WhisperConfig.IdentityFile = "../../static/keys/wnodekey"
mailboxConfig.WhisperConfig.PasswordFile = "../../static/keys/wnodepassword"
mailboxConfig.WhisperConfig.DataDir = "../../.ethereumtest/mailbox/w2"
mailboxConfig.DataDir = "../../.ethereumtest/mailbox/"
mailboxNodeStarted, err := mailboxBackend.StartNode(mailboxConfig)
s.Require().NoError(err)
<-mailboxNodeStarted // wait till node is started
s.Require().True(mailboxBackend.IsNodeRunning())
return mailboxBackend, func() {
s.True(mailboxBackend.IsNodeRunning())
backendStopped, err := mailboxBackend.StopNode()
s.NoError(err)
<-backendStopped
s.False(mailboxBackend.IsNodeRunning())
}
}
type getFilterMessagesResponse struct {
Result []map[string]interface{}
Err interface{}
}
type newMessagesFilterResponse struct {
Result string
Err interface{}
}
type baseRPCResponse struct {
Result interface{}
Err interface{}
}