diff options
author | Péter Szilágyi <peterke@gmail.com> | 2017-08-25 21:03:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-25 21:03:39 +0800 |
commit | 9d0c51fb0f9f4c2db02f12d485bb78f9c177b397 (patch) | |
tree | 8decfb111ffe4d1c409f56e2d0dd660f01e77e19 | |
parent | 27a5622e995d762683dd1a79423d83fcf3e62ccf (diff) | |
parent | 08f27428b4e97c339a220b7155ad13f4ef5a6767 (diff) | |
download | go-tangerine-9d0c51fb0f9f4c2db02f12d485bb78f9c177b397.tar.gz go-tangerine-9d0c51fb0f9f4c2db02f12d485bb78f9c177b397.tar.zst go-tangerine-9d0c51fb0f9f4c2db02f12d485bb78f9c177b397.zip |
Merge pull request #15039 from karalabe/metropolis-contract-clash
core, tests: implement Metropolis EIP 684
-rw-r--r-- | core/vm/errors.go | 11 | ||||
-rw-r--r-- | core/vm/evm.go | 14 | ||||
-rw-r--r-- | tests/state_test.go | 2 | ||||
m--------- | tests/testdata | 0 | ||||
-rw-r--r-- | tests/vm_test.go | 1 |
5 files changed, 17 insertions, 11 deletions
diff --git a/core/vm/errors.go b/core/vm/errors.go index 69c7d6a98..b19366be0 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -19,9 +19,10 @@ package vm import "errors" var ( - ErrOutOfGas = errors.New("out of gas") - ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") - ErrDepth = errors.New("max call depth exceeded") - ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") - ErrInsufficientBalance = errors.New("insufficient balance for transfer") + ErrOutOfGas = errors.New("out of gas") + ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") + ErrDepth = errors.New("max call depth exceeded") + ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") + ErrInsufficientBalance = errors.New("insufficient balance for transfer") + ErrContractAddressCollision = errors.New("contract address collision") ) diff --git a/core/vm/evm.go b/core/vm/evm.go index 34933a1dc..caf8b4507 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -25,6 +25,10 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// emptyCodeHash is used by create to ensure deployment is disallowed to already +// deployed contract addresses (relevant after the account abstraction). +var emptyCodeHash = crypto.Keccak256Hash(nil) + type ( CanTransferFunc func(StateDB, common.Address, *big.Int) bool TransferFunc func(StateDB, common.Address, common.Address, *big.Int) @@ -307,13 +311,17 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } - - // Create a new account on the state + // Ensure there's no existing contract already at the designated address nonce := evm.StateDB.GetNonce(caller.Address()) evm.StateDB.SetNonce(caller.Address(), nonce+1) - snapshot := evm.StateDB.Snapshot() 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 + } + // Create a new account on the state + snapshot := evm.StateDB.Snapshot() evm.StateDB.CreateAccount(contractAddr) if evm.ChainConfig().IsEIP158(evm.BlockNumber) { evm.StateDB.SetNonce(contractAddr, 1) diff --git a/tests/state_test.go b/tests/state_test.go index 00067c61a..3d7b29012 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -37,10 +37,8 @@ func TestState(t *testing.T) { // Expected failures: st.fails(`^stCodeSizeLimit/codesizeOOGInvalidSize\.json/(Frontier|Homestead|EIP150)`, "code size limit implementation is not conditional on fork") - st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/EIP15[08]/[67]`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test") st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test") - st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/Byzantium/[67]`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test") st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/Byzantium`, "bug in test") diff --git a/tests/testdata b/tests/testdata -Subproject cd2c3f1b3acb98c0d1501b06a4a54629d8794d7 +Subproject 1d30b4795664f64b1b157971754e14a10cfd911 diff --git a/tests/vm_test.go b/tests/vm_test.go index f35abeb11..c9f5e225e 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -27,7 +27,6 @@ func TestVM(t *testing.T) { vmt := new(testMatcher) vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution") - vmt.skipLoad(`^vmPerformanceTest.json`) // log format broken vmt.skipLoad(`^vmInputLimits(Light)?.json`) // log format broken vmt.skipShortMode("^vmPerformanceTest.json") |