diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java index f571ff2ff0..9f065aee98 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java @@ -128,7 +128,6 @@ public class UpdateTrackingAccount implements MutableAccount public void setWrappedAccount(final A account) { if (this.account == null) { this.account = account; - storageWasCleared = false; } else { throw new IllegalStateException("Already tracking a wrapped account"); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java index 9b57b6ab9e..4cbda73279 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; + /** * An object that buffers updates made over a particular {@link WorldView}. * @@ -73,8 +75,29 @@ public interface WorldUpdater extends MutableWorldView { * #createAccount(Address)} (and thus all his fields will be zero/empty). */ default MutableAccount getOrCreate(final Address address) { - final MutableAccount account = getAccount(address); - return account == null ? createAccount(address) : account; + MutableAccount account = getAccount(address); + if (account == null) { + account = createAccount(address); + if (parentUpdater().isPresent() && parentUpdater().get().isDeleted(address)) { + account.clearStorage(); + account.setCode(Bytes.EMPTY); + } + } + return account; + } + + /** + * Check this and parent updaters to see if an address has been deleted since the last persist + * + * @param address address to check + * @return true if any updaters have marked the address as deleted. + */ + default boolean isDeleted(final Address address) { + if (getDeletedAccountAddresses().contains(address)) { + return true; + } else { + return parentUpdater().map(wu -> wu.isDeleted(address)).orElse(false); + } } /**