From 1855836206fde6a31ba6b838428b97dd8bb9a220 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 9 Dec 2024 04:33:18 +0700 Subject: [PATCH] Update EOFCREATE memory code (#7979) * Update EOFCREATE memory code Switch to longs so EOFCREATE can handle gigagas sized transactions. Signed-off-by: Danno Ferrin --- .../operation/AbstractCreateOperation.java | 15 ++++++--- .../operation/AbstractExtCallOperation.java | 32 ++++++++++++------- .../evm/operation/EOFCreateOperation.java | 14 ++++++-- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index 5d9bea61ce0..a7977491af6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.evm.operation; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; -import static org.hyperledger.besu.evm.operation.AbstractCallOperation.LEGACY_FAILURE_STACK_ITEM; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; @@ -158,12 +157,18 @@ protected int getPcIncrement() { */ protected abstract Code getInitCode(MessageFrame frame, EVM evm); - private void fail(final MessageFrame frame) { + /** + * Handles stack items when operation fails for validation reasons (noe enough ether, bad eof + * code) + * + * @param frame the current execution frame + */ + protected void fail(final MessageFrame frame) { final long inputOffset = clampedToLong(frame.getStackItem(1)); final long inputSize = clampedToLong(frame.getStackItem(2)); frame.readMutableMemory(inputOffset, inputSize); frame.popStackItems(getStackItemsConsumed()); - frame.pushStackItem(LEGACY_FAILURE_STACK_ITEM); + frame.pushStackItem(Bytes.EMPTY); } private void spawnChildMessage(final MessageFrame parent, final Code code, final EVM evm) { @@ -227,12 +232,12 @@ private void complete(final MessageFrame frame, final MessageFrame childFrame, f } else { frame.getWorldUpdater().deleteAccount(childFrame.getRecipientAddress()); frame.setReturnData(childFrame.getOutputData()); - frame.pushStackItem(LEGACY_FAILURE_STACK_ITEM); + frame.pushStackItem(Bytes.EMPTY); onInvalid(frame, (CodeInvalid) outputCode); } } else { frame.setReturnData(childFrame.getOutputData()); - frame.pushStackItem(LEGACY_FAILURE_STACK_ITEM); + frame.pushStackItem(Bytes.EMPTY); onFailure(frame, childFrame.getExceptionalHaltReason()); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java index 7a0296bf56e..5f6c70eb668 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.evm.operation; +import static org.hyperledger.besu.evm.internal.Words.clampedAdd; import static org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper.deductDelegatedCodeGasCost; import org.hyperledger.besu.datatypes.Address; @@ -116,9 +117,11 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { } if (toBytes.size() > Address.SIZE) { return new OperationResult( - gasCalculator.memoryExpansionGasCost(frame, inputOffset, inputLength) - + (zeroValue ? 0 : gasCalculator.callValueTransferGasCost()) - + gasCalculator.getColdAccountAccessCost(), + clampedAdd( + clampedAdd( + gasCalculator.memoryExpansionGasCost(frame, inputOffset, inputLength), + (zeroValue ? 0 : gasCalculator.callValueTransferGasCost())), + gasCalculator.getColdAccountAccessCost()), ExceptionalHaltReason.ADDRESS_OUT_OF_RANGE); } Address to = Words.toAddress(toBytes); @@ -135,16 +138,21 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { boolean accountCreation = contract == null && !zeroValue; long cost = - gasCalculator.memoryExpansionGasCost(frame, inputOffset, inputLength) - + (zeroValue ? 0 : gasCalculator.callValueTransferGasCost()) - + (frame.warmUpAddress(to) || gasCalculator.isPrecompile(to) - ? gasCalculator.getWarmStorageReadCost() - : gasCalculator.getColdAccountAccessCost()) - + (accountCreation ? gasCalculator.newAccountGasCost() : 0); - long currentGas = frame.getRemainingGas() - cost; - if (currentGas < 0) { + clampedAdd( + clampedAdd( + clampedAdd( + gasCalculator.memoryExpansionGasCost(frame, inputOffset, inputLength), + (zeroValue ? 0 : gasCalculator.callValueTransferGasCost())), + (frame.warmUpAddress(to) || gasCalculator.isPrecompile(to) + ? gasCalculator.getWarmStorageReadCost() + : gasCalculator.getColdAccountAccessCost())), + (accountCreation ? gasCalculator.newAccountGasCost() : 0)); + long currentGas = frame.getRemainingGas(); + if (currentGas < cost) { return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS); } + currentGas -= cost; + frame.expandMemory(inputOffset, inputLength); final Code code = contract == null @@ -202,7 +210,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { .build(); frame.setState(MessageFrame.State.CODE_SUSPENDED); - return new OperationResult(cost + childGas, null, 0); + return new OperationResult(clampedAdd(cost, childGas), null, 0); } private @Nonnull OperationResult softFailure(final MessageFrame frame, final long cost) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java index 3ea3ef1407f..7d3f10a0396 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java @@ -16,7 +16,6 @@ import static org.hyperledger.besu.crypto.Hash.keccak256; import static org.hyperledger.besu.evm.internal.Words.clampedAdd; -import static org.hyperledger.besu.evm.internal.Words.clampedToInt; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; import org.hyperledger.besu.datatypes.Address; @@ -49,8 +48,8 @@ public EOFCreateOperation(final GasCalculator gasCalculator) { @Override public long cost(final MessageFrame frame, final Supplier codeSupplier) { - final int inputOffset = clampedToInt(frame.getStackItem(2)); - final int inputSize = clampedToInt(frame.getStackItem(3)); + final long inputOffset = clampedToLong(frame.getStackItem(2)); + final long inputSize = clampedToLong(frame.getStackItem(3)); return clampedAdd( gasCalculator().memoryExpansionGasCost(frame, inputOffset, inputSize), clampedAdd( @@ -86,4 +85,13 @@ protected Bytes getInputData(final MessageFrame frame) { protected int getPcIncrement() { return 2; } + + @Override + protected void fail(final MessageFrame frame) { + final long inputOffset = clampedToLong(frame.getStackItem(2)); + final long inputSize = clampedToLong(frame.getStackItem(3)); + frame.readMutableMemory(inputOffset, inputSize); + frame.popStackItems(getStackItemsConsumed()); + frame.pushStackItem(Bytes.EMPTY); + } }