1

I use python 3.7 and own Node.
So i want to receiving every last block from own Node immediately after it was mined.

from web3 import Web3


WEB3_WS_URI = 'ws://node_url:8546'
w3 = Web3(Web3.WebsocketProvider(WEB3_WS_URI))  

After that how i should use w3 for establish connection to receive every new block with transactions immediately after it was mined?

I can use:

def run():
    while True:
        last_block = w3.eth.block_number
        print(last_block)
        time.sleep(45)

but i'm sticking to my own time interval of 45 sec which is not very good because the real interval before to emerge new block can be more or lees. I need get new block only after new event was done - block was mined and ready for parce.

2 Answers 2

3

You can't, at least as of the latest release (5.19.0), do it without polling the endpoint because currently the websocket connection is closed after the first response is received. This is also why the filtering and events functions also require constant polling of the endpoint. Basically, the websocket endpoint is treated like an HTTPProvider or IPCProvider. You would have to connect to the node through a generic websocket client and keep the connection open after calling a subscribe function. The best way with web3.py is to simply poll your node more frequently but discard the result if the block remains the same as your last_block variable.

EDIT August 1, 2022: All indications show that Web3.py v6 is going to be asyncio compatible, but it is not done and there are a range of issues that have yet to be resolved, for example certain middleware implementations. You can give it a try (it's in the same repo). Also it's not fully documented as of this date. Feel free to try it.

2
  • then what the difference between WebsocketProvider and HTTPProvider with web3.py? i thought WebsocketProvider keeps the connection open always after connect and listens new event (block was mined) and HTTPProvider works as endpoint - creates connect, gets some info, closes connect
    – Vadim
    Commented May 29, 2021 at 16:17
  • 1
    In practice, the only difference is the endpoint protocol, which may be slightly faster but may also cause errors on certain calls - namely web3.geth.txpool.contents() if the return data takes longer than the default websocket timeout setting to produce. It's not that maintainers don't know about this issue, since it gets raised in the issues on Github once in a while. However, it doesn't look like it's an urgent enough issue for anyone to fix.
    – Jim Zhou
    Commented May 29, 2021 at 22:30
1

You can also use web3-proxy-providers and subscribe tonewHeads event

web3-proxy-providers is a python package for connecting to HTTP and WebSocket Json-RPC using Socks and HTTP proxies

Learn about newHeads event: https://geth.ethereum.org/docs/interacting-with-geth/rpc/pubsub

Sample Code:

import asyncio
from Crypto.Hash import keccak
from web3 import Web3
from python_socks import ProxyType
from web3_proxy_providers import AsyncSubscriptionWebsocketWithProxyProvider

async def callback(subs_id: str, json_result):
    print(json_result)

async def main(loop: asyncio.AbstractEventLoop):
    provider = AsyncSubscriptionWebsocketProvider(
        loop=loop,
        endpoint_uri='wss://your_node_url',
    )
    
    # subscribe to newHeads
    subscription_id = await provider.subscribe(
        [
            'logs',
            {
                "address": 'newHeads',
                "topics": []
            }
        ],
        callback
    )
    print(f'Subscribed with id {subscription_id}')
    
    # unsubscribe after 30 seconds
    await asyncio.sleep(30)
    await provider.unsubscribe(subscription_id)

if __name__ == '__main__':
    async_loop = asyncio.get_event_loop()
    async_loop.run_until_complete(main(loop=async_loop))

Disclaimer: I am the owner of this package https://github.com/sinarezaei/web3-proxy-providers

Your Answer

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

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