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

Refactor to non-recursive solution for target block #78

Merged
merged 4 commits into from
Feb 17, 2020

Conversation

corydickson
Copy link
Contributor

What was wrong?

Issue #19

How was it fixed?

The approach laid out here attempts to reach the target block by measuring the time passed between initial block and the last block given. It is considerably slower than the recursive solution, though addresses the implementation concern. Most likely I'm missing something by not taking advantage of the fact we can look at the block in-between this initial range and search on a smaller set of inputs?

Cute Animal Picture

put a cute animal picture link inside the parentheses

@njgheorghita
Copy link
Contributor

@corydickson Thanks for the pr! The broken tests are b/c of web3's latest update - I've got a fix coming soon that should solve them

@njgheorghita
Copy link
Contributor

Fix is in - if you rebase against master that should clear up the failing tests

@corydickson
Copy link
Contributor Author

corydickson commented Feb 6, 2020

@njgheorghita Thank you, tho I'm having trouble reproducing the failure in the latest build above to fix

============================================================================================ slowest 10 test durations =============================================================================================
53.84s call     tests/core/test_scraper.py::test_scraper_imports_existing_ethpmcli_dir
41.02s call     tests/core/test_scraper.py::test_scraper_writes_to_disk
26.66s call     tests/core/test_scraper.py::test_get_ethpm_birth_block[4000]
17.98s call     tests/cli/test_registry_cli.py::test_ethpm_registry_commands
13.51s call     tests/cli/test_activate.py::test_activate_etherscan_uri_with_single_deployment
12.91s call     tests/cli/test_install_cli.py::test_ethpm_install_from_etherscan
11.90s call     tests/cli/test_activate.py::test_activate_ipfs_uri_with_factories_and_deployments
10.51s call     tests/cli/test_activate.py::test_activate_registry_uri_with_contract_types_no_deployments
7.12s call     tests/core/test_install.py::test_uninstall_packages[owned-wallet]
6.97s call     tests/core/test_install.py::test_install_multiple_packages
==================================================================================== 120 passed, 1 warning in 627.24s (0:10:27) ==================================================================================== 

delta_end = version_release_date - to_date
delta_mid = version_release_date - mid_date

min_delta = min(delta_mid.days, delta_start.days, abs(delta_end.days))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little confused by what's going on here. Wouldn't the min_delta always be delta_end.days?

It also seems that adjusting the hunt for the next block by one is going to take a looong time. I'd try looking at this and see if you can get some better performance by following that pattern.

Copy link
Contributor Author

@corydickson corydickson Feb 10, 2020

Choose a reason for hiding this comment

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

You're right, thanks for that resource. I see now that you have to update the range you're looking at for each iteration 😓

@@ -166,6 +166,8 @@ def test_get_ethpm_birth_block(w3, interval):
time_travel(w3, interval)
actual = get_ethpm_birth_block(w3, 0, w3.eth.blockNumber, latest_block.timestamp)
assert actual == latest_block.number - 1
# Not found
assert get_ethpm_birth_block(w3, 0, 0, latest_block.timestamp) == -1
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hope it's okay to add this to the existing test instead of a separate function even though it's no longer looking at only valid intervals

Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be better if it went in its own test - testing that it raises an exception (a la piper's comment). In most cases, it's better to separate testing concerns into as many functions as necessary rather than squeezing them into a single test (though I'm definitely guilty of this also)

@corydickson
Copy link
Contributor Author

Thank you for the swift review @njgheorghita ! Let me know if you'd like me to squash the previous commits if things look good

from_block = mid + 1
else:
return mid - 1
return -1
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be an exception case since otherwise it requires checking the return value which is an antipattern since it is easy to forget to do.

get_ethpm_birth_block(w3, 0, w3.eth.blockNumber, latest_block.timestamp)
with pytest.raises(BlockNotFoundError):
time_travel(w3, 1)
get_ethpm_birth_block(w3, w3.eth.blockNumber, 0, latest_block.timestamp)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For when the to_block is strictly larger than the from_block

Copy link
Contributor

Choose a reason for hiding this comment

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

cool! notes like this are definitely worth a comment in the code - and honestly it might be better off as a separate test - then in the test name you can explain what's going on

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, still trying to discern when it's bloat and when it's appropriate for clarity. Any rule of thumbs you use?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm, imo with tests bloat is not such a big concern, I tend to default to the more tests the better. It's good to have only one specific cause/effect being tested per test. We like to use @pytest.mark.parametrize (example) a lot which helps improve the testing quality while reducing bloat. ping @pipermerriam for thoughts

Copy link
Contributor

@njgheorghita njgheorghita left a comment

Choose a reason for hiding this comment

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

Thanks! and ughh these cli tests are so flaky - they're working fine locally, so my guess is there's something funky b/w infura requests and circle.

@corydickson
Copy link
Contributor Author

@pipermerriam @njgheorghita Thank you both learned a lot !

Seperate test functions for different exception cases
@njgheorghita njgheorghita merged commit 21f6b19 into ethpm:master Feb 17, 2020
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