diff --git a/state/executor.go b/state/executor.go index 2e67829085..2b19c905e5 100644 --- a/state/executor.go +++ b/state/executor.go @@ -906,8 +906,11 @@ func (t *Transition) hasCodeOrNonce(addr types.Address) bool { } codeHash := t.state.GetCodeHash(addr) + // EIP-7610 change - rejects the contract deployment if the destination has non-empty storage. + storageRoot := t.state.GetStorageRoot(addr) - return codeHash != types.EmptyCodeHash && codeHash != types.ZeroHash + return (codeHash != types.EmptyCodeHash && codeHash != types.ZeroHash) || // non-empty code + (storageRoot != types.EmptyRootHash && storageRoot != types.ZeroHash) // non-empty storage } func (t *Transition) applyCreate(c *runtime.Contract, host runtime.Host) *runtime.ExecutionResult { diff --git a/state/txn.go b/state/txn.go index 168481d22c..bb6b8f3797 100644 --- a/state/txn.go +++ b/state/txn.go @@ -505,6 +505,17 @@ func (txn *Txn) GetCommittedState(addr types.Address, key types.Hash) types.Hash return txn.snapshot.GetStorage(addr, obj.Account.Root, key) } +// GetStorageRoot retrieves the storage root from the given address or empty +// if object not found. +func (txn *Txn) GetStorageRoot(addr types.Address) types.Hash { + obj, ok := txn.getStateObject(addr) + if !ok { + return types.Hash{} + } + + return obj.Account.Root +} + // SetFullStorage is used to replace the full state of the address. // Only used for debugging on the override jsonrpc endpoint. func (txn *Txn) SetFullStorage(addr types.Address, state map[types.Hash]types.Hash) { diff --git a/tests/tests b/tests/tests index 066a5878da..faf33b4714 160000 --- a/tests/tests +++ b/tests/tests @@ -1 +1 @@ -Subproject commit 066a5878da000bbf0ff95205c62a6c5c91ca6f52 +Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2