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

fix bug in how eth_tester_middleware filled default fields #2600

Merged
merged 1 commit into from
Aug 22, 2022

Conversation

pacrob
Copy link
Contributor

@pacrob pacrob commented Aug 8, 2022

What was wrong?

function async_default_transaction_fields_middleware was using some non-asynced helper functions, so it wouldn't fill properly

How was it fixed?

added async versions of the helper functions

Todo:

Cute Animal Picture

image

@pacrob pacrob force-pushed the eth-tester-middleware-async-bug branch from 2873b4e to 1b42630 Compare August 8, 2022 21:57
@pacrob pacrob requested review from fselmo and kclowes August 8, 2022 22:08
@pacrob pacrob changed the title fix bug in how eth_tester middleware filled default fields fix bug in how eth_tester_middleware filled default fields Aug 8, 2022
Copy link
Collaborator

@fselmo fselmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked too deep here yet but right away I returned all of the code in web3/providers/eth_tester/middleware.py to what it is in master and all the tests pass, including the ones added in this PR.

Let's try to create a test (or a few) that fail(s) without the changes in the PR but passes with the changes.

@pacrob pacrob force-pushed the eth-tester-middleware-async-bug branch 2 times, most recently from b892b22 to 0007a9e Compare August 10, 2022 20:36
@pacrob
Copy link
Contributor Author

pacrob commented Aug 10, 2022

Updated tests so they now fail on the old code. I tried various ways of patching the w3 instance but couldn't make anything work, so went with Mock instead.

One question/point for discussion - the guess_from functions try to fill the from field, but don't make any noise if they can't. Should they?

@pacrob pacrob force-pushed the eth-tester-middleware-async-bug branch from b1d0653 to a73d185 Compare August 11, 2022 19:47
Copy link
Collaborator

@fselmo fselmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch and fix 👌🏼 ... I had a few nits, mostly just on conventions. I'll approve since the fix is in there though 👍🏼. I'm good with the mocking too.

As far as not making any noise when it cannot fill the fields... it looks like we purposefully return None if that's the case. I'd leave it for now as this seems more of a helper middleware, to make communicating with eth-tester a bit easier, than it seems a validation type middleware.

@@ -340,6 +346,18 @@ def fill_default(
return assoc(transaction, field, guess_val)


@curry
async def async_fill_default(
field: str, guess_func: Callable[..., Any], w3: "Web3", transaction: TxParams
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: w3 -> async_w3 for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -363,15 +381,17 @@ def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:


async def async_default_transaction_fields_middleware(
make_request: Callable[[RPCEndpoint, Any], Any], web3: "Web3"
make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: w3 -> async_w3 for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

filled_transaction[0].pop("from", None)
assert filled_transaction[0] == base_params


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I've been separating async from sync tests with:

def test_last_sync_test_here():
    ...
    

# -- async -- #


@pytest.mark.asyncio
async def test_async_first_async_test_here():
    ...

With sync and async tests that exist in the same file I'd like to organize them somehow for quicker / easier readability. Since that convention has been used in quite a few places already I'm partial to it 😄 .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check

@@ -20,3 +27,157 @@ def test_get_block_formatters(w3):
keys_diff = all_block_keys.difference(latest_block_keys)
assert len(keys_diff) == 1
assert keys_diff.pop() == "mixHash" # mixHash is not implemented in eth-tester


sample_address_1 = "0x0000000000000000000000000000000000000001"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Let's have these as capitalized and near the top of the file just to stick with python convention, especially since sync and async both use these values.

from some_module import last_import_statement

SAMPLE_ADDRESS_1 = "0x0000000000000000000000000000000000000001"
SAMPLE_ADDRESS_2 = "0x0000000000000000000000000000000000000002"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check

def test_default_transaction_fields_middleware(
w3_accounts, w3_coinbase, method, from_field_added, from_field_value
):
w3_accounts = [w3_accounts]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of re-defining the variable here, I think we should either make the mock return the list with a variable more appropriately named w3_account (singular):

mock_w3.eth.accounts = [w3_account]  # and the variable is renamed to w3_account (singular)

# async:
async def mock_async_accounts():
    return [w3_account]  # singular

or... we can just pass in a list of accounts into the tests themselves and keep the variable as w3_accounts (plural). I vote this option and we can change one of the tests to return more than one account in the list to make sure that works as intended as well... I believe it always returns accounts[0].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to have the mock return what the function normally would. I've updated the sample address constants accordingly. It will still only ever choose index 0 of the list of addresses though, as that's how the guess_from function is written.

@pacrob pacrob force-pushed the eth-tester-middleware-async-bug branch 2 times, most recently from 2bd1b0c to 31cb191 Compare August 19, 2022 21:52
@pacrob pacrob force-pushed the eth-tester-middleware-async-bug branch from 31cb191 to 3b1870a Compare August 19, 2022 22:01
Copy link
Collaborator

@kclowes kclowes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚢

@pacrob pacrob merged commit 258292f into ethereum:master Aug 22, 2022
@pacrob pacrob deleted the eth-tester-middleware-async-bug branch August 22, 2022 16:26
pacrob pushed a commit to pacrob/web3.py that referenced this pull request Sep 8, 2022
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 this pull request may close these issues.

3 participants