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

core, tests: implement Metropolis EIP 684 #15039

Merged
merged 1 commit into from Aug 25, 2017

Conversation

Projects
None yet
3 participants
@karalabe
Member

karalabe commented Aug 25, 2017

Implements ethereum/EIPs#684.

Note, this PR is retroactively activated for all past transactions too. Please take care reviewing it.

@karalabe karalabe added the metropolis label Aug 25, 2017

@karalabe karalabe added this to the 1.7.0 milestone Aug 25, 2017

@karalabe karalabe requested a review from holiman Aug 25, 2017

Show outdated Hide outdated core/vm/evm.go
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
contractHash := evm.StateDB.GetCodeHash(contractAddr)
if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {

This comment has been minimized.

@fjl

fjl Aug 25, 2017

Contributor

Why is this not env.StateDB.Exist?

@fjl

fjl Aug 25, 2017

Contributor

Why is this not env.StateDB.Exist?

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

That results in a lot of test failures.

@karalabe

karalabe Aug 25, 2017

Member

That results in a lot of test failures.

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

I'm guessing it's some complexity with suicides within create.

@karalabe

karalabe Aug 25, 2017

Member

I'm guessing it's some complexity with suicides within create.

This comment has been minimized.

@fjl

fjl Aug 25, 2017

Contributor

Does it work with !env.StateDB.Empty(contractAddr)? Trying to avoid the complicated condition here.

@fjl

fjl Aug 25, 2017

Contributor

Does it work with !env.StateDB.Empty(contractAddr)? Trying to avoid the complicated condition here.

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

Empty also requires balance == 0. That's not the case here, balance is allowed to be > 0.

@karalabe

karalabe Aug 25, 2017

Member

Empty also requires balance == 0. That's not the case here, balance is allowed to be > 0.

This comment has been minimized.

@fjl

fjl Aug 25, 2017

Contributor

right

@fjl

fjl Aug 25, 2017

Contributor

right

contractAddr = crypto.CreateAddress(caller.Address(), nonce)
contractHash := evm.StateDB.GetCodeHash(contractAddr)
if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {

This comment has been minimized.

@holiman

holiman Aug 25, 2017

Contributor

If you check the nonce first, you may not even need to get the contractHash from the db.

@holiman

holiman Aug 25, 2017

Contributor

If you check the nonce first, you may not even need to get the contractHash from the db.

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

Well, true, but the nonce and hash retrieval should cost the same. I.e. retrieving the nonce pulls in the account node from the trie, which also contains the contract hash, so it shouldn't matter much. But that's just my 2c.

@karalabe

karalabe Aug 25, 2017

Member

Well, true, but the nonce and hash retrieval should cost the same. I.e. retrieving the nonce pulls in the account node from the trie, which also contains the contract hash, so it shouldn't matter much. But that's just my 2c.

This comment has been minimized.

@holiman

holiman Aug 25, 2017

Contributor

Still, I prefer the less assuming kind of defensive programming:

	contractAddr = crypto.CreateAddress(caller.Address(), nonce)

	if existingHash := evm.StateDB.GetCodeHash(contractAddr); (existingHash != (common.Hash{}) && existingHash != emptyCodeHash) {
		if evm.StateDB.GetNonce(contractAddr) != 0 {
			return nil, common.Address{}, 0, ErrContractAddressCollision
		}
	}

But I can live with it anyway...

@holiman

holiman Aug 25, 2017

Contributor

Still, I prefer the less assuming kind of defensive programming:

	contractAddr = crypto.CreateAddress(caller.Address(), nonce)

	if existingHash := evm.StateDB.GetCodeHash(contractAddr); (existingHash != (common.Hash{}) && existingHash != emptyCodeHash) {
		if evm.StateDB.GetNonce(contractAddr) != 0 {
			return nil, common.Address{}, 0, ErrContractAddressCollision
		}
	}

But I can live with it anyway...

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

It's a bit messier than that. Your code requires both the nonce and the code hash to be zero for the error to trigger. The true intent is either cases triggers it.

@karalabe

karalabe Aug 25, 2017

Member

It's a bit messier than that. Your code requires both the nonce and the code hash to be zero for the error to trigger. The true intent is either cases triggers it.

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

But yeah, I do see your point.

@karalabe

karalabe Aug 25, 2017

Member

But yeah, I do see your point.

contractAddr = crypto.CreateAddress(caller.Address(), nonce)
contractHash := evm.StateDB.GetCodeHash(contractAddr)
if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
return nil, common.Address{}, 0, ErrContractAddressCollision

This comment has been minimized.

@holiman

holiman Aug 25, 2017

Contributor

At this point, the caller nonce is already incremented. Is that correct behaviour? Just want to double-check.

@holiman

holiman Aug 25, 2017

Contributor

At this point, the caller nonce is already incremented. Is that correct behaviour? Just want to double-check.

This comment has been minimized.

@holiman

holiman Aug 25, 2017

Contributor

in exactly the same way as it would fail if the sender address did not have enough balance to create the contract with the given initial wei value.

Sounds like not incrementing nonce (?)

@holiman

holiman Aug 25, 2017

Contributor

in exactly the same way as it would fail if the sender address did not have enough balance to create the contract with the given initial wei value.

Sounds like not incrementing nonce (?)

This comment has been minimized.

@karalabe

karalabe Aug 25, 2017

Member

Well yes, but the nonce is retrieved already in nonce. If you're asking whether a failure should increment the nonce or not, currently the tests expect it incremented. Not incrementing it would mean that Create transactions might have a new invalidity possibility which the txpool needs to handle.

@karalabe

karalabe Aug 25, 2017

Member

Well yes, but the nonce is retrieved already in nonce. If you're asking whether a failure should increment the nonce or not, currently the tests expect it incremented. Not incrementing it would mean that Create transactions might have a new invalidity possibility which the txpool needs to handle.

@fjl

fjl approved these changes Aug 25, 2017

@karalabe karalabe merged commit 9d0c51f into ethereum:master Aug 25, 2017

2 of 3 checks passed

continuous-integration/appveyor/pr AppVeyor build failed
Details
commit-message-check/gitcop All commit messages are valid
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment