I have a problem to parallel executions during querying ethereum node transactions via RPC.
Error says that it can not pickle w3 object (when I do pool.starmap_async()).
It's important to do in class. If I remove class and do parallel job, making global w3 in calculate_transaction() - it works, but I need object oriented way.
If I define w3 outside the class in main(), which way is also good and pass w3 like w.start(w3=w3), error is raised the same.
Any ideas how to do?
Code that produced the error
import asyncio
from web3 import Web3, AsyncWeb3
from multiprocessing import Pool, cpu_count
class Wallet():
def start(self):
testnet = 'https://eth-pokt.nodies.app'
# self.w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider(testnet))
self.w3 = Web3(Web3.HTTPProvider(testnet))
if not self.w3.is_connected():
exit("w3 not connected")
block = self.w3.eth.get_block('latest')
transactions = block['transactions'][:min(cpu_count(), 10)]
params = []
for i, hash_ in enumerate(transactions):
params.append((i, hash_))
pool = Pool(min(cpu_count(), 10))
pool.starmap_async(self.calculate_transaction, params).get()
pool.close()
def calculate_transaction(self, i, hash_):
return self.w3.eth.get_transaction(hash_)
def main():
w = Wallet()
w.start()
if __name__ == '__main__':
main()
# asyncio.run(main())
Full error output
Traceback (most recent call last):
File "/home/fridary/python/ethereum/parallel_3.py", line 42, in <module>
main()
File "/home/fridary/python/ethereum/parallel_3.py", line 37, in main
w.start()
File "/home/fridary/python/ethereum/parallel_3.py", line 26, in start
pool.starmap_async(self.calculate_transaction, params).get()
File "/home/fridary/miniconda3/envs/eth/lib/python3.11/multiprocessing/pool.py", line 774, in get
raise self._value
File "/home/fridary/miniconda3/envs/eth/lib/python3.11/multiprocessing/pool.py", line 540, in _handle_tasks
put(task)
File "/home/fridary/miniconda3/envs/eth/lib/python3.11/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fridary/miniconda3/envs/eth/lib/python3.11/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'construct_web3_formatting_middleware.<locals>.formatter_middleware'
Fill this section in if you know how this could or should be fixed
The only solution I came up with is create w3 = Web3(Web3.HTTPProvider(testnet)) everytime in calculate_transaction(). Is it the best way? Create thousands of thousands connections with a node in a loop.
What happened?
I have a problem to parallel executions during querying ethereum node transactions via RPC. Error says that it can not pickle
w3
object (when I dopool.starmap_async()
). It's important to do inclass
. If I removeclass
and do parallel job, makingglobal w3
incalculate_transaction()
- it works, but I need object oriented way. If I definew3
outside the class inmain()
, which way is also good and passw3
likew.start(w3=w3)
, error is raised the same. Any ideas how to do?Code that produced the error
Full error output
Fill this section in if you know how this could or should be fixed
No response
web3 Version
6.16.0
Python Version
3.11.8
Operating System
Ubuntu 20.04.6 LTS
Output from
pip freeze