From 80b8cd766980910184a21d8444dd0d44052d5670 Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Mon, 22 Apr 2024 17:31:34 +0200 Subject: [PATCH] add push modification Signed-off-by: Karim Taam --- .../java/org/hyperledger/besu/evm/EVM.java | 35 +---------------- .../gascalculator/FrontierGasCalculator.java | 11 ++++++ .../besu/evm/gascalculator/GasCalculator.java | 6 +++ .../gascalculator/ShanghaiGasCalculator.java | 33 ++++++++++++++++ .../besu/evm/operation/CodeSizeOperation.java | 14 ++++--- .../evm/operation/ExtCodeSizeOperation.java | 1 + .../besu/evm/operation/PushOperation.java | 38 +++++-------------- .../processor/ContractCreationProcessor.java | 1 + 8 files changed, 72 insertions(+), 67 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/EVM.java b/evm/src/main/java/org/hyperledger/besu/evm/EVM.java index ea490d9ff5..e440c6c9f9 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/EVM.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/EVM.java @@ -228,46 +228,12 @@ public class EVM { case 0x19 -> NotOperation.staticOperation(frame); case 0x1a -> ByteOperation.staticOperation(frame); case 0x50 -> PopOperation.staticOperation(frame); - case 0x56 -> JumpOperation.staticOperation(frame); case 0x57 -> JumpiOperation.staticOperation(frame); case 0x5b -> JumpDestOperation.JUMPDEST_SUCCESS; case 0x5f -> enableShanghai ? Push0Operation.staticOperation(frame) : InvalidOperation.INVALID_RESULT; - case 0x60, // PUSH1-32 - 0x61, - 0x62, - 0x63, - 0x64, - 0x65, - 0x66, - 0x67, - 0x68, - 0x69, - 0x6a, - 0x6b, - 0x6c, - 0x6d, - 0x6e, - 0x6f, - 0x70, - 0x71, - 0x72, - 0x73, - 0x74, - 0x75, - 0x76, - 0x77, - 0x78, - 0x79, - 0x7a, - 0x7b, - 0x7c, - 0x7d, - 0x7e, - 0x7f -> - PushOperation.staticOperation(frame, code, pc, opcode - PUSH_BASE); case 0x80, // DUP1-16 0x81, 0x82, @@ -312,6 +278,7 @@ public class EVM { } catch (final UnderflowException ue) { result = UNDERFLOW_RESPONSE; } + System.out.println("operation "+currentOperation.getName()+" "+result.getGasCost()+" "+frame.getRemainingGas()); final ExceptionalHaltReason haltReason = result.getHaltReason(); if (haltReason != null) { LOG.trace("MessageFrame evaluation halted because of {}", haltReason); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java index 859d3856d3..c174d5d48d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java @@ -229,6 +229,17 @@ public class FrontierGasCalculator implements GasCalculator { return NEW_ACCOUNT_GAS_COST; } + @Override + public long pushOperationGasCost( + final MessageFrame frame, final long codeOffset, final long readSize, final long codeSize) { + return getVeryLowTierGasCost(); + } + + @Override + public long extCodeSizeOperationGasCost(final MessageFrame frame) { + return getBaseTierGasCost(); + } + @SuppressWarnings("removal") @Override public long callOperationGasCost( diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java index 3ed7d79898..56d98760c3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java @@ -315,6 +315,11 @@ public interface GasCalculator { long codeCopyOperationGasCost( MessageFrame frame, long memOffset, long codeOffset, long readSize, final long codeSize); + long pushOperationGasCost(MessageFrame frame, long codeOffset, long readSize, long codeSize); + + + long extCodeSizeOperationGasCost(MessageFrame frame); + /** * Returns the cost of expanding memory for the specified access. * @@ -675,4 +680,5 @@ public interface GasCalculator { final MutableAccount sender) { return 0L; } + } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/ShanghaiGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/ShanghaiGasCalculator.java index 86c2ee033b..cdaa29a33a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/ShanghaiGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/ShanghaiGasCalculator.java @@ -290,6 +290,39 @@ public class ShanghaiGasCalculator extends LondonGasCalculator { return gasCost; } + @Override + public long pushOperationGasCost( + final MessageFrame frame, final long codeOffset, final long readSize, final long codeSize) { + long gasCost = super.pushOperationGasCost(frame, codeOffset, readSize, codeSize); + if (!frame.wasCreatedInTransaction(frame.getContractAddress())) { + gasCost = + clampedAdd( + gasCost, + frame + .getAccessWitness() + .touchCodeChunks(frame.getContractAddress(), codeOffset, readSize, codeSize)); + System.out.println("push "+isPrecompile(frame.getContractAddress())+" "+frame.getContractAddress()+" "+codeOffset+" "+readSize+" "+codeSize+" "+gasCost); + } + return gasCost; + } + + @Override + public long extCodeSizeOperationGasCost(final MessageFrame frame) { + if(!isPrecompile(frame.getContractAddress())) { + long gasCost = + frame + .getAccessWitness() + .touchAddressOnReadAndComputeGas(frame.getContractAddress(), UInt256.ZERO, VERSION_LEAF_KEY); + return + clampedAdd( + gasCost, + frame + .getAccessWitness() + .touchAddressOnReadAndComputeGas(frame.getContractAddress(), UInt256.ZERO, CODE_SIZE_LEAF_KEY)); + } + return 0; + } + @Override public long calculateStorageRefundAmount( final UInt256 newValue, diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeSizeOperation.java index 690b5692f8..3c1d0de7df 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeSizeOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.Words; /** The Code size operation. */ -public class CodeSizeOperation extends AbstractFixedCostOperation { +public class CodeSizeOperation extends AbstractOperation { /** * Instantiates a new Code size operation. @@ -29,15 +29,19 @@ public class CodeSizeOperation extends AbstractFixedCostOperation { * @param gasCalculator the gas calculator */ public CodeSizeOperation(final GasCalculator gasCalculator) { - super(0x38, "CODESIZE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x38, "CODESIZE", 0, 1, gasCalculator); } + protected long cost(final MessageFrame frame) { + return gasCalculator().extCodeSizeOperationGasCost(frame); + } + + @Override - public Operation.OperationResult executeFixedCostOperation( + public Operation.OperationResult execute( final MessageFrame frame, final EVM evm) { final Code code = frame.getCode(); frame.pushStackItem(Words.intBytes(code.getSize())); - - return successResponse; + return new OperationResult(cost(frame),null); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java index 9d891f7d37..81cde5ca79 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java @@ -64,6 +64,7 @@ public class ExtCodeSizeOperation extends AbstractOperation { final Account account = frame.getWorldUpdater().get(address); frame.pushStackItem( account == null ? Bytes.EMPTY : Words.intBytes(account.getCode().size())); + System.out.println("code size "+gasCalculator().isPrecompile(address)); return new OperationResult(cost, null); } } catch (final UnderflowException ufe) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/PushOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/PushOperation.java index 006956207b..34d22e0ea7 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/PushOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/PushOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.apache.tuweni.bytes.Bytes; /** The Push operation. */ -public class PushOperation extends AbstractFixedCostOperation { +public class PushOperation extends AbstractOperation { /** The constant PUSH_BASE. */ public static final int PUSH_BASE = 0x5F; @@ -31,9 +31,6 @@ public class PushOperation extends AbstractFixedCostOperation { private final int length; - /** The Push operation success result. */ - static final OperationResult pushSuccess = new OperationResult(3, null); - /** * Instantiates a new Push operation. * @@ -41,43 +38,28 @@ public class PushOperation extends AbstractFixedCostOperation { * @param gasCalculator the gas calculator */ public PushOperation(final int length, final GasCalculator gasCalculator) { - super( - PUSH_BASE + length, - "PUSH" + length, - 0, - 1, - gasCalculator, - gasCalculator.getVeryLowTierGasCost()); + super(PUSH_BASE + length, "PUSH" + length, 0, 1, gasCalculator); this.length = length; } @Override - public OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) { + public OperationResult execute(final MessageFrame frame, final EVM evm) { final byte[] code = frame.getCode().getBytes().toArrayUnsafe(); - return staticOperation(frame, code, frame.getPC(), length); - } + int pc = frame.getPC(); + - /** - * Performs Push operation. - * - * @param frame the frame - * @param code the code - * @param pc the pc - * @param pushSize the push size - * @return the operation result - */ - public static OperationResult staticOperation( - final MessageFrame frame, final byte[] code, final int pc, final int pushSize) { int copyStart = pc + 1; + + long gasCost = gasCalculator().pushOperationGasCost(frame, copyStart, length, code.length); Bytes push; if (code.length <= copyStart) { push = Bytes.EMPTY; } else { - final int copyLength = Math.min(pushSize, code.length - pc - 1); + final int copyLength = Math.min(length, code.length - pc - 1); push = Bytes.wrap(code, copyStart, copyLength); } frame.pushStackItem(push); - frame.setPC(pc + pushSize); - return pushSuccess; + frame.setPC(pc + length); + return new OperationResult(gasCost, null); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java b/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java index 480c7f103d..53a44041e2 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java @@ -107,6 +107,7 @@ public class ContractCreationProcessor extends AbstractMessageProcessor { LOG.trace("Executing contract-creation"); } try { + System.out.println("start contract creation "); final MutableAccount sender = frame.getWorldUpdater().getSenderAccount(frame); sender.decrementBalance(frame.getValue());