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

EIP 1052 EXTCODEHASH #326

Merged
merged 1 commit into from
Nov 16, 2018
Merged

EIP 1052 EXTCODEHASH #326

merged 1 commit into from
Nov 16, 2018

Conversation

jwasinger
Copy link
Contributor

@jwasinger jwasinger commented Jul 30, 2018

Closes #357.

lib/opFns.js Outdated Show resolved Hide resolved
lib/opFns.js Outdated
stateManager.getContractCode(address, function (err, code) {

if (runState._precompiled[address.toString('hex')]) {
cb(null, new BN(0))
Copy link
Member

Choose a reason for hiding this comment

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

If non-existent account has a result 0, while empty code has the empty keccak256, why is the hash of the precompile 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.

I would think that this is a way to signal that the contract shouldn't be calling EXTCODEHASH on a precompile address.

Copy link
Contributor Author

@jwasinger jwasinger Jul 30, 2018

Choose a reason for hiding this comment

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

I can see how this would be confusing behavior. maybe the result of calling EXTCODEHASH on a precompile should be KECCAK256_NULL

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 it should be the empty code hash for precompiles, since the account does exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay. It seems Geth is the only client that has implemented this EIP so I will look over the behavior there.

lib/opFns.js Outdated Show resolved Hide resolved
lib/opFns.js Show resolved Hide resolved
@coveralls
Copy link

coveralls commented Aug 3, 2018

Coverage Status

Coverage decreased (-0.6%) to 90.405% when pulling 45f1ef8 on eip-1052 into fca78fc on master.

lib/opFns.js Outdated Show resolved Hide resolved
@holgerd77
Copy link
Member

Rebased this to latest master.

@holgerd77
Copy link
Member

What is the status of this?

@holgerd77
Copy link
Member

Current state here: tests from ethereum/tests#484 are not yet merged, so test result stays the same.

@5chdn
Copy link

5chdn commented Nov 14, 2018

What's the status of this?

@holgerd77
Copy link
Member

@5chdn I will today do a new release on the ethereum/tests library including the first EXTCODEHASH consensus tests and then directly update our proxy testing library ethereumjs-testing to have tests for this.

We should then be able to complete here within a week or so and hopefully do a release at the end of next week of we are lucky (this also depends on 1-2 other outstanding changes).

Out of interest: what is your connection on (need for) this?

@5chdn
Copy link

5chdn commented Nov 14, 2018

Out of interest: what is your connection on (need for) this?

I just checked all clients in the tracker against Constantinople readiness and this is the last open PR. :)

No pressure :)

@holgerd77
Copy link
Member

Rebased this, this will now run some initial EXTCODEHASH tests from #387.

@holgerd77
Copy link
Member

Results in:

ok 770 the state roots should match
# file: extCodeHashCALL test: extCodeHashCALL
/home/circleci/project/ethereumjs-vm/dist/runCode.js:243
          throw e;
          ^

TypeError: stateManager.exists is not a function
    at EXTCODEHASH (/home/circleci/project/ethereumjs-vm/dist/opFns.js:304:18)
    at runOp (/home/circleci/project/ethereumjs-vm/dist/runCode.js:237:27)
    at /home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:3880:24
    at replenish (/home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:1011:17)
    at /home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:1016:9
    at eachOfLimit (/home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:1041:24)
    at /home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:1046:16
    at _parallel (/home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:3879:5)
    at Object.series (/home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:4735:5)
    at iterateVm (/home/circleci/project/ethereumjs-vm/dist/runCode.js:138:11)
    at next (/home/circleci/project/ethereumjs-vm/node_modules/async/dist/async.js:5223:28)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)

@holgerd77
Copy link
Member

Rebased this.

@rmeissner
Copy link
Contributor

I would love to take a closer look on this if nobody else is working on it :)

Also on another note I found some weird behaviour with --jsontrace. I found a test where it fails if I use --jsontrace, but passes if I don't use it.

node ./tests/tester -s --fork='Constantinople' --test='extCodeHashDynamicArgument' --data=0 --gas=0 --value=0

TAP version 13
# GeneralStateTests
# file: extCodeHashDynamicArgument test: extCodeHashDynamicArgument
ok 1 the state roots should match

1..1
# tests 1
# pass  1

# ok

vs

node ./tests/tester -s --fork='Constantinople' --test='extCodeHashDynamicArgument' --data=0 --gas=0 --value=0 --jsontrace

TAP version 13
# GeneralStateTests
# file: extCodeHashDynamicArgument test: extCodeHashDynamicArgument
# {"pc":0,"op":96,"gas":"0x5c7b8","gasCost":"0x3","stack":[],"depth":0,"opName":"PUSH1"}
# {"pc":2,"op":53,"gas":"0x5c7b5","gasCost":"0x3","stack":["0x0"],"depth":0,"opName":"CALLDATALOAD"}
# {"pc":3,"op":63,"gas":"0x5c7b2","gasCost":"0x190","stack":["0x1"],"depth":0,"opName":"EXTCODEHASH"}
# {"pc":4,"op":96,"gas":"0x5c622","gasCost":"0x3","stack":["0x0"],"depth":0,"opName":"PUSH1"}
# {"pc":6,"op":85,"gas":"0x5c61f","gasCost":"0x0","stack":["0x0","0x0"],"depth":0,"opName":"SSTORE"}
# {"pc":7,"op":96,"gas":"0x5b297","gasCost":"0x3","stack":[],"depth":0,"opName":"PUSH1"}
# {"pc":9,"op":53,"gas":"0x5b294","gasCost":"0x3","stack":["0x0"],"depth":0,"opName":"CALLDATALOAD"}
# {"pc":10,"op":59,"gas":"0x5b291","gasCost":"0x2bc","stack":["0x1"],"depth":0,"opName":"EXTCODESIZE"}
# {"pc":11,"op":96,"gas":"0x5afd5","gasCost":"0x3","stack":["0x0"],"depth":0,"opName":"PUSH1"}
# {"pc":13,"op":85,"gas":"0x5afd2","gasCost":"0x0","stack":["0x0","0x1"],"depth":0,"opName":"SSTORE"}
not ok 1 the state roots should match
  ---
    operator: equal
    expected: |-
      '2ceab025ea1bcf156d3b82dcd37082bbd7550c50933057550a55a7dce4c06df0'
    actual: |-
      'dfbd02fee291d961905b27a5b42838a7c946fb89514534217e6bb3344d2dad71'
    at: replenish (/Users/rimeissner/gnosis/ethereumjs-vm/node_modules/async/dist/async.js:1011:17)
  ...

1..1
# tests 1
# pass  0
# fail  1

Is this known or should I open an issue?

@holgerd77
Copy link
Member

@rmeissner Feel free, that would be great! 😄

jsontrace: This is not known and you should open an issue.

@holgerd77
Copy link
Member

Side-note: I am currently targeting a VM release mid or end of next week.

if (err) return cb(err)
if (!exists) {
return cb(null, new BN(0))
}
Copy link
Member

Choose a reason for hiding this comment

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

Hi @mattdean-digicatapult, short note: what occurred to mean when having a short look on how to update here regarding StateManager: we should make it clear in the docs especially for the the get* methods (so getAccount, getContractStorage,...) what the behavior is when called on a non-existing account (will it throw or not, what is returned).

Think it would also not be overblown to have additional test cases for that. If you don't want to do yourself you can also alternatively open an issue on that.

Copy link
Contributor

Choose a reason for hiding this comment

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

No problem, I've started working a bit on the documentation so I'll make that clear. If I find too many inconsistencies for the missing values I might make some changes as well.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks. 😀

@rmeissner
Copy link
Contributor

rmeissner commented Nov 15, 2018

I removed the check for precompiles, because this is what I saw when I looked at go-ethereum, also this seems to be satisfying the tests :D

Also right now I use the Account.isEmpty() to check if an account exists. The tests pass, but I am not sure if that is the most correct way.

@axic axic removed their assignment Nov 16, 2018
@axic
Copy link
Member

axic commented Nov 16, 2018

Can some of these commits be squashed?

@holgerd77
Copy link
Member

Whew, just 1 (!) failing test on the Constantinople test run, how amazing is that?? 🥂 😄

@holgerd77
Copy link
Member

@axic I think actually all. @rmeissner can you do that?

lib/opFns.js Outdated Show resolved Hide resolved
add EXTCODEHASH rules for nonexistent accounts and precompiles

.

Replace removed state manager method

Fix lint
Copy link
Member

@holgerd77 holgerd77 left a comment

Choose a reason for hiding this comment

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

Looks good now, thanks!

@holgerd77 holgerd77 merged commit 839417d into master Nov 16, 2018
@holgerd77 holgerd77 deleted the eip-1052 branch November 16, 2018 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Constantinople] EIP 1052 EXTCODEHASH Opcode
8 participants