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

web3.eth.getBlock is broken with PyEVMBackend #1213

Closed
njgheorghita opened this issue Jan 16, 2019 · 3 comments · Fixed by #1217
Closed

web3.eth.getBlock is broken with PyEVMBackend #1213

njgheorghita opened this issue Jan 16, 2019 · 3 comments · Fixed by #1217

Comments

@njgheorghita
Copy link
Contributor

  • Version: 5.0.0b3
  • Python: 3.6
  • OS: osx
  • pip freeze output
appnope (0.1.0)
asn1crypto (0.24.0)
attrdict (2.0.0)
backcall (0.1.0)
certifi (2018.11.29)
cffi (1.11.5)
chardet (3.0.4)
cryptography (2.4.2)
cytoolz (0.9.0.1)
decorator (4.3.0)
eth-abi (2.0.0b4)
eth-account (0.3.0)
eth-bloom (1.0.3)
eth-hash (0.2.0)
eth-keyfile (0.5.1)
eth-keys (0.2.1)
eth-rlp (0.1.2)
eth-tester (0.1.0b36)
eth-typing (2.0.0)
eth-utils (1.4.1)
hexbytes (0.1.0)
idna (2.8)
ipython (7.2.0)
ipython-genutils (0.2.0)
jedi (0.13.2)
lru-dict (1.1.6)
mypy-extensions (0.4.1)
parsimonious (0.8.1)
parso (0.3.1)
pexpect (4.6.0)
pickleshare (0.7.5)
pip (9.0.1)
prompt-toolkit (2.0.7)
ptyprocess (0.6.0)
py-ecc (1.4.7)
py-evm (0.2.0a39)
py-geth (2.0.1)
pycparser (2.19)
pycryptodome (3.7.2)
pyethash (0.1.27)
Pygments (2.3.1)
requests (2.21.0)
rlp (1.1.0)
semantic-version (2.6.0)
setuptools (28.8.0)
six (1.12.0)
toolz (0.9.0)
traitlets (4.3.2)
trie (1.3.8)
urllib3 (1.24.1)
wcwidth (0.1.7)
web3 (5.0.0a3)
websockets (7.0)

What was wrong?

Using web3.eth.getBlock() method is broken in v5 alpha - when using a PyEVMBackend - the same code works fine when using MockBackend.

from web3 import Web3
from eth_tester import PyEVMBackend

w3 = Web3(Web3.EthereumTesterProvider(PyEVMBackend()))
w3.testing.mine()
>>> '0x123....'
w3.eth.getBlock('0x123....')

The final line breaks with the following error

~/ethereum/py-ethpm/trash-venv/lib/python3.6/site-packages/eth/validation.py in validate_word(value, title)
    162             "{title} is not a valid word. Must be of bytes type: Got: {0}".format(
    163                 type(value),
--> 164                 title=title,
    165             )
    166         )

ValidationError: Block Hash is not a valid word. Must be of bytes type: Got: <class 'str'>

How can it be fixed?

Not sure, I spent some time digging around eth-tester/py-evm to try and find a solution, but no luck. Though, this is most likely related to update in those dependencies in v5.

@pipermerriam
Copy link
Member

This is almost certainly related to #1212

Likely candidate for when/how this got introduced is to look at #1188 since it touched the middlewares in web3.py that handled some of the normalization steps.

@njgheorghita
Copy link
Contributor Author

@pipermerriam The problem was with how I was instantiating my class using the PyEVMBackend.

This is what was broken...

from web3 import Web3
from eth_tester import PyEVMBackend

w3 = Web3(Web3.EthereumTesterProvider(PyEVMBackend()))

This is what I should have been doing / What works fine.

from web3 import Web3
from eth_tester import PyEVMBackend, EthereumTester

w3 = Web3(Web3.EthereumTesterProvider(EthereumTester(PyEVMBackend())))

Basically, the inbound tx normalization happens in the EthereumTester class and not in PyEVMBackend - but they share the same methods, so web3's delegator was calling the PyEVMBackend.estimate_gas() directly instead of EthereumTester.estimate_gas() which would normalize and then subsequently pass on the normalized tx to PyEVMBackend.estimate_gas()

I'm unsure as to exactly where I saw the first (aka broken) pattern, but it seems to me that maybe the best fix is something in the docs explaining how to instantiate w/ PyEVMBackend directly - as I think this'll be common now that you can adjust genesis-params in eth-tester.

@pipermerriam
Copy link
Member

When @kclowes and I looked over this today I had the thought that we could add a check to EthereumTesterProvider.__init__ which checked if the provided value was an instance of EthereumTester and errors out if it isn't. Additionally, if the value is a backend it could lazily wrap it in the EthereumTester class. Either way we can prevent this mistake with some simple value checks.

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

Successfully merging a pull request may close this issue.

2 participants