Skip to content

Commit

Permalink
Merge pull request #117 from shravan-shandilya/master
Browse files Browse the repository at this point in the history
Whisper support
  • Loading branch information
pipermerriam committed Oct 21, 2016
2 parents ce346fe + 1b9eda6 commit 74a8178
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ env:
- TOX_ENV=py27-net
- TOX_ENV=py34-net
- TOX_ENV=py35-net
# shh
- TOX_ENV=py27-shh
- TOX_ENV=py34-shh
- TOX_ENV=py35-shh
# txpool
- TOX_ENV=py27-txpool
- TOX_ENV=py34-txpool
Expand Down
2 changes: 1 addition & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def setup_testing_geth():
geth_process = GethProcess(
'testing',
base_dir=base_dir,
overrides={'verbosity': '3'},
overrides={'verbosity': '3','shh': True},
)
with geth_process as running_geth_process:
running_geth_process.wait_for_ipc(60)
Expand Down
22 changes: 21 additions & 1 deletion docs/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ will return a new :py:class::`BlockFilter` object.
... sys.stdout.write("New Block: {0}".format(transaction_hash))
...
>>> new_transaction_filter = web3.eth.filter('pending')
>>> new_transaction_filter.watch(new_transaction_filter)
>>> new_transaction_filter.watch(new_transaction_callback)
# each time the client receieves a unmined transaction the
# `new_transaction_filter` function will be called with the transaction
# hash.
Expand Down Expand Up @@ -143,3 +143,23 @@ event data from the event logs.
The :py:class::`PastLogFilter` is a subclass of :py:class::`LogFilter` that is
configured specially to return historical event logs. It conforms to the same
API as the ``LogFilter`` class.


Shh Filter
----------

.. py:class:: ShhFilter(web3, filter_id)
The :py:class:: `ShhFilter` class is used for filtering Shh messages.
You can setup a callback function for Whipser messages matching the topics subscribed using ``web3.shh.filter(filter_params)``,which
will return a :py:class::`ShhFilter` object

.. code-block:: python
>>>def filter_callback(new_message):
... sys.stdout.write("New Shh Message: {0}".format(new_message))
...
>>>shh_filter = web3.shh.filter({"topics":[web3.fromAscii("topic_to_subscribe")]})
>>>shh_filter.watch(filter_callback)
#each time client recieves a Shh messages matching the topics subscibed,
#filter_callback is called
110 changes: 99 additions & 11 deletions docs/web3.shh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,120 @@ SHH API
The ``web3.shh`` object exposes methods to interact with the RPC APIs under the
``shh_`` namespace.

Properties
----------

The following properties are available on the ``web.shh`` namespace.

.. py:attribute:: Shh.version
The version of Whisper protocol used by client

.. code-block:: python
>>>web3.shh.version
2
Methods
-------

The following methods are available on the ``web3.personal`` namespace.
The following methods are available on the ``web3.shh`` namespace.


.. py:method:: Shh.post(self, params)
* Delegates to ``shh_post`` RPC method

* ``params`` cannot be ``None`` and should contain ``topics`` and ``payload``

* Returns ``True`` if the message was succesfully sent,otherwise ``False``

.. code-block:: python
>>>web3.shh.post({"topics":[web3.fromAscii("test_topic")],"payload":web3.fromAscii("test_payload")})
True
.. py:method:: Shh.newIdentity(self)
* Delegates to ``shh_newIdentity`` RPC method

* Returns ``address`` of newly created identity.

.. code-block:: python
>>>web3.shh.newIdentity()
u'0x045ed8042f436e1b546afd16e1f803888b896962484c0154fcc7c5fc43e276972af85f29a995a3beb232a4e9a0648858c0c8c0639d709f5d3230807d084b2d5030'
.. py:method:: Shh.hasIdentity(self, identity)
* Delegates to ``shh_hasIdentity`` RPC method

* Returns ``True`` if the client holds the private key for the given identity,otherwise ``False``

.. code-block:: python
>>>web3.shh.hasIdentity(u'0x045ed8042f436e1b546afd16e1f803888b896962484c0154fcc7c5fc43e276972af85f29a995a3beb232a4e9a0648858c0c8c0639d709f5d3230807d084b2d5030')
True
.. py:method:: Shh.newGroup(self)
* Delegates to ``shh_newGroup`` RPC method

* Returns ``address`` of newly created group.

.. note:: This method is not implemented yet in ``Geth``. `Open Issue <https://github.com/ethereum/go-ethereum/issues/310>`_

.. py:method:: Shh.addToGroup(self, identity)
* Delegates to ``shh_addToGroup`` RPC Method

* Returns ``True`` if the identity was succesfully added to the group,otherwise ``False``

.. note:: This method is not implemented yet in ``Geth``. `Open Issue <https://github.com/ethereum/go-ethereum/issues/310>`_

.. py:method:: Shh.filter(self, filter_params)
* Delegates to ``shh_newFilter`` RPC Method

* ``filter_params`` should contain the ``topics`` to subscribe

* Returns an instance of ``ShhFilter`` on succesful creation of filter,otherwise raises ``ValueError`` exception

.. py:method:: Shh.post(self, *args, **kwargs)
.. code-block:: python
.. note:: Not Implemented
>>>shh_filter = shh.filter({"topics":[web.fromAscii("topic_to_subscribe")]})
>>>shh_filter.filter_id
u'0x0'
.. py:method:: Shh.uninstallFilter(self, filter_id)
.. py:method:: Shh.newIdentity(self, *args, **kwargs)
* Delegates to ``shh_uninstallFilter`` RPC Method

.. note:: Not Implemented
* Returns ``True`` if the filter was sucesfully uninstalled ,otherwise ``False``

.. code-block:: python
.. py:method:: Shh.hasIdentity(self, *args, **kwargs)
>>>web3.shh.uninstallFilter("0x2")
True
.. note:: Not Implemented
.. py:method:: Shh.getFilterChanges(self, filter_id)
* Delegates to ``shh_getFilterChanges`` RPC Method

.. py:method:: Shh.newGroup(self, *args, **kwargs)
* Returns list of messages recieved since last poll

.. code-block:: python
>>>web3.shh.getFilterChanges(self,"0x2")
[{u'from': u'0x0', u'to': u'0x0', u'ttl': 50, u'hash': u'0xf84900b57d856a6ab1b41afc9784c31be48e841b9bcfc6accac14d05d7189f2f', u'payload': u'0x746573696e67', u'sent': 1476625149}]
.. note:: Not Implemented
.. py:method:: Shh.getMessages(self, filter_id)
* Delegates to ``shh_getMessages`` RPC Method

.. py:method:: Shh.addToGroup(self, *args, **kwargs)
* Returns a list of all messages

.. note:: Not Implemented
.. code-block:: python
>>>web3.shh.getMessages("0x2")
[{u'from': u'0x0', u'to': u'0x0', u'ttl': 50, u'hash': u'0x808d74d003d1dcbed546cca29d7a4e839794c226296b613b0fa7a8c670f84146', u'payload': u'0x746573696e67617364', u'sent': 1476625342}, {u'from': u'0x0', u'to': u'0x0', u'ttl': 50, u'hash': u'0x62a2eb9a19968d59d8a85e6dc8d73deb9b4cd40c83d95b796262d6affe6397c6', u'payload': u'0x746573696e67617364617364', u'sent': 1476625369}]
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pytest-pythonpath>=0.3
tox>=1.8.0
eth-testrpc>=0.8.6
ethereum-tester-client>=1.2.3
py-geth>=1.2.0
py-geth>=1.4.0
ethereum>=1.5.2
secp256k1>=0.13.1
rlp>=0.4.6
hypothesis>=3.4.2
flaky>=3.3.0
flake8==3.0.4
2 changes: 1 addition & 1 deletion requirements-docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contextlib2>=0.5.4
#eth-testrpc>=0.8.0
#ethereum-tester-client>=1.1.0
gevent>=1.1.2
py-geth>=1.1.0
py-geth>=1.4.0
py-solc>=0.4.0
#pysha3>=0.3
pytest>=2.7.2
Expand Down
14 changes: 7 additions & 7 deletions tests/filtering/test_contract_on_event_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_on_filter_using_get_interface(web3_empty,
txn_hash = emitter.transact().logNoArgs(emitter_event_ids.LogNoArguments)
txn_receipt = wait_for_transaction(web3, txn_hash)

with gevent.Timeout(10):
with gevent.Timeout(30):
while not filter.get(False):
gevent.sleep(random.random())

Expand Down Expand Up @@ -54,11 +54,11 @@ def test_on_filter_with_only_event_name(web3_empty,
txn_hash = emitter.transact().logNoArgs(emitter_event_ids.LogNoArguments)
txn_receipt = wait_for_transaction(web3, txn_hash)

with gevent.Timeout(5):
with gevent.Timeout(30):
while not seen_logs:
gevent.sleep(random.random())

filter.stop_watching(10)
filter.stop_watching(30)

assert len(seen_logs) == 1
assert seen_logs[0]['transactionHash'] == txn_hash
Expand Down Expand Up @@ -99,11 +99,11 @@ def test_on_filter_with_event_name_and_single_argument(web3_empty,
for txn_hash in txn_hashes:
wait_for_transaction(web3, txn_hash)

with gevent.Timeout(5):
with gevent.Timeout(30):
while len(seen_logs) < 2:
gevent.sleep(random.random())

filter.stop_watching(10)
filter.stop_watching(30)

assert len(seen_logs) == 2
assert {l['transactionHash'] for l in seen_logs} == set(txn_hashes[1:])
Expand Down Expand Up @@ -144,11 +144,11 @@ def test_on_filter_with_event_name_and_non_indexed_argument(web3_empty,
for txn_hash in txn_hashes:
wait_for_transaction(web3, txn_hash)

with gevent.Timeout(5):
with gevent.Timeout(30):
while not seen_logs:
gevent.sleep(random.random())

filter.stop_watching(10)
filter.stop_watching(30)

assert len(seen_logs) == 1
assert seen_logs[0]['transactionHash'] == txn_hashes[1]
6 changes: 3 additions & 3 deletions tests/filtering/test_contract_past_event_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ def test_past_events_filter_with_callback(web3_empty,
else:
filter = Emitter.pastEvents('LogNoArguments', {}, seen_logs.append)

with gevent.Timeout(5):
with gevent.Timeout(30):
while not seen_logs:
gevent.sleep(random.random())

filter.stop_watching(10)
filter.stop_watching(30)

assert len(seen_logs) == 1
event_data = seen_logs[0]
Expand Down Expand Up @@ -62,7 +62,7 @@ def test_past_events_filter_using_get_api(web3_empty,
else:
filter = Emitter.pastEvents('LogNoArguments')

with gevent.Timeout(10):
with gevent.Timeout(30):
while not filter.get(False):
gevent.sleep(random.random())

Expand Down
22 changes: 22 additions & 0 deletions tests/shh-module/test_shh_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import gevent

def test_shh_filter(web3, skip_if_testrpc):
skip_if_testrpc(web3)
recieved_messages = []
shh_filter = web3.shh.filter({"topics":[web3.fromAscii("test")]})
shh_filter.watch(recieved_messages.append)
gevent.sleep(1)

payloads = []
payloads.append(str.encode("payload1"))
web3.shh.post({"topics":[web3.fromAscii("test")], "payload":web3.fromAscii(payloads[len(payloads)-1])})
gevent.sleep(1)

payloads.append(str.encode("payload2"))
web3.shh.post({"topics":[web3.fromAscii("test")], "payload":web3.fromAscii(payloads[len(payloads)-1])})
gevent.sleep(1)

assert len(recieved_messages) > 1

for message in recieved_messages:
assert web3.toAscii(message["payload"]) in payloads
5 changes: 5 additions & 0 deletions tests/shh-module/test_shh_has_identity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def test_shh_has_identity(web3, skip_if_testrpc):
skip_if_testrpc(web3)
new_identity = web3.shh.newIdentity()
assert len(new_identity) == 132
assert web3.shh.hasIdentity(new_identity)
4 changes: 4 additions & 0 deletions tests/shh-module/test_shh_new_identity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def test_shh_new_identity(web3, skip_if_testrpc):
skip_if_testrpc(web3)
new_identity = web3.shh.newIdentity()
assert len(new_identity) == 132
4 changes: 4 additions & 0 deletions tests/shh-module/test_shh_post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def test_shh_post(web3, skip_if_testrpc):
skip_if_testrpc(web3)
random_topic = "testing"
assert web3.shh.post({"topics":[web3.fromAscii(random_topic)], "payload":web3.fromAscii("testing shh on web3.py")})
3 changes: 3 additions & 0 deletions tests/shh-module/test_shh_properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def test_shh_version(web3, skip_if_testrpc):
skip_if_testrpc(web3)
assert web3.shh.version == 2
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ commands=
contracts: py.test {posargs:tests/contracts}
filtering: py.test {posargs:tests/filtering}
net: py.test {posargs:tests/net-module}
shh: py.test {posargs:tests/shh-module}
txpool: py.test {posargs:tests/txpool-module}
db: py.test {posargs:tests/db-module}
managers: py.test {posargs:tests/managers}
Expand Down

0 comments on commit 74a8178

Please sign in to comment.