Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eth_subscribe and eth_unsubscribe support #1402

Closed
tsudmi opened this issue Jul 29, 2019 · 22 comments
Closed

eth_subscribe and eth_unsubscribe support #1402

tsudmi opened this issue Jul 29, 2019 · 22 comments

Comments

@tsudmi
Copy link

tsudmi commented Jul 29, 2019

Hi,

Are there any plans on implementing eth_subscribe/eth_unsubscribe RPC calls similarly how it's done in web3js?

eth_getFilterChanges consumes a lot of traffic as you need to always poll the node for the changes. With eth_subscribe node will push the updates upon arrival.

@kclowes
Copy link
Collaborator

kclowes commented Aug 1, 2019

We do not have any plans yet, but will leave this ticket open to indicate that there is interest!

@jerryji
Copy link
Contributor

jerryji commented Nov 25, 2019

As of Nov-2019, Infura keeps promoting eth_subscribe to an extreme extent that they are not trying to fix any other websocket issues for web3.py

Here's a week-long agonizing talk I had with them --

https://community.infura.io/t/ropsten-websocket-event-timeout-with-web3-py/1078

Given Infura's direction, could the discussion to support eth_subscribe/eth_unsubscribe be revived?

Thanks.

@om26er
Copy link

om26er commented Jul 31, 2020

We are trying to keep our multiple off-chain backends in sync with the blockchain but are having a hard time doing that. We currently have the polling interval set to 300 seconds, maybe we could adjust that a bit. However there are still cases where we could only "afford" a few seconds lag between on-chain and off-chain states. Being able to subscribe to blockchain events will likely make things simpler for us. It will also enable us to simplify our blockchain monitoring code largely.

@tgdn
Copy link

tgdn commented Feb 8, 2021

Hi, thank you for developing this project.

This issue was opened two years ago, has anything been done to implement subscriptions?

Thanks.

@kclowes
Copy link
Collaborator

kclowes commented Feb 8, 2021

@tgdn Nope, not yet, but it's fairly high priority at this point. If anyone has the time to put up a PR, I'd be happy to review/help out. That's probably the fastest way to get something in!

@tgdn
Copy link

tgdn commented Feb 8, 2021

Do you have any idea how you would like this to be built?
I suppose it would be available through the websocket interface.

@kclowes
Copy link
Collaborator

kclowes commented Feb 8, 2021

I'd like to get some feedback from @pipermerriam because I'm not super familiar with python pub/sub paradigms. One naive implementation might be to add the subscribe and unsubscribe methods to the Eth Module, and then we'd have a similar API to the event examples here. But I'm curious if there's a more elegant way.

/cc @marcgarreau

@wolovim
Copy link
Member

wolovim commented Feb 9, 2021

Also unsure of the most pythonic approach. Web3.js uses the event emitter pattern, e.g.,

myContract.events.MyEvent({})
    .on('data', async function(event) {
        // handle event
    })
    .on('error', console.error);

Looks like a python port exists here. Maybe a different flavor of observer pattern is preferred, though. I yield the remainder of my time to Piper or Carver.

@zipzapzanigan
Copy link

im curious if anyone has figured out a way to get eth_subscribe to work with web3py? I just ported a project from web3js because I wanted to work with scikit, only to find that I can't subscribe. I'd love to see this feature implemented, or if someone has an idea of a workaround, that would be great too!

@zipzapzanigan
Copy link

here are two examples of pub sub. python-binance-chain has a subscribe feature and an auto reconnect for their websockets connection.
https://github.com/eclipse/paho.mqtt.python#subscribe-unsubscribe
https://github.com/sammchardy/python-binance-chain

@quazzuk
Copy link

quazzuk commented Jul 5, 2021

can't something similar to this be used?

@Fillicia
Copy link

Fillicia commented Jul 9, 2021

I'm not usually one to give tricks but here's a small snippet you can use to subscribe with autobahn/twisted under python

from twisted.internet.protocol import ReconnectingClientFactory
from autobahn.twisted.websocket import WebSocketClientProtocol, \
    WebSocketClientFactory
import json

#This part dictate how the different events are managed with your websocket
class MyClientProtocol(WebSocketClientProtocol):

    def onConnect(self, response):
        print("Server connected: {0}".format(response.peer))

    def onConnecting(self, transport_details):
        print("Connecting; transport details: {}".format(transport_details))
        return None  # ask for defaults

    def onOpen(self):
        print("WebSocket connection open.")
        # Change this part to the subscription you want to get
        self.sendMessage(json.dumps({"jsonrpc":"2.0","id": 1, "method": "eth_subscribe", "params": ["newHeads"]}).encode('utf8'))

    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))



    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))

#This is to automatically reconnect on failure
class MyClientFactory(WebSocketClientFactory, ReconnectingClientFactory):

    protocol = MyClientProtocol

    def clientConnectionFailed(self, connector, reason):
        print("Client connection failed .. retrying ..")
        self.retry(connector)

    def clientConnectionLost(self, connector, reason):
        print("Client connection lost .. retrying ..")
        self.retry(connector)


if __name__ == '__main__':

    import sys

    from twisted.python import log
    from twisted.internet import reactor

    log.startLogging(sys.stdout)

    factory = MyClientFactory("wss://eth-ropsten.ws.alchemyapi.io/v2/<your API>")

    reactor.connectTCP("eth-ropsten.ws.alchemyapi.io", 80, factory)
    reactor.run()

You would have to manage the response under the onMessage, probably with a json.loads(payload) thingy. I'll let you all discover the rest. Also this is twisted which is similar but different to asyncio so you would have to manage it as such but it's a good start

@ls-lucency
Copy link

any updates on the implementation of subscriptions?

@kclowes
Copy link
Collaborator

kclowes commented Jul 22, 2021

I looked into doing this a while back, and there wasn't really a straightforward way to do it within our existing architecture. It's not on our immediate roadmap but it will probably move up in priority once async gets off the ground since there is so much interest! If anyone wants to take a crack at it, I'd be happy to review/keep things moving!

@SpeakinTelnet
Copy link

Let me know if this is out of place but in case someone want an idea on how to implement this I've made a subscription client for JSON-RPC for python.

https://github.com/SpeakinTelnet/Sub3

@jpiabrantes
Copy link

this answer helped me do eth_subscribe in python.

might be a good solution while we wait for eth_subscribe to be supported by web3.py

@quintos
Copy link

quintos commented Jul 28, 2022

Greetings,

I've made subscription work for websockets using the link below:

link

But does anyone know how to go about doing the same thing for IPC?

@coccoinomane
Copy link
Contributor

coccoinomane commented Mar 9, 2023

Hello,
Is there any update on the eth_subscribe front?
Thanks,
Cocco

@coccoinomane
Copy link
Contributor

On a related note, Infura made a guide to listen to pendong transactions using web3.py:

@pacrob
Copy link
Contributor

pacrob commented Aug 31, 2023

We've added eth_subscribe and eth_unsubscribe with PR #3048, documentation here. It's still in beta, so if you have the time, please take it for a spin and let us know if it meets your needs!

@coccoinomane
Copy link
Contributor

Thanks for the update @pacrob, this is great news 💪

I ended up implementing my own solution in web3client. I think we took a similar approach: https://github.com/coccoinomane/web3client/blob/master/src/web3client/base_client.py#L451-L673

Will test the web3.py implementation at the next occasion.

Cheers,
Cocco

@pacrob
Copy link
Contributor

pacrob commented Sep 1, 2023

Great, thanks! I'm going to close this issue, but please let us know if you have any further suggestions/request.

@pacrob pacrob closed this as completed Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests