3

Whisper Protocol is not well documented related to its usage. I believe this issue will help other users who might face with similar problem.

Each sent message has time-to-live in seconds (ttl), that is defined by the sender. For more detail please see Whisper v5 RPC API => shh_post. Whisper Protocol keeps received messages in the memory until messages' time-to-live time is over, when geth was closed or shh.newMessageFilter() is not activated.

=> How could we access and print those received messages that are actually stored in the memory?


Whisper v5 RPC API:

shh_getFilterMessages

Retrieve messages that match the filter criteria and are received between the last time this function was called and now.

  • But there is no getFilterMessages() method with the latest shh. Please see.

On this solution; we can use same key pairs after geth is restarted. But the issue after geth is restarted and later when we run shh.newMessageFilter(); it does not retrieve/return any message that was sent while geth was closed.

[Q] How could we obtain/filter messages that sent when geth was closed or shh.newMessageFilter() is not activated?. When we run web3.shh.newMessageFilter(), it only retrieves/filters messages right after it start running and it does not filter/print any message before it starts running.

Example Scenario:

=> On the receiver node I closed geth and from the sender node, I have sent multiple messages into receiver node. Later, when I reopened geth on the receiver node, shh.info.memory verifies that there are received messages in memory, but I was not able to retrieve/filter those messages using web3.shh.newMessageFilter().

> shh.info.memory
780

Here is some logs:

Creating web3.shh.newMessageFilter():

> kId=shh.addPrivateKey('0x8de0b39f3a4a109f27bb06a92dab680d58e8f029eaca61da6be7115981a2ed11')
"439bfd6aa63a81b404ba20e4fc250e11c326d72ad9943c72dc445f476638989d"

> filter=web3.shh.newMessageFilter(
...         {privateKeyID:kId},
...         function(err, res) {console.log(web3.toUtf8(res.payload))});
{
  callbacks: [function(err, res)],
  filterId: "a0b4194651c9143d977c2fa4848ab681b414720364461b4096fb17588d84ae78",
  formatter: null,
  getLogsCallbacks: [],
  implementation: {
    getLogs: function(),
    newFilter: function(),
    poll: function(),
    uninstallFilter: function()
  },
  options: {
    privateKeyID: "439bfd6aa63a81b404ba20e4fc250e11c326d72ad9943c72dc445f476638989d"
  },
  pollFilters: [],
  requestManager: {
    polls: {
      82f08d2d7fe974a69acdadcfac39f788575d337eed9577969b617ae28462e597: {
        data: {...},
        id: "82f08d2d7fe974a69acdadcfac39f788575d337eed9577969b617ae28462e597",
        callback: function(error, messages),
        uninstall: function()
      },
      a0b4194651c9143d977c2fa4848ab681b414720364461b4096fb17588d84ae78: {
        data: {...},
        id: "a0b4194651c9143d977c2fa4848ab681b414720364461b4096fb17588d84ae78",
        callback: function(error, messages),
        uninstall: function()
      }
    },
    provider: {
      newAccount: function(),
      openWallet: function(),
      send: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
      sendAsync: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
      sign: function(),
      unlockAccount: function()
    },
    timeout: {},
    poll: function(),
    reset: function(keepIsSyncing),
    send: function(data),
    sendAsync: function(data, callback),
    sendBatch: function(data, callback),
    setProvider: function(p),
    startPolling: function(data, pollId, callback, uninstall),
    stopPolling: function(pollId)
  },
  get: function(callback),
  stopWatching: function(callback),
  watch: function(callback)
}

I can see shh_getFilterMessages under filter.requestManager.polls but I cannot call it.

> filter.requestManager.polls
{
  82f08d2d7fe974a69acdadcfac39f788575d337eed9577969b617ae28462e597: {
    data: {
      method: "shh_getFilterMessages",
      params: ["82f08d2d7fe974a69acdadcfac39f788575d337eed9577969b617ae28462e597"]
    },
    id: "82f08d2d7fe974a69acdadcfac39f788575d337eed9577969b617ae28462e597",
    callback: function(error, messages),
    uninstall: function()
  },
  a0b4194651c9143d977c2fa4848ab681b414720364461b4096fb17588d84ae78: {
    data: {
      method: "shh_getFilterMessages",
      params: ["a0b4194651c9143d977c2fa4848ab681b414720364461b4096fb17588d84ae78"]
    },
    id: "a0b4194651c9143d977c2fa4848ab681b414720364461b4096fb17588d84ae78",
    callback: function(error, messages),
    uninstall: function()
  }
}

> a.requestManager.polls.82f08d2d7fe974a69acdadcfac39f788575d337eed9577969b617ae28462e597
(anonymous): Line 1:23 Unexpected token ILLEGAL

web3.py approach:

from web3 import Web3, HTTPProvider
web3 = Web3(HTTPProvider('http://localhost:8545'))
from web3.shh import Shh
Shh.attach(web3, "shh")

import time
print(web3.shh.info)

keyPair = web3.shh.newKeyPair();

kId = web3.shh.addPrivateKey(keyPair)
print(web3.shh.hasKeyPair(kId))
print('PubKey: ' + web3.shh.getPublicKey(kId))

#Message sent before filter is assigned
web3.shh.post({
  'pubKey': web3.shh.getPublicKey(kId),
  'topic': '0x07678231',
  'powTarget': 2.01,
  'powTime': 2,
  'ttl': 10,
  'payload': web3.toHex(text="test message :)")

});
time.sleep(1)    

received_messages = [];
myFilter = web3.shh.newMessageFilter({'topic': '0x07678231',
                                      'privateKeyID': kId
                                      });
myFilter.poll_interval = 600;

print(myFilter.filter_id)
received_messages = myFilter.get_all_entries() # Error occurs!!
print(received_messages)

Error I am having:

  File "/home/alper/eBlocBroker/venv/lib/python3.5/site-packages/web3/utils/filters.py", line 191, in get_all_entries
    raise NotImplementedError()
NotImplementedError

1 Answer 1

1

Latest Web3.js does not have web3.shh.getMessages() ; but web3.py has it. So I was able to solve this problem using web3.py.

Shh.getMessages(self, filter_id)

=> Retrieve messages that match the filter criteria and are received between the last time this function was called and now.
=> Returns all new messages since the last invocation


First you have to save keyPair and filter-id:

from web3 import Web3, HTTPProvider
web3 = Web3(HTTPProvider('http://localhost:8545'))
from web3.shh import Shh
Shh.attach(web3, "shh")
import time

keyPair =  web3.shh.newKeyPair();
kId     = web3.shh.addPrivateKey(keyPair)
myFilter = web3.shh.newMessageFilter({'topic': '0x07678231',
                                      'privateKeyID': kId
                                      });
myFilter.poll_interval = 600;
print('keyPair: '  + keyPair)
print('FilterID: ' + myFilter.filter_id)

Output:

keyPair: 0xa82ff6abcf75393084edb06d100e53268c5e118884d59282ef9d3396c8537011
FilterID: 35e2f4c4451fb36da13260c67fe57bdff1f2aeea2bdd346611eef61903c19aaa

Later do following; this will print messages that exists on the memory.:

from web3 import Web3, HTTPProvider
web3 = Web3(HTTPProvider('http://localhost:8545'))
from web3.shh import Shh
Shh.attach(web3, "shh")
import time
print(web3.shh.info)

keyPair =  '0xa82ff6abcf75393084edb06d100e53268c5e118884d59282ef9d3396c8537011'; # obtained from web3.shh.newKeyPair();    
kId = web3.shh.addPrivateKey(keyPair)
print(web3.shh.hasKeyPair(kId))
print('PubKey: ' + web3.shh.getPublicKey(kId))

# Message is sent before the filter is activated
web3.shh.post({
  'pubKey': web3.shh.getPublicKey(kId),
  'topic': '0x07678231',
  'powTarget': 2.01,
  'powTime': 2,
  'ttl': 10,
  'payload': web3.toHex(text="test message :)")

});
time.sleep(1)

filterID = '35e2f4c4451fb36da13260c67fe57bdff1f2aeea2bdd346611eef61903c19aaa' #Filter-id is obtained from previous session.
retreived_messages = web3.shh.getMessages(filterID) 

for i in range(0, len(retreived_messages)):
    print(retreived_messages[i]['payload'].decode("utf-8"))
    print(retreived_messages[i])

Output:

test message :)
{'padding': HexBytes('0xcd6e2ee5fb8d7c4b7e296397c2e9d6d2ba9563c003295004afe488dffc384833b8f5ada10a01dd08f16bf6e72a1f6a6ab45ffa3a1a2e23e2a5853b7978d438e306660e22b3edf93359c290dcf5669072aba1c19ab9012d8904f80f7daa256d0d796f4ae096b7ece2c3a34e2f19f5162916bd4537492a137e84d2b717a3b2a91cf4f6291dd5c26d17cdc7df94ddfdedeaad2b216925e9404c8f645cee9cf338957c374e4d6770f27db8624689b7ba4604b3f05ba7d4fa06560a165860dbd1b54562bde7e96686c96aee7a9ad45e2669a05323eec89f5ea23dcda8308cb494d774a1d28b0f8e4058c410326a8fdf'), 
'topic': HexBytes('0x07678231'), 
'payload': HexBytes('0x74657374206d657373616765203a293e3e'),
'recipientPublicKey': HexBytes('0x04d96278caa49aff29d76399001a43a9a8005da21c6853d20d6af11d61df8a2a25de0fe79a1099bd4b915445d94cbd448b2fe548fb53fed5d887291f35de0f44c9'),
'timestamp': 1530126289, 
'ttl': 10, 
'pow': 8.402051282051282, 
'hash': HexBytes('0x58240972265ea90d3cd8af3d71a8eb4663ae5bfccd00f3e2fb100c5072798017')}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.