Persist address ans slot warmth in CREATE[2] calls. (#1468)

The warm address/slot data was not returned to the calling messageFrame
for CREATE[2] calls as it was for CALL series calls.

Also, improve performance by using more efficient copy constructors and
reusing objects were relevant.

Signed-off-by: Danno Ferrin <danno.ferrin@gmail.com>
pull/1482/head
Danno Ferrin 4 years ago committed by GitHub
parent 15d1789689
commit 43abf832ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/AbstractCallOperation.java
  2. 17
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java
  3. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/AbstractCreateOperation.java

@ -213,7 +213,7 @@ public abstract class AbstractCallOperation extends AbstractOperation {
.returnStack(frame.getReturnStack()) .returnStack(frame.getReturnStack())
.build(); .build();
frame.incrementRemainingGas(cost); frame.incrementRemainingGas(cost);
childFrame.mergeWarmedUpFields(frame); childFrame.copyWarmedUpFields(frame);
frame.getMessageFrameStack().addFirst(childFrame); frame.getMessageFrameStack().addFirst(childFrame);
frame.setState(MessageFrame.State.CODE_SUSPENDED); frame.setState(MessageFrame.State.CODE_SUSPENDED);

@ -214,8 +214,8 @@ public class MessageFrame {
private Gas gasRefund; private Gas gasRefund;
private final Set<Address> selfDestructs; private final Set<Address> selfDestructs;
private final Map<Address, Wei> refunds; private final Map<Address, Wei> refunds;
private final Set<Address> warmedUpAddresses; private Set<Address> warmedUpAddresses;
private final Multimap<Address, Bytes32> warmedUpStorage; private Multimap<Address, Bytes32> warmedUpStorage;
// Execution Environment fields. // Execution Environment fields.
private final Address recipient; private final Address recipient;
@ -858,13 +858,22 @@ public class MessageFrame {
return !warmedUpStorage.put(address, 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) { public void mergeWarmedUpFields(final MessageFrame childFrame) {
if (childFrame == this) { if (childFrame == this) {
return; return;
} }
warmedUpAddresses.addAll(childFrame.warmedUpAddresses); warmedUpAddresses = childFrame.warmedUpAddresses;
warmedUpStorage.putAll(childFrame.warmedUpStorage); warmedUpStorage = childFrame.warmedUpStorage;
} }
/** /**

@ -149,7 +149,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
.build(); .build();
frame.incrementRemainingGas(cost); frame.incrementRemainingGas(cost);
childFrame.mergeWarmedUpFields(frame); childFrame.copyWarmedUpFields(frame);
frame.getMessageFrameStack().addFirst(childFrame); frame.getMessageFrameStack().addFirst(childFrame);
frame.setState(MessageFrame.State.CODE_SUSPENDED); frame.setState(MessageFrame.State.CODE_SUSPENDED);
@ -165,6 +165,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
frame.popStackItems(getStackItemsConsumed()); frame.popStackItems(getStackItemsConsumed());
if (childFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { if (childFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) {
frame.mergeWarmedUpFields(childFrame);
frame.pushStackItem(Words.fromAddress(childFrame.getContractAddress())); frame.pushStackItem(Words.fromAddress(childFrame.getContractAddress()));
} else { } else {
frame.setReturnData(childFrame.getOutputData()); frame.setReturnData(childFrame.getOutputData());

Loading…
Cancel
Save