diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/AbstractCallOperation.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/AbstractCallOperation.java index 11f662eec76..a65fa330ecd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/AbstractCallOperation.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/AbstractCallOperation.java @@ -213,7 +213,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { .returnStack(frame.getReturnStack()) .build(); frame.incrementRemainingGas(cost); - childFrame.mergeWarmedUpFields(frame); + childFrame.copyWarmedUpFields(frame); frame.getMessageFrameStack().addFirst(childFrame); frame.setState(MessageFrame.State.CODE_SUSPENDED); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java index 517c0283f8e..442885b0ae3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java @@ -214,8 +214,8 @@ public enum Type { private Gas gasRefund; private final Set
selfDestructs; private final Map refunds; - private final Set
warmedUpAddresses; - private final Multimap warmedUpStorage; + private Set
warmedUpAddresses; + private Multimap warmedUpStorage; // Execution Environment fields. private final Address recipient; @@ -858,13 +858,22 @@ public boolean warmUpStorage(final Address address, final Bytes32 slot) { return !warmedUpStorage.put(address, slot); } + public void copyWarmedUpFields(final MessageFrame parentFrame) { + if (parentFrame == this) { + return; + } + + warmedUpAddresses = new HashSet<>(parentFrame.warmedUpAddresses); + warmedUpStorage = HashMultimap.create(parentFrame.warmedUpStorage); + } + public void mergeWarmedUpFields(final MessageFrame childFrame) { if (childFrame == this) { return; } - warmedUpAddresses.addAll(childFrame.warmedUpAddresses); - warmedUpStorage.putAll(childFrame.warmedUpStorage); + warmedUpAddresses = childFrame.warmedUpAddresses; + warmedUpStorage = childFrame.warmedUpStorage; } /** diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/AbstractCreateOperation.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/AbstractCreateOperation.java index 794f1c09e51..0296b2d0a13 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/AbstractCreateOperation.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/AbstractCreateOperation.java @@ -149,7 +149,7 @@ private void spawnChildMessage(final MessageFrame frame) { .build(); frame.incrementRemainingGas(cost); - childFrame.mergeWarmedUpFields(frame); + childFrame.copyWarmedUpFields(frame); frame.getMessageFrameStack().addFirst(childFrame); frame.setState(MessageFrame.State.CODE_SUSPENDED); @@ -165,6 +165,7 @@ private void complete(final MessageFrame frame, final MessageFrame childFrame) { frame.popStackItems(getStackItemsConsumed()); if (childFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { + frame.mergeWarmedUpFields(childFrame); frame.pushStackItem(Words.fromAddress(childFrame.getContractAddress())); } else { frame.setReturnData(childFrame.getOutputData());