From ba6c96532bfdfcc1bc95d5535d3d6b04ee7de49e Mon Sep 17 00:00:00 2001 From: b00ris Date: Tue, 12 Dec 2017 14:00:17 +0300 Subject: [PATCH] add enode to request messages params (#508) --- e2e/whisper/whisper_mailbox_test.go | 106 ++++++++++++++++++---- geth/api/backend.go | 6 +- geth/whisper/request_historic_messages.go | 68 +++++++++----- 3 files changed, 135 insertions(+), 45 deletions(-) diff --git a/e2e/whisper/whisper_mailbox_test.go b/e2e/whisper/whisper_mailbox_test.go index 5cbf131ae..2a7c23c6a 100644 --- a/e2e/whisper/whisper_mailbox_test.go +++ b/e2e/whisper/whisper_mailbox_test.go @@ -2,7 +2,6 @@ package whisper import ( "encoding/json" - "fmt" "strconv" "testing" "time" @@ -49,13 +48,15 @@ func (s *WhisperMailboxSuite) TestRequestMessageFromMailboxAsync() { s.Require().NoError(err) //Mark mailbox node trusted - mailboxPeer, err := extractIdFromEnode(mailboxNode.Server().NodeInfo().Enode) + 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 := "asdfasdf" + password := "status-offline-inbox" MailServerKeyID, err := w.AddSymKeyFromPassword(password) s.Require().NoError(err) @@ -98,7 +99,7 @@ func (s *WhisperMailboxSuite) TestRequestMessageFromMailboxAsync() { s.Require().Equal(0, len(messages.Result)) //Post message - rpcClient.CallRaw(`{ + resp = rpcClient.CallRaw(`{ "jsonrpc": "2.0", "method": "shh_post", "params": [ @@ -111,8 +112,12 @@ func (s *WhisperMailboxSuite) TestRequestMessageFromMailboxAsync() { } ], "id": 1}`) + postResp := baseRPCResponse{} + err = json.Unmarshal([]byte(resp), &postResp) + s.Require().NoError(err) + s.Require().Nil(postResp.Err) - //Threre are no messages, because it's sender filter + //There are no messages, because it's a sender filter resp = rpcClient.CallRaw(`{ "jsonrpc": "2.0", "method": "shh_getFilterMessages", @@ -125,18 +130,23 @@ func (s *WhisperMailboxSuite) TestRequestMessageFromMailboxAsync() { //act //Request messages from mailbox - rpcClient.CallRaw(`{ + reqMessagesBody := `{ "jsonrpc": "2.0", "id": 1, "method": "shh_requestMessages", "params": [{ - "peer":"` + string(mailboxPeer) + `", + "peer":"` + mailboxPeerStr + `", "topic":"` + topic.String() + `", "symKeyID":"` + MailServerKeyID + `", "from":0, - "to":` + strconv.FormatInt(time.Now().UnixNano(), 10) + ` + "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) @@ -151,6 +161,74 @@ func (s *WhisperMailboxSuite) TestRequestMessageFromMailboxAsync() { //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()) { @@ -210,11 +288,7 @@ type newMessagesFilterResponse struct { Result string Err interface{} } - -func extractIdFromEnode(s string) ([]byte, error) { - n, err := discover.ParseNode(s) - if err != nil { - return nil, fmt.Errorf("Failed to parse enode: %s", err) - } - return n.ID[:], nil +type baseRPCResponse struct { + Result interface{} + Err interface{} } diff --git a/geth/api/backend.go b/geth/api/backend.go index ea8b3c5dd..cb1f5aae7 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -244,11 +244,7 @@ func (m *StatusBackend) registerHandlers() error { return node.ErrRPCClient } - handler, err := whisper.RequestHistoricMessagesHandler(m.nodeManager) - if err != nil { - return err - } - rpcClient.RegisterHandler("shh_requestMessages", handler) + rpcClient.RegisterHandler("shh_requestMessages", whisper.RequestHistoricMessagesHandler(m.nodeManager)) rpcClient.RegisterHandler("eth_accounts", m.accountManager.AccountsRPCHandler()) rpcClient.RegisterHandler("eth_sendTransaction", m.txQueueManager.SendTransactionRPCHandler) m.txQueueManager.SetTransactionQueueHandler(m.txQueueManager.TransactionQueueHandler()) diff --git a/geth/whisper/request_historic_messages.go b/geth/whisper/request_historic_messages.go index 79f6ceeea..8e90a3201 100644 --- a/geth/whisper/request_historic_messages.go +++ b/geth/whisper/request_historic_messages.go @@ -7,6 +7,7 @@ import ( "fmt" "time" + "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/whisper/whisperv5" "github.com/status-im/status-go/geth/common" "github.com/status-im/status-go/geth/rpc" @@ -26,27 +27,25 @@ var ( //ErrMailboxSymkeyIDNotString - error symKeyID is not string type ErrMailboxSymkeyIDNotString = fmt.Errorf("symKeyID is not string") //ErrPeerNotExist - error peer field doesn't exist in request - ErrPeerNotExist = fmt.Errorf("peer does not exist") - //ErrPeerNotString - error peer is not string type - ErrPeerNotString = fmt.Errorf("peer is not string") + ErrPeerOrEnode = fmt.Errorf("enode or peer field should be not empty") ) const defaultWorkTime = 5 //RequestHistoricMessagesHandler returns an RPC handler which sends a p2p request for historic messages. -func RequestHistoricMessagesHandler(nodeManager common.NodeManager) (rpc.Handler, error) { - whisper, err := nodeManager.WhisperService() - if err != nil { - return nil, err - } - - node, err := nodeManager.Node() - if err != nil { - return nil, err - } - +func RequestHistoricMessagesHandler(nodeManager common.NodeManager) rpc.Handler { return func(ctx context.Context, args ...interface{}) (interface{}, error) { - r, err := parseArgs(args) + whisper, err := nodeManager.WhisperService() + if err != nil { + return nil, err + } + + node, err := nodeManager.Node() + if err != nil { + return nil, err + } + + r, err := parseArgs(args...) if err != nil { return nil, err } @@ -67,7 +66,7 @@ func RequestHistoricMessagesHandler(nodeManager common.NodeManager) (rpc.Handler } return true, nil - }, nil + } } type historicMessagesRequest struct { @@ -129,15 +128,11 @@ func parseArgs(args ...interface{}) (historicMessagesRequest, error) { return historicMessagesRequest{}, ErrMailboxSymkeyIDNotString } - peerInterfaceValue, ok := historicMessagesArgs["peer"] - if !ok { - return historicMessagesRequest{}, ErrPeerNotExist + peer, err := getPeerID(historicMessagesArgs) + if err != nil { + return historicMessagesRequest{}, err } - r.Peer, ok = peerInterfaceValue.([]byte) - if !ok { - return historicMessagesRequest{}, ErrPeerNotString - } - + r.Peer = peer return r, nil } @@ -165,3 +160,28 @@ func makePayloadData(r historicMessagesRequest) []byte { copy(data[8:], r.Topic[:]) return data } + +//getPeerID is used to get peerID from string values of peerID or enode +func getPeerID(m map[string]interface{}) ([]byte, error) { + peerInterfaceValue, okPeer := m["peer"] + enodeInterfaceValue, okEnode := m["enode"] + + //only if existing peer or enode(!xor) + if okPeer == okEnode { + return nil, ErrPeerOrEnode + } + var peerOrEnode string + if p, ok := peerInterfaceValue.(string); ok && okPeer { + peerOrEnode = p + } else if str, ok := enodeInterfaceValue.(string); ok && okEnode { + peerOrEnode = str + } else { + return nil, ErrPeerOrEnode + } + + n, err := discover.ParseNode(peerOrEnode) + if err != nil { + return nil, err + } + return n.ID[:], nil +}