-
Notifications
You must be signed in to change notification settings - Fork 765
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
Remove contract specific commit #335
Conversation
Hi @mattdean-digicatapult, sorry, I am delayed on reviews due to personal reasons. I also think on this one, @jwasinger, @axic or @cdetrio would be more into the code base to do a review, maybe one of them is available? I would otherwise try to look into this asap, but also have some other time-critical things on the plate. |
np @holgerd77, I really only added you as a reviewer as I wasn't sure who would be best suited to look at this. I'm not going to be available to do further work on this next week anyway, so it can wait a bit. This change does highlight a potential bug in how we handle touched accounts though, so it would be good to work out which interpretation is correct and also whether a new test case would be appropriate. |
Hi @jwasinger, do you want to have a look if you can create such a new test case as described above (see Matthews introductory text)? |
Hi @mattdean-digicatapult, just to bring you up-to-date: just did a first review and had a look into the various code parts. I think I now have a rough understanding what was intended and what is going on, nevertheless I don't understand all the details yet and so don't dare yet to do a proper review, will continue on this in the upcoming days. Nevertheless my confidence in the code changes being consistent and generally making sense grew. 😄 I also ran the blockchain tests on this, outcome is the same (66 failing, far too much on a side note) as a test run (see #341) without the changes. |
Also includes removing concept that a contract `exists`
9e8f750
to
da81615
Compare
Good find @mattdean-digicatapult . If you want I can show you how to write test cases (we are looking for people to help with testing for the next hard fork). |
I can also look into seeing if we can get a bounty for this state test case once I confirm the bug from my side. |
@jwasinger, more than happy to learn how to write a test case for something like this. Some pointers on how to get started would be greatly appreciated |
Check out this guide: https://github.com/ewasm/tests/tree/wasm-tests/src/GeneralStateTestsFiller/stEWASMTests . Although it's for ewasm tests, the normal tests are developed the exact same way. Just omit compiling Hera and remove You will also need to change the code section. You can write code for tests using LLL, raw bytecode (hex string) or solidity assembly. I usually use LLL because that's what I'm familiar with. You will want a test with two pre-existing accounts: |
After, check to make sure the new test case fails on master (and passes on this PR). |
Wouldn't this make sense to integrate this in the general |
Yes |
@mattdean-digicatapult @holgerd77 I'm actually surprised that this is an undefined area of test coverage. If you read, https://eips.ethereum.org/EIPS/eip-161 , scroll to the bottom to find this:
So perhaps this was fixed in both clients but no one wrote tests for it? |
Thanks @jwasinger, give it a look. I'm not sure the logic of the test you describe quite covers the issue and I'm pretty sure I came across a test like that whilst working on this PR. I think the logic needs to be something like: Two pre-existing accounts A and B. Transaction to A. First, call B which succeeds. Next, call B which fails. At the end of the transaction B should not exist. My belief is that on master B will still exist as the touched set will have been emptied when the second call to B fails. I think the behaviour in this PR is the correct one but like I say, I'll give this a go and let you know if I run into any issues. |
Maybe this is covered in the blockchain tests and not the state tests? |
@holgerd77 could be. At this point, the state tests are a subset of blockchain tests (as state tests are converted to blockchain tests when a PR is made). |
@mattdean-digicatapult Ah okay. Will be interesting to see what the result is. Feel free to ping me over gitter if you run into any problems with the testing tooling. |
Regression test for [https://github.com/ethereumjs/ethereumjs-vm/pull/335](https://github.com/ethereumjs/ethereumjs-vm/pull/335] First call marks an empty account as touched. Second call errors OOG. Transaction should still cleanup empty account.
Regression test for [https://github.com/ethereumjs/ethereumjs-vm/pull/335](https://github.com/ethereumjs/ethereumjs-vm/pull/335] First call marks an empty account as touched. Second call errors OOG. Transaction should still cleanup empty account.
Regression test for [https://github.com/ethereumjs/ethereumjs-vm/pull/335](https://github.com/ethereumjs/ethereumjs-vm/pull/335] First call marks an empty account as touched. Second call errors OOG. Transaction should still cleanup empty account.
OK, I've had some success defining a test case. You'll find the new test in my fork of the ethereum/tests repo https://github.com/mattdean-digicatapult/tests/blob/add-new-touched-cleanup-case/src/GeneralStateTestsFiller/stEIP158Specific/callToEmptyThenCallErrorFiller.json. As expected this fails against ethereumjs-vm master but passes after these changes. I'm assuming the correct thing to do is to PR that new test prior to this being merged in? |
Wonderful! Thanks so much @mattdean-digicatapult |
Regression test for ethereumjs/ethereumjs-monorepo#335 First call marks an empty account as touched. Second call errors OOG. Transaction should still cleanup empty account.
Now the test has been merged is there anything else to do prior to this being merged? |
Hi @mattdean-digicatapult, cool, that you took on this! Will have a look during the week, I think this should be now ready for merge on first sight. We are not using the tests directly but through snapshots in the https://github.com/ethereumjs/ethereumjs-testing repository, so it's a bit off since this code will be run directly on the new tests, we are currently working to fix somewhat recent tests here (but not yet including your new test cases). We can nevertheless test-run/use your new cases manually, see the testing section in the Cheers |
If you run/ran your new tests on this, can you post your test results here? Then we have this explicitly documented. |
@holgerd77, I'm not sure precisely what you're after but I'll give it a go. To test I forked the testing repo and then updated the relevant references. When I then run the following:
On master I get
Whilst on my feature branch I get:
Essentially the execution is identical; the only difference being that with this change the first called account is considered |
Hi Matthew, ah yes, that's what I wanted to have documented here for future lookups of this PR, that the cases from the new test case are actually fixed with this PR, hope this didn't cause too much extra inconvenience. |
np, I already had it set up to do this from when I developed the test case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, will merge this after 24 hours wait period if no objection is coming from other reviewers or people watching this.
Hi @mattdean-digicatapult, thanks again for keeping this up so long, I really have a bad conscience here. I was somewhat completely away in the last weeks due to family reasons, but I am slowly getting back to work now and will take on being more responsive for stuff/work from you and give responses and reviews in a more timely fashion. |
This is part of the broader discussion in #268 and #309 so readers should probably start there.
This PR simplifies the
stateManager
interface by removing the two-phase commit that is exposed bystateManager
. In the old setup a contract account goes through an extra phase of commit/revert so as to cope with the consensus bug after EIP-161 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md). The aim here was to reproduce a behaviour whereby a precompiled contract is considered touched even in the case where an OOG error occurs. The new implementation introduces an explicit touch of a precompiled contract in the case of an OOG error inrunCall
and more closely matches the implementation used in other evm implementations. It also simplifies the interface ofstateManager
such that this behaviour does not have to be replicated in multiple places should other implementations be created as intended.This PR also includes removing concept that a contract
exists
, relying instead on the concept of the account beingempty
. I believe in the current EVMempty
-ness is the only concept that matters and so this change is broadly speaking just cleanup.Ideally this latter change would have been done as a separate PR, but it turns out that separating this from the first change is problematic due to what I believe is a bug in the handling of touched contracts. Essentially when an error occurs during a
CALL
we completely reset thetouched
account set to the empty set. This means that a previously touched account, perhaps from a previousCALL
, would now not be considered touched and would not be cleaned up if empty. The new implementation introduces atouched
stack so as to handle reverting thetouched
set as required. Worryingly state tests pass for both the old implementation and the new one, thus a new test case should probably be created to resolve the correct behaviour.