aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-08-25 17:30:51 +0800
committerPéter Szilágyi <peterke@gmail.com>2017-08-25 18:00:27 +0800
commit08f27428b4e97c339a220b7155ad13f4ef5a6767 (patch)
tree8decfb111ffe4d1c409f56e2d0dd660f01e77e19
parent27a5622e995d762683dd1a79423d83fcf3e62ccf (diff)
downloadgo-tangerine-08f27428b4e97c339a220b7155ad13f4ef5a6767.tar.gz
go-tangerine-08f27428b4e97c339a220b7155ad13f4ef5a6767.tar.zst
go-tangerine-08f27428b4e97c339a220b7155ad13f4ef5a6767.zip
core, tests: implement Metropolis EIP 684
-rw-r--r--core/vm/errors.go11
-rw-r--r--core/vm/evm.go14
-rw-r--r--tests/state_test.go2
m---------tests/testdata0
-rw-r--r--tests/vm_test.go1
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")