You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Please include any of the following that are applicable:
The code which produced the error
fromweb3importWeb3, HTTPProviderimportmultiprocessingurl="http://ip:port"defconn():
w3=Web3(HTTPProvider(endpoint_uri=url, request_kwargs={"timeout": 1000}))
genesis_account=lambda: (
w3.to_checksum_address(w3.eth.accounts[0]) ifw3.eth.accountselseNone
)
flag=w3.geth.personal.unlock_account(genesis_account(), "", 0)
# execute one more time, then the exception occurs !!!genesis_account()
if__name__=="__main__":
conn()
proc1=multiprocessing.Process(target=conn)
proc2=multiprocessing.Process(target=conn)
proc1.start()
proc2.start()
proc1.join()
proc2.join()
The full output of the error
MainProcess, session: 140271829895392
MainProcess, session: 140271829895392
MainProcess, session: 140271829895392
MainProcess, session: 140271829895392
MainProcess, session: 140271829895392
Process-1, session: 140271829895392
Process-2, session: 140271829895392
Process-2, session: 140271829895392
Process-1, session: 140271829895392
Process-2, session: 140271829895392
Process-1, session: 140271829895392
Process-2, session: 140271829895392
Process Process-2:
Traceback (most recent call last):
File "/home/miniconda3/envs/py38/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/home/miniconda3/envs/py38/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "temp/para_web3.py", line 15, in conn
genesis_account()
File "temp/para_web3.py", line 11, in<lambda>
w3.to_checksum_address(w3.eth.accounts[0]) if w3.eth.accounts else None
File "/home/.local/share/virtualenvs/tor-experiment-L97qUE1y/lib/python3.8/site-packages/web3/eth/eth.py", line 114, in accounts
returnself._accounts()
File "/home/.local/share/virtualenvs/tor-experiment-L97qUE1y/lib/python3.8/site-packages/web3/module.py", line 78, incallerreturn apply_result_formatters(result_formatters, result)
File "cytoolz/functoolz.pyx", line 267, in cytoolz.functoolz.curry.__call__
File "cytoolz/functoolz.pyx", line 263, in cytoolz.functoolz.curry.__call__
File "/home/.local/share/virtualenvs/tor-experiment-L97qUE1y/lib/python3.8/site-packages/web3/module.py", line 49, in apply_result_formatters
formatted_result = pipe(result, result_formatters)
File "cytoolz/functoolz.pyx", line 680, in cytoolz.functoolz.pipe
File "cytoolz/functoolz.pyx", line 655, in cytoolz.functoolz.c_pipe
File "/home/.local/share/virtualenvs/tor-experiment-L97qUE1y/lib/python3.8/site-packages/eth_utils/functional.py", line 47, in inner
return callback(fn(*args, **kwargs))
TypeError: 'bool' object is not iterable
Process-1, session: 140271829895392
Process-1, session: 140271829895392
What type of node you were connecting to.
Private ethereum node. Geth version is 1.10.0-stable.
How can it be fixed?
explain the output
I print session id in the format "{current_process().name}, session: {id(session)}".
The exception happens when querying eth.accounts. The response shoule be type: List[Account], while it is type: bool which should be the response type of unlock_account.
The detailed exception line is the code. It has obtained the response but faces the error type.
reason
When sending requests, web3 uses the cached session with SimpleCache(). 'SimpleCache()' is instantiated upon importing the web3 and won't be re-instantiated whenever creating a new Web3() .
In the main process, after executing conn() the first session is cached. When forking the children process, all objects including the cached session in the main process are also forked. However, the underlying connections of this session will be shared across all processes, which could cause the responses mixed up in different processes.
It is an absolutely dangerous BUG !!!
solution
solution 1.
The easiest solution is to change the cache key. Now the key is just tied to the thread identifier which is identical in the above codes. Just add the process identifier into the key.
solution 2.
Solution 1 is not the best because all process are still using the same one SimpleCache(). I think, it should check whether it is in a new forked process or not. If it is, then a new SimpleCache()` should be instantiated.
The text was updated successfully, but these errors were encountered:
The problem is that even though I use two seperate instances of w3 in different processes, this ERROR still exists just like the above example.
Though it doesn't support multiprocessing, it shouldn't occur any errors when using seperate instances in different processes.
The key BUG is about when to initialize SimpleCache() and how to set the cache key. The cache key is only identical to the threading identifier. That's NOT enough in python.
pip freeze
outputWhat was wrong?
Please include any of the following that are applicable:
How can it be fixed?
explain the output
I print session id in the format
"{current_process().name}, session: {id(session)}"
.The exception happens when querying
eth.accounts
. The response shoule betype: List[Account]
, while it istype: bool
which should be the response type ofunlock_account
.The detailed exception line is the code. It has obtained the response but faces the error type.
reason
When sending requests, web3 uses the cached session with
SimpleCache()
. 'SimpleCache()' is instantiated upon importing the web3 and won't be re-instantiated whenever creating a newWeb3()
.In the main process, after executing
conn()
the first session is cached. When forking the children process, all objects including the cached session in the main process are also forked. However, the underlying connections of this session will be shared across all processes, which could cause the responses mixed up in different processes.It is an absolutely dangerous BUG !!!
solution
The easiest solution is to change the cache key. Now the key is just tied to the thread identifier which is identical in the above codes. Just add the process identifier into the key.
Solution 1 is not the best because all process are still using the same one
SimpleCache()
. I think, it should check whether it is in a new forked process or not. If it is, then a new SimpleCache()` should be instantiated.The text was updated successfully, but these errors were encountered: