diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index e5152a25cc..2a8516c3c9 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -57,7 +57,7 @@ public class DebugOperationTracerTest { // @Mock private OperationTracer.ExecuteOperation executeOperationAction; private final Operation anOperation = - new AbstractOperation(0x02, "MUL", 2, 1, 1, null) { + new AbstractOperation(0x02, "MUL", 2, 1, null) { @Override public OperationResult execute(final MessageFrame frame, final EVM evm) { return new OperationResult(20L, null); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/operations/RelativeJumpOperationTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/operations/RelativeJumpOperationTest.java new file mode 100644 index 0000000000..c1bbc62d67 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/operations/RelativeJumpOperationTest.java @@ -0,0 +1,97 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.hyperledger.besu.ethereum.vm.operations; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; +import org.hyperledger.besu.evm.operation.Operation; +import org.hyperledger.besu.evm.operation.RelativeJumpIfOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpVectorOperation; + +import org.apache.tuweni.bytes.Bytes; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Mockito; + +public class RelativeJumpOperationTest { + + @ParameterizedTest + @ValueSource(ints = {1, 0, 9, -4, -5}) + void rjumpOperation(final int jumpLength) { + final GasCalculator gasCalculator = mock(GasCalculator.class); + final MessageFrame messageFrame = mock(MessageFrame.class, Mockito.RETURNS_DEEP_STUBS); + final String twosComplementJump = String.format("%08x", jumpLength).substring(4); + final int rjumpOperationIndex = 3; + final Bytes code = Bytes.fromHexString("00".repeat(3) + "5c" + twosComplementJump); + + when(messageFrame.getCode().getCodeBytes()).thenReturn(code); + when(messageFrame.getRemainingGas()).thenReturn(3L); + when(messageFrame.getPC()).thenReturn(rjumpOperationIndex); + + RelativeJumpOperation rjump = new RelativeJumpOperation(gasCalculator); + Operation.OperationResult rjumpResult = rjump.execute(messageFrame, null); + + Assertions.assertThat(rjumpResult.getPcIncrement()) + .isEqualTo(code.size() - rjumpOperationIndex + jumpLength); + } + + @Test + void rjumpiOperation() { + final GasCalculator gasCalculator = mock(GasCalculator.class); + final MessageFrame messageFrame = mock(MessageFrame.class, Mockito.RETURNS_DEEP_STUBS); + final int rjumpOperationIndex = 3; + final Bytes code = Bytes.fromHexString("00".repeat(rjumpOperationIndex) + "5d0004"); + + when(messageFrame.getCode().getCodeBytes()).thenReturn(code); + when(messageFrame.getPC()).thenReturn(rjumpOperationIndex); + when(messageFrame.getRemainingGas()).thenReturn(5L); + when(messageFrame.popStackItem()).thenReturn(Bytes.EMPTY); + + RelativeJumpIfOperation rjumpi = new RelativeJumpIfOperation(gasCalculator); + Operation.OperationResult rjumpResult = rjumpi.execute(messageFrame, null); + + Assertions.assertThat(rjumpResult.getPcIncrement()).isEqualTo(2 + 1); + } + + @Test + void rjumpvOperation() { + final GasCalculator gasCalculator = mock(GasCalculator.class); + final MessageFrame messageFrame = mock(MessageFrame.class, Mockito.RETURNS_DEEP_STUBS); + final int rjumpOperationIndex = 3; + final int jumpVectorSize = 1; + final int jumpLength = 4; + final Bytes code = + Bytes.fromHexString( + "00".repeat(rjumpOperationIndex) + + String.format("5e%02x%04x", jumpVectorSize, jumpLength)); + + when(messageFrame.getCode().getCodeBytes()).thenReturn(code); + when(messageFrame.getPC()).thenReturn(rjumpOperationIndex); + when(messageFrame.getRemainingGas()).thenReturn(5L); + when(messageFrame.popStackItem()).thenReturn(Bytes.of(jumpVectorSize)); + + RelativeJumpVectorOperation rjumpv = new RelativeJumpVectorOperation(gasCalculator); + Operation.OperationResult rjumpResult = rjumpv.execute(messageFrame, null); + + Assertions.assertThat(rjumpResult.getPcIncrement()).isEqualTo(1 + 2 * jumpVectorSize + 1); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java index 051ec5fda7..95be393d8d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -84,6 +84,9 @@ import org.hyperledger.besu.evm.operation.PopOperation; import org.hyperledger.besu.evm.operation.PrevRanDaoOperation; import org.hyperledger.besu.evm.operation.Push0Operation; import org.hyperledger.besu.evm.operation.PushOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpIfOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpVectorOperation; import org.hyperledger.besu.evm.operation.ReturnDataCopyOperation; import org.hyperledger.besu.evm.operation.ReturnDataSizeOperation; import org.hyperledger.besu.evm.operation.ReturnOperation; @@ -456,5 +459,8 @@ public class MainnetEVMs { registerParisOperations(registry, gasCalculator, chainID); // Register the PUSH0 operation. registry.put(new Push0Operation(gasCalculator)); + registry.put(new RelativeJumpOperation(gasCalculator)); + registry.put(new RelativeJumpIfOperation(gasCalculator)); + registry.put(new RelativeJumpVectorOperation(gasCalculator)); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/OpcodesV1.java b/evm/src/main/java/org/hyperledger/besu/evm/code/OpcodesV1.java index 6852ed8fb1..fdea5c24df 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/OpcodesV1.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/OpcodesV1.java @@ -17,6 +17,11 @@ package org.hyperledger.besu.evm.code; import org.hyperledger.besu.evm.operation.PushOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpIfOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpOperation; +import org.hyperledger.besu.evm.operation.RelativeJumpVectorOperation; + +import java.util.BitSet; import org.apache.tuweni.bytes.Bytes; @@ -122,9 +127,9 @@ class OpcodesV1 { VALID, // 0x59 - MSIZE VALID, // 0x5a - GAS VALID_AND_JUMPDEST, // 0x5b - JUMPDEST - INVALID, // 0X5c - INVALID, // 0X5d - INVALID, // 0X5e + VALID, // 0X5c - RJUMP + VALID, // 0X5d - RJUMPI + VALID, // 0X5e - RJUMPV VALID, // 0X5f - PUSH0 VALID, // 0x60 - PUSH1 VALID, // 0x61 - PUSH2 @@ -294,34 +299,77 @@ class OpcodesV1 { static long[] validateAndCalculateJumpDests(final Bytes code) { final int size = code.size(); - final long[] bitmap = new long[(size >> 6) + 1]; + final BitSet bitmap = new BitSet(size); + final BitSet rjumpdests = new BitSet(size); + final BitSet immediates = new BitSet(size); final byte[] rawCode = code.toArrayUnsafe(); - final int length = rawCode.length; int attribute = INVALID; - for (int i = 0; i < length; ) { - long thisEntry = 0L; - final int entryPos = i >> 6; - final int max = Math.min(64, length - (entryPos << 6)); - int j = i & 0x3f; - for (; j < max; i++, j++) { - final int operationNum = rawCode[i] & 0xff; - attribute = opcodeAttributes[operationNum]; - if ((attribute & INVALID) == INVALID) { + int pos = 0; + while (pos < size) { + final int operationNum = rawCode[pos] & 0xff; + attribute = opcodeAttributes[operationNum]; + if ((attribute & INVALID) == INVALID) { + // undefined instruction + return null; + } + if ((attribute & JUMPDEST) == JUMPDEST) { + bitmap.set(pos); + } + pos += 1; + int pcPostInstruction = pos; + if (operationNum > PushOperation.PUSH_BASE && operationNum <= PushOperation.PUSH_MAX) { + final int multiByteDataLen = operationNum - PushOperation.PUSH_BASE; + pcPostInstruction += multiByteDataLen; + } else if (operationNum == RelativeJumpOperation.OPCODE + || operationNum == RelativeJumpIfOperation.OPCODE) { + if (pos + 2 > size) { + // truncated relative jump offset + return null; + } + pcPostInstruction += 2; + final int offset = RelativeJumpOperation.getRelativeOffset(code, pos); + final int rjumpdest = pcPostInstruction + offset; + if (rjumpdest < 0 || rjumpdest >= size) { + // relative jump destination out of bounds + return null; + } + rjumpdests.set(rjumpdest); + } else if (operationNum == RelativeJumpVectorOperation.OPCODE) { + if (pos + 1 > size) { + // truncated jump table return null; - } else if ((attribute & JUMPDEST) == JUMPDEST) { - thisEntry |= 1L << j; - } else if (operationNum > PushOperation.PUSH_BASE - && operationNum <= PushOperation.PUSH_MAX) { - final int multiByteDataLen = operationNum - PushOperation.PUSH_BASE; - j += multiByteDataLen; - i += multiByteDataLen; + } + final int jumpTableSize = RelativeJumpVectorOperation.getVectorSize(code, pos); + if (jumpTableSize == 0) { + // empty jump table + return null; + } + pcPostInstruction += 1 + 2 * jumpTableSize; + if (pcPostInstruction > size) { + // truncated jump table + return null; + } + for (int offsetPos = pos + 1; offsetPos < pcPostInstruction; offsetPos += 2) { + final int offset = RelativeJumpOperation.getRelativeOffset(code, offsetPos); + final int rjumpdest = pcPostInstruction + offset; + if (rjumpdest < 0 || rjumpdest >= size) { + // relative jump destination out of bounds + return null; + } + rjumpdests.set(rjumpdest); } } - bitmap[entryPos] = thisEntry; + immediates.set(pos, pcPostInstruction); + pos = pcPostInstruction; } if ((attribute & TERMINAL) != TERMINAL) { + // no terminating instruction + return null; + } + if (rjumpdests.intersects(immediates)) { + // Ensure relative jump destinations don't target immediates return null; } - return bitmap; + return bitmap.toLongArray(); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java index b5664fb3e9..23495a3d30 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java @@ -45,9 +45,8 @@ public abstract class AbstractCallOperation extends AbstractOperation { final String name, final int stackItemsConsumed, final int stackItemsProduced, - final int opSize, final GasCalculator gasCalculator) { - super(opcode, name, stackItemsConsumed, stackItemsProduced, opSize, gasCalculator); + super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator); } /** 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 3ac8af4670..e91399c56d 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 @@ -41,9 +41,8 @@ public abstract class AbstractCreateOperation extends AbstractOperation { final String name, final int stackItemsConsumed, final int stackItemsProduced, - final int opSize, final GasCalculator gasCalculator) { - super(opcode, name, stackItemsConsumed, stackItemsProduced, opSize, gasCalculator); + super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractFixedCostOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractFixedCostOperation.java index 5f079daf9e..2629f71259 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractFixedCostOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractFixedCostOperation.java @@ -36,10 +36,9 @@ abstract class AbstractFixedCostOperation extends AbstractOperation { final String name, final int stackItemsConsumed, final int stackItemsProduced, - final int opSize, final GasCalculator gasCalculator, final long fixedCost) { - super(opcode, name, stackItemsConsumed, stackItemsProduced, opSize, gasCalculator); + super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator); gasCost = fixedCost; successResponse = new OperationResult(gasCost, null); outOfGasResponse = new OperationResult(gasCost, ExceptionalHaltReason.INSUFFICIENT_GAS); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractOperation.java index 2eb3f4f796..d2f524afa9 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractOperation.java @@ -26,7 +26,6 @@ public abstract class AbstractOperation implements Operation { private final String name; private final int stackItemsConsumed; private final int stackItemsProduced; - private final int opSize; private final GasCalculator gasCalculator; protected AbstractOperation( @@ -34,13 +33,11 @@ public abstract class AbstractOperation implements Operation { final String name, final int stackItemsConsumed, final int stackItemsProduced, - final int opSize, final GasCalculator gasCalculator) { this.opcode = opcode & 0xff; this.name = name; this.stackItemsConsumed = stackItemsConsumed; this.stackItemsProduced = stackItemsProduced; - this.opSize = opSize; this.gasCalculator = gasCalculator; } @@ -67,9 +64,4 @@ public abstract class AbstractOperation implements Operation { public int getStackItemsProduced() { return stackItemsProduced; } - - @Override - public int getOpSize() { - return opSize; - } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AddModOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AddModOperation.java index 6143681b63..2135286618 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AddModOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AddModOperation.java @@ -29,7 +29,7 @@ public class AddModOperation extends AbstractFixedCostOperation { private static final OperationResult addModSuccess = new OperationResult(8, null); public AddModOperation(final GasCalculator gasCalculator) { - super(0x08, "ADDMOD", 3, 1, 1, gasCalculator, gasCalculator.getMidTierGasCost()); + super(0x08, "ADDMOD", 3, 1, gasCalculator, gasCalculator.getMidTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AddOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AddOperation.java index 20c4996b34..b3697b36c6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AddOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AddOperation.java @@ -27,7 +27,7 @@ public class AddOperation extends AbstractFixedCostOperation { static final OperationResult addSuccess = new OperationResult(3, null); public AddOperation(final GasCalculator gasCalculator) { - super(0x01, "ADD", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x01, "ADD", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AddressOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AddressOperation.java index 6b13411828..57dff99c31 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AddressOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AddressOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class AddressOperation extends AbstractFixedCostOperation { public AddressOperation(final GasCalculator gasCalculator) { - super(0x30, "ADDRESS", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x30, "ADDRESS", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AndOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AndOperation.java index 35951ca501..8d58e3bd2b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AndOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AndOperation.java @@ -25,7 +25,7 @@ public class AndOperation extends AbstractFixedCostOperation { static final OperationResult andSuccess = new OperationResult(3, null); public AndOperation(final GasCalculator gasCalculator) { - super(0x16, "AND", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x16, "AND", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/BalanceOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/BalanceOperation.java index 647f4866f2..e8b81f961e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/BalanceOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/BalanceOperation.java @@ -29,7 +29,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class BalanceOperation extends AbstractOperation { public BalanceOperation(final GasCalculator gasCalculator) { - super(0x31, "BALANCE", 1, 1, 1, gasCalculator); + super(0x31, "BALANCE", 1, 1, gasCalculator); } protected long cost(final boolean accountIsWarm) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/BaseFeeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/BaseFeeOperation.java index f905715168..0f5ab969cc 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/BaseFeeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/BaseFeeOperation.java @@ -25,7 +25,7 @@ import java.util.Optional; public class BaseFeeOperation extends AbstractFixedCostOperation { public BaseFeeOperation(final GasCalculator gasCalculator) { - super(0x48, "BASEFEE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x48, "BASEFEE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/BlockHashOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/BlockHashOperation.java index 6e6909d65c..d75c0cb027 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/BlockHashOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/BlockHashOperation.java @@ -29,7 +29,7 @@ public class BlockHashOperation extends AbstractFixedCostOperation { private static final int MAX_RELATIVE_BLOCK = 255; public BlockHashOperation(final GasCalculator gasCalculator) { - super(0x40, "BLOCKHASH", 1, 1, 1, gasCalculator, gasCalculator.getBlockHashOperationGasCost()); + super(0x40, "BLOCKHASH", 1, 1, gasCalculator, gasCalculator.getBlockHashOperationGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ByteOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ByteOperation.java index c957a3aa60..5b1de565a7 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ByteOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ByteOperation.java @@ -26,7 +26,7 @@ public class ByteOperation extends AbstractFixedCostOperation { static final OperationResult byteSuccess = new OperationResult(3, null); public ByteOperation(final GasCalculator gasCalculator) { - super(0x1A, "BYTE", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x1A, "BYTE", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } private static UInt256 getByte(final UInt256 seq, final UInt256 offset) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallCodeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallCodeOperation.java index ce4bc56d01..08b84c359b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallCodeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallCodeOperation.java @@ -26,7 +26,7 @@ import org.hyperledger.besu.evm.internal.Words; public class CallCodeOperation extends AbstractCallOperation { public CallCodeOperation(final GasCalculator gasCalculator) { - super(0xF2, "CALLCODE", 7, 1, 1, gasCalculator); + super(0xF2, "CALLCODE", 7, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataCopyOperation.java index a08b00cc5d..145aa15c08 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataCopyOperation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes; public class CallDataCopyOperation extends AbstractOperation { public CallDataCopyOperation(final GasCalculator gasCalculator) { - super(0x37, "CALLDATACOPY", 3, 0, 1, gasCalculator); + super(0x37, "CALLDATACOPY", 3, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataLoadOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataLoadOperation.java index 569e48557f..833e91f887 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataLoadOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataLoadOperation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class CallDataLoadOperation extends AbstractFixedCostOperation { public CallDataLoadOperation(final GasCalculator gasCalculator) { - super(0x35, "CALLDATALOAD", 1, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x35, "CALLDATALOAD", 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataSizeOperation.java index 90e04f557c..3e9143565a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallDataSizeOperation.java @@ -24,7 +24,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class CallDataSizeOperation extends AbstractFixedCostOperation { public CallDataSizeOperation(final GasCalculator gasCalculator) { - super(0x36, "CALLDATASIZE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x36, "CALLDATASIZE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallOperation.java index 3046e26513..aa5d23fa2c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallOperation.java @@ -28,7 +28,7 @@ import org.hyperledger.besu.evm.internal.Words; public class CallOperation extends AbstractCallOperation { public CallOperation(final GasCalculator gasCalculator) { - super(0xF1, "CALL", 7, 1, 1, gasCalculator); + super(0xF1, "CALL", 7, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallValueOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallValueOperation.java index 2978165bcf..c5ccb38ba8 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallValueOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallValueOperation.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class CallValueOperation extends AbstractFixedCostOperation { public CallValueOperation(final GasCalculator gasCalculator) { - super(0x34, "CALLVALUE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x34, "CALLVALUE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallerOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallerOperation.java index 0aa53895e2..70b1011411 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallerOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallerOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class CallerOperation extends AbstractFixedCostOperation { public CallerOperation(final GasCalculator gasCalculator) { - super(0x33, "CALLER", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x33, "CALLER", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ChainIdOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ChainIdOperation.java index a6cbe90993..da3588ae54 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ChainIdOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ChainIdOperation.java @@ -26,7 +26,7 @@ public class ChainIdOperation extends AbstractFixedCostOperation { private final UInt256 chainId; public ChainIdOperation(final GasCalculator gasCalculator, final Bytes32 chainId) { - super(0x46, "CHAINID", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x46, "CHAINID", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); this.chainId = UInt256.fromBytes(chainId); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeCopyOperation.java index f3d420f366..f22f5657a3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CodeCopyOperation.java @@ -25,7 +25,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class CodeCopyOperation extends AbstractOperation { public CodeCopyOperation(final GasCalculator gasCalculator) { - super(0x39, "CODECOPY", 3, 0, 1, gasCalculator); + super(0x39, "CODECOPY", 3, 0, gasCalculator); } @Override 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 1282a4b54d..ef02776a76 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 @@ -24,7 +24,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class CodeSizeOperation extends AbstractFixedCostOperation { public CodeSizeOperation(final GasCalculator gasCalculator) { - super(0x38, "CODESIZE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x38, "CODESIZE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CoinbaseOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CoinbaseOperation.java index 94d66f942e..214374bd1f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CoinbaseOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CoinbaseOperation.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class CoinbaseOperation extends AbstractFixedCostOperation { public CoinbaseOperation(final GasCalculator gasCalculator) { - super(0x41, "COINBASE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x41, "COINBASE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java index 8e7d823f52..2546073293 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java @@ -30,7 +30,7 @@ public class Create2Operation extends AbstractCreateOperation { private static final Bytes PREFIX = Bytes.fromHexString("0xFF"); public Create2Operation(final GasCalculator gasCalculator) { - super(0xF5, "CREATE2", 4, 1, 1, gasCalculator); + super(0xF5, "CREATE2", 4, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java index 4f58c2cd59..079b66f338 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class CreateOperation extends AbstractCreateOperation { public CreateOperation(final GasCalculator gasCalculator) { - super(0xF0, "CREATE", 3, 1, 1, gasCalculator); + super(0xF0, "CREATE", 3, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/DelegateCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/DelegateCallOperation.java index d74d253d55..dbdb63ee5b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/DelegateCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/DelegateCallOperation.java @@ -26,7 +26,7 @@ import org.hyperledger.besu.evm.internal.Words; public class DelegateCallOperation extends AbstractCallOperation { public DelegateCallOperation(final GasCalculator gasCalculator) { - super(0xF4, "DELEGATECALL", 6, 1, 1, gasCalculator); + super(0xF4, "DELEGATECALL", 6, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/DifficultyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/DifficultyOperation.java index 3bf8c4fc40..3b8f93f67e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/DifficultyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/DifficultyOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class DifficultyOperation extends AbstractFixedCostOperation { public DifficultyOperation(final GasCalculator gasCalculator) { - super(0x44, "DIFFICULTY", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x44, "DIFFICULTY", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/DivOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/DivOperation.java index 54ae9fb3f0..87f53503f2 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/DivOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/DivOperation.java @@ -28,7 +28,7 @@ public class DivOperation extends AbstractFixedCostOperation { static final OperationResult divSuccess = new OperationResult(5, null); public DivOperation(final GasCalculator gasCalculator) { - super(0x04, "DIV", 2, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x04, "DIV", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/DupOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/DupOperation.java index 41058c8d2e..b7049a3b90 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/DupOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/DupOperation.java @@ -33,7 +33,6 @@ public class DupOperation extends AbstractFixedCostOperation { "DUP" + index, index, index + 1, - 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); this.index = index; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/EqOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/EqOperation.java index 69fb081f23..8f15a7c032 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/EqOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/EqOperation.java @@ -25,7 +25,7 @@ public class EqOperation extends AbstractFixedCostOperation { static final OperationResult eqSuccess = new OperationResult(3, null); public EqOperation(final GasCalculator gasCalculator) { - super(0x14, "EQ", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x14, "EQ", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExpOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExpOperation.java index 43e45c5ffa..903588107a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExpOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExpOperation.java @@ -24,7 +24,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class ExpOperation extends AbstractOperation { public ExpOperation(final GasCalculator gasCalculator) { - super(0x0A, "EXP", 2, 1, 1, gasCalculator); + super(0x0A, "EXP", 2, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java index e393cab97f..4475c5cb8c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java @@ -30,7 +30,7 @@ import org.apache.tuweni.bytes.Bytes; public class ExtCodeCopyOperation extends AbstractOperation { public ExtCodeCopyOperation(final GasCalculator gasCalculator) { - super(0x3C, "EXTCODECOPY", 4, 0, 1, gasCalculator); + super(0x3C, "EXTCODECOPY", 4, 0, gasCalculator); } protected long cost( diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java index 97ccf6954c..35864b3cd3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java @@ -29,7 +29,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class ExtCodeHashOperation extends AbstractOperation { public ExtCodeHashOperation(final GasCalculator gasCalculator) { - super(0x3F, "EXTCODEHASH", 1, 1, 1, gasCalculator); + super(0x3F, "EXTCODEHASH", 1, 1, gasCalculator); } protected long cost(final boolean accountIsWarm) { 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 abaa345dff..50ebb40742 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 @@ -29,7 +29,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class ExtCodeSizeOperation extends AbstractOperation { public ExtCodeSizeOperation(final GasCalculator gasCalculator) { - super(0x3B, "EXTCODESIZE", 1, 1, 1, gasCalculator); + super(0x3B, "EXTCODESIZE", 1, 1, gasCalculator); } protected long cost(final boolean accountIsWarm) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/GasLimitOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/GasLimitOperation.java index f2e384422e..14ea74baaa 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/GasLimitOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/GasLimitOperation.java @@ -23,7 +23,7 @@ import org.apache.tuweni.bytes.Bytes; public class GasLimitOperation extends AbstractFixedCostOperation { public GasLimitOperation(final GasCalculator gasCalculator) { - super(0x45, "GASLIMIT", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x45, "GASLIMIT", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/GasOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/GasOperation.java index 0d8ae82c7d..f28cb50ed5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/GasOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/GasOperation.java @@ -23,7 +23,7 @@ import org.apache.tuweni.bytes.Bytes; public class GasOperation extends AbstractFixedCostOperation { public GasOperation(final GasCalculator gasCalculator) { - super(0x5A, "GAS", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x5A, "GAS", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/GasPriceOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/GasPriceOperation.java index b33a45f4a9..5eccdcba5a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/GasPriceOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/GasPriceOperation.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class GasPriceOperation extends AbstractFixedCostOperation { public GasPriceOperation(final GasCalculator gasCalculator) { - super(0x3A, "GASPRICE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x3A, "GASPRICE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/GtOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/GtOperation.java index 54dde37310..323d654953 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/GtOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/GtOperation.java @@ -25,7 +25,7 @@ public class GtOperation extends AbstractFixedCostOperation { static final OperationResult gtSuccess = new OperationResult(3, null); public GtOperation(final GasCalculator gasCalculator) { - super(0x11, "GT", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x11, "GT", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/InvalidOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/InvalidOperation.java index 2ad8fce8fb..e329826336 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/InvalidOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/InvalidOperation.java @@ -31,7 +31,7 @@ public class InvalidOperation extends AbstractOperation { } public InvalidOperation(final int opcode, final GasCalculator gasCalculator) { - super(opcode, "INVALID", -1, -1, 1, gasCalculator); + super(opcode, "INVALID", -1, -1, gasCalculator); invalidResult = new OperationResult(0L, ExceptionalHaltReason.INVALID_OPERATION); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/IsZeroOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/IsZeroOperation.java index d256598192..6b5c1e0388 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/IsZeroOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/IsZeroOperation.java @@ -25,7 +25,7 @@ public class IsZeroOperation extends AbstractFixedCostOperation { static final OperationResult isZeroSuccess = new OperationResult(3, null); public IsZeroOperation(final GasCalculator gasCalculator) { - super(0x15, "ISZERO", 1, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x15, "ISZERO", 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpDestOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpDestOperation.java index 13e3da3dc5..553c0c35eb 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpDestOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpDestOperation.java @@ -23,7 +23,7 @@ public class JumpDestOperation extends AbstractFixedCostOperation { public static final int OPCODE = 0x5B; public JumpDestOperation(final GasCalculator gasCalculator) { - super(OPCODE, "JUMPDEST", 0, 0, 1, gasCalculator, gasCalculator.getJumpDestOperationGasCost()); + super(OPCODE, "JUMPDEST", 0, 0, gasCalculator, gasCalculator.getJumpDestOperationGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpOperation.java index 9819578d0c..0f43346154 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpOperation.java @@ -28,7 +28,7 @@ public class JumpOperation extends AbstractFixedCostOperation { private final OperationResult jumpResponse; public JumpOperation(final GasCalculator gasCalculator) { - super(0x56, "JUMP", 2, 0, 1, gasCalculator, gasCalculator.getMidTierGasCost()); + super(0x56, "JUMP", 2, 0, gasCalculator, gasCalculator.getMidTierGasCost()); invalidJumpResponse = new Operation.OperationResult(gasCost, ExceptionalHaltReason.INVALID_JUMP_DESTINATION); jumpResponse = new OperationResult(gasCost, null, 0); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpiOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpiOperation.java index 8426fa5ad8..e4c41f89d9 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpiOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpiOperation.java @@ -28,7 +28,7 @@ public class JumpiOperation extends AbstractFixedCostOperation { private final OperationResult jumpResponse; public JumpiOperation(final GasCalculator gasCalculator) { - super(0x57, "JUMPI", 2, 0, 1, gasCalculator, gasCalculator.getHighTierGasCost()); + super(0x57, "JUMPI", 2, 0, gasCalculator, gasCalculator.getHighTierGasCost()); invalidJumpResponse = new Operation.OperationResult(gasCost, ExceptionalHaltReason.INVALID_JUMP_DESTINATION); jumpResponse = new OperationResult(gasCost, null, 0); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/Keccak256Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/Keccak256Operation.java index 3b172a819c..2a877eabff 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/Keccak256Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/Keccak256Operation.java @@ -28,7 +28,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class Keccak256Operation extends AbstractOperation { public Keccak256Operation(final GasCalculator gasCalculator) { - super(0x20, "KECCAK256", 2, 1, 1, gasCalculator); + super(0x20, "KECCAK256", 2, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/LogOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/LogOperation.java index 281a58d789..826e552ce1 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/LogOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/LogOperation.java @@ -33,7 +33,7 @@ public class LogOperation extends AbstractOperation { private final int numTopics; public LogOperation(final int numTopics, final GasCalculator gasCalculator) { - super(0xA0 + numTopics, "LOG" + numTopics, numTopics + 2, 0, 1, gasCalculator); + super(0xA0 + numTopics, "LOG" + numTopics, numTopics + 2, 0, gasCalculator); this.numTopics = numTopics; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/LtOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/LtOperation.java index 267de1a929..dcb62489f5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/LtOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/LtOperation.java @@ -25,7 +25,7 @@ public class LtOperation extends AbstractFixedCostOperation { static final OperationResult ltSuccess = new OperationResult(3, null); public LtOperation(final GasCalculator gasCalculator) { - super(0x10, "LT", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x10, "LT", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/MLoadOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/MLoadOperation.java index bf45ff5976..856afac9e1 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/MLoadOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/MLoadOperation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes; public class MLoadOperation extends AbstractOperation { public MLoadOperation(final GasCalculator gasCalculator) { - super(0x51, "MLOAD", 1, 1, 1, gasCalculator); + super(0x51, "MLOAD", 1, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/MSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/MSizeOperation.java index 7fa2f3a1e0..bf64a6e419 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/MSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/MSizeOperation.java @@ -23,7 +23,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class MSizeOperation extends AbstractFixedCostOperation { public MSizeOperation(final GasCalculator gasCalculator) { - super(0x59, "MSIZE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x59, "MSIZE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/MStore8Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/MStore8Operation.java index efaf320fa9..26a6b13f57 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/MStore8Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/MStore8Operation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes; public class MStore8Operation extends AbstractOperation { public MStore8Operation(final GasCalculator gasCalculator) { - super(0x53, "MSTORE8", 2, 0, 1, gasCalculator); + super(0x53, "MSTORE8", 2, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/MStoreOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/MStoreOperation.java index 34ed4aca9b..d6bd180c66 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/MStoreOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/MStoreOperation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes; public class MStoreOperation extends AbstractOperation { public MStoreOperation(final GasCalculator gasCalculator) { - super(0x52, "MSTORE", 2, 0, 1, gasCalculator); + super(0x52, "MSTORE", 2, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ModOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ModOperation.java index 36d8a0357e..382adfc5ef 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ModOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ModOperation.java @@ -29,7 +29,7 @@ public class ModOperation extends AbstractFixedCostOperation { private static final OperationResult modSuccess = new OperationResult(5, null); public ModOperation(final GasCalculator gasCalculator) { - super(0x06, "MOD", 2, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x06, "MOD", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/MulModOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/MulModOperation.java index a4e8c4077d..543fa5cfe3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/MulModOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/MulModOperation.java @@ -29,7 +29,7 @@ public class MulModOperation extends AbstractFixedCostOperation { private static final OperationResult mulModSuccess = new OperationResult(8, null); public MulModOperation(final GasCalculator gasCalculator) { - super(0x09, "MULMOD", 3, 1, 1, gasCalculator, gasCalculator.getMidTierGasCost()); + super(0x09, "MULMOD", 3, 1, gasCalculator, gasCalculator.getMidTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/MulOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/MulOperation.java index 844b7e45d7..89ab195eab 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/MulOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/MulOperation.java @@ -27,7 +27,7 @@ public class MulOperation extends AbstractFixedCostOperation { static final OperationResult mulSuccess = new OperationResult(5, null); public MulOperation(final GasCalculator gasCalculator) { - super(0x02, "MUL", 2, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x02, "MUL", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/NotOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/NotOperation.java index d83587aeb8..750b5360d3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/NotOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/NotOperation.java @@ -25,7 +25,7 @@ public class NotOperation extends AbstractFixedCostOperation { static final OperationResult notSuccess = new OperationResult(3, null); public NotOperation(final GasCalculator gasCalculator) { - super(0x19, "NOT", 1, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x19, "NOT", 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/NumberOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/NumberOperation.java index 254304303c..2b81e30e8d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/NumberOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/NumberOperation.java @@ -23,7 +23,7 @@ import org.apache.tuweni.bytes.Bytes; public class NumberOperation extends AbstractFixedCostOperation { public NumberOperation(final GasCalculator gasCalculator) { - super(0x43, "NUMBER", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x43, "NUMBER", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/Operation.java index bd80517dc0..a8debf8203 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/Operation.java @@ -71,8 +71,6 @@ public interface Operation { int getStackItemsProduced(); - int getOpSize(); - /** * Determines whether this operation has been virtually added to the contract code. For instance * if the contract is not ended by a STOP opcode the {@link EVM} adds an explicit end of script diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/OrOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/OrOperation.java index a054a1e14c..6b71a90acd 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/OrOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/OrOperation.java @@ -25,7 +25,7 @@ public class OrOperation extends AbstractFixedCostOperation { static final OperationResult orSuccess = new OperationResult(3, null); public OrOperation(final GasCalculator gasCalculator) { - super(0x17, "OR", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x17, "OR", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/OriginOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/OriginOperation.java index f66c7759af..15a4ab7020 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/OriginOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/OriginOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class OriginOperation extends AbstractFixedCostOperation { public OriginOperation(final GasCalculator gasCalculator) { - super(0x32, "ORIGIN", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x32, "ORIGIN", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/PCOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/PCOperation.java index 4183f1199a..16727b4c56 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/PCOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/PCOperation.java @@ -23,7 +23,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class PCOperation extends AbstractFixedCostOperation { public PCOperation(final GasCalculator gasCalculator) { - super(0x58, "PC", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x58, "PC", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/PopOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/PopOperation.java index c463d7b260..d7ee02ba81 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/PopOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/PopOperation.java @@ -23,7 +23,7 @@ public class PopOperation extends AbstractFixedCostOperation { static final OperationResult popSuccess = new OperationResult(2, null); public PopOperation(final GasCalculator gasCalculator) { - super(0x50, "POP", 1, 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x50, "POP", 1, 0, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperation.java index bd4b3de629..485c71d224 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperation.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class PrevRanDaoOperation extends AbstractFixedCostOperation { public PrevRanDaoOperation(final GasCalculator gasCalculator) { - super(0x44, "PREVRANDAO", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x44, "PREVRANDAO", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/Push0Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/Push0Operation.java index 32ac7db409..22ac7477f6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/Push0Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/Push0Operation.java @@ -27,7 +27,7 @@ public class Push0Operation extends AbstractFixedCostOperation { static final OperationResult push0Success = new OperationResult(2, null); public Push0Operation(final GasCalculator gasCalculator) { - super(PUSH_BASE, "PUSH0", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(PUSH_BASE, "PUSH0", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override 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 4330d2285d..9869e4e142 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 @@ -35,7 +35,6 @@ public class PushOperation extends AbstractFixedCostOperation { "PUSH" + length, 0, 1, - length + 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); this.length = length; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java new file mode 100644 index 0000000000..a94f17569d --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java @@ -0,0 +1,41 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.hyperledger.besu.evm.operation; + +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; + +import org.apache.tuweni.bytes.Bytes; + +public class RelativeJumpIfOperation extends RelativeJumpOperation { + + public static final int OPCODE = 0x5d; + + public RelativeJumpIfOperation(final GasCalculator gasCalculator) { + super(OPCODE, "RJUMPI", 0, 0, gasCalculator, 4L); + } + + @Override + protected OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) { + final Bytes condition = frame.popStackItem(); + // If condition is zero (false), no jump is will be performed. Therefore, skip the rest. + if (!condition.isZero()) { + return super.executeFixedCostOperation(frame, evm); + } + return new OperationResult(gasCost, null, 2 + 1); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java new file mode 100644 index 0000000000..6d707f2595 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java @@ -0,0 +1,65 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.hyperledger.besu.evm.operation; + +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; + +import org.apache.tuweni.bytes.Bytes; + +public class RelativeJumpOperation extends AbstractFixedCostOperation { + + public static final int OPCODE = 0x5c; + + public RelativeJumpOperation(final GasCalculator gasCalculator) { + this(OPCODE, "RJUMP", 0, 0, gasCalculator, gasCalculator.getBaseTierGasCost()); + } + + protected RelativeJumpOperation( + final int opcode, + final String name, + final int stackItemsConsumed, + final int stackItemsProduced, + final GasCalculator gasCalculator, + final long fixedCost) { + super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator, fixedCost); + } + + @Override + protected OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) { + final Bytes code = frame.getCode().getCodeBytes(); + final int pcPostInstruction = frame.getPC() + 1; + return new OperationResult(gasCost, null, 2 + getRelativeOffset(code, pcPostInstruction) + 1); + } + + /** + * Extracts the relative offset from the 16 bits after the RJUMP[I] opcode. This value is encoded + * as a 16-bit signed (two’s-complement) big-endian value + * + * @param code the source + * @param relativeOffsetBegin offset within the code where the immediate offset begins + * @return code immediate offset + */ + public static int getRelativeOffset(final Bytes code, final int relativeOffsetBegin) { + int relativeOffset = + (code.get(relativeOffsetBegin) << 8) | (code.get(relativeOffsetBegin + 1) & 0xff); + if ((relativeOffset & 0x8000) != 0) { + relativeOffset = -((~relativeOffset & 0xffff) + 1); + } + return relativeOffset; + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java new file mode 100644 index 0000000000..14f6750850 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java @@ -0,0 +1,53 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.hyperledger.besu.evm.operation; + +import static org.hyperledger.besu.evm.operation.RelativeJumpOperation.getRelativeOffset; + +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; + +import org.apache.tuweni.bytes.Bytes; + +public class RelativeJumpVectorOperation extends AbstractFixedCostOperation { + + public static final int OPCODE = 0x5e; + + public RelativeJumpVectorOperation(final GasCalculator gasCalculator) { + super(OPCODE, "RJUMPV", 0, 0, gasCalculator, 4L); + } + + @Override + protected OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) { + final Bytes code = frame.getCode().getCodeBytes(); + final int offsetCase = frame.popStackItem().toInt(); + final int vectorSize = getVectorSize(code, frame.getPC() + 1); + return new OperationResult( + gasCost, + null, + 1 + + 2 * vectorSize + + ((offsetCase >= vectorSize) + ? 0 + : getRelativeOffset(code, frame.getPC() + 1 + offsetCase * 2)) + + 1); + } + + public static int getVectorSize(final Bytes code, final int offsetCountByteIndex) { + return code.get(offsetCountByteIndex) & 0xff; + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataCopyOperation.java index c0f0c2eb22..81abfb25d3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataCopyOperation.java @@ -31,7 +31,7 @@ public class ReturnDataCopyOperation extends AbstractOperation { new OperationResult(0L, ExceptionalHaltReason.OUT_OF_BOUNDS); public ReturnDataCopyOperation(final GasCalculator gasCalculator) { - super(0x3E, "RETURNDATACOPY", 3, 0, 1, gasCalculator); + super(0x3E, "RETURNDATACOPY", 3, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataSizeOperation.java index 2b31ae73eb..5ad628b322 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataSizeOperation.java @@ -24,7 +24,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class ReturnDataSizeOperation extends AbstractFixedCostOperation { public ReturnDataSizeOperation(final GasCalculator gasCalculator) { - super(0x3D, "RETURNDATASIZE", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x3D, "RETURNDATASIZE", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnOperation.java index ed569845b0..14fd1847f9 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnOperation.java @@ -24,7 +24,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class ReturnOperation extends AbstractOperation { public ReturnOperation(final GasCalculator gasCalculator) { - super(0xF3, "RETURN", 2, 0, 1, gasCalculator); + super(0xF3, "RETURN", 2, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RevertOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RevertOperation.java index a205bc30b3..cf276050b6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/RevertOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RevertOperation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes; public class RevertOperation extends AbstractOperation { public RevertOperation(final GasCalculator gasCalculator) { - super(0xFD, "REVERT", 2, 0, 1, gasCalculator); + super(0xFD, "REVERT", 2, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SDivOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SDivOperation.java index bfe3f2046e..2031b8ed10 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SDivOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SDivOperation.java @@ -29,7 +29,7 @@ public class SDivOperation extends AbstractFixedCostOperation { private static final OperationResult sdivSuccess = new OperationResult(5, null); public SDivOperation(final GasCalculator gasCalculator) { - super(0x05, "SDIV", 2, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x05, "SDIV", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SGtOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SGtOperation.java index 0fb72c424f..bbbd5b1f0d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SGtOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SGtOperation.java @@ -28,7 +28,7 @@ public class SGtOperation extends AbstractFixedCostOperation { static final OperationResult sgtSuccess = new OperationResult(3, null); public SGtOperation(final GasCalculator gasCalculator) { - super(0x13, "SGT", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x13, "SGT", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SLoadOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SLoadOperation.java index 64a5cce790..a24e22a599 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SLoadOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SLoadOperation.java @@ -35,7 +35,7 @@ public class SLoadOperation extends AbstractOperation { private final OperationResult coldSuccess; public SLoadOperation(final GasCalculator gasCalculator) { - super(0x54, "SLOAD", 1, 1, 1, gasCalculator); + super(0x54, "SLOAD", 1, 1, gasCalculator); final long baseCost = gasCalculator.getSloadOperationGasCost(); warmCost = baseCost + gasCalculator.getWarmStorageReadCost(); coldCost = baseCost + gasCalculator.getColdSloadCost(); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SLtOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SLtOperation.java index a3f7244c4e..7563835443 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SLtOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SLtOperation.java @@ -28,7 +28,7 @@ public class SLtOperation extends AbstractFixedCostOperation { static final OperationResult sltSuccess = new OperationResult(3, null); public SLtOperation(final GasCalculator gasCalculator) { - super(0x12, "SLT", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x12, "SLT", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SModOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SModOperation.java index c6d6829c79..b42ef90d04 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SModOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SModOperation.java @@ -29,7 +29,7 @@ public class SModOperation extends AbstractFixedCostOperation { private static final OperationResult smodSuccess = new OperationResult(5, null); public SModOperation(final GasCalculator gasCalculator) { - super(0x07, "SMOD", 2, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x07, "SMOD", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java index b932ca22ce..31c89b7807 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java @@ -34,7 +34,7 @@ public class SStoreOperation extends AbstractOperation { private final long minimumGasRemaining; public SStoreOperation(final GasCalculator gasCalculator, final long minimumGasRemaining) { - super(0x55, "SSTORE", 2, 0, 1, gasCalculator); + super(0x55, "SSTORE", 2, 0, gasCalculator); this.minimumGasRemaining = minimumGasRemaining; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SarOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SarOperation.java index 428718b697..bfa4dc500b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SarOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SarOperation.java @@ -31,7 +31,7 @@ public class SarOperation extends AbstractFixedCostOperation { private static final UInt256 ALL_BITS = UInt256.MAX_VALUE; public SarOperation(final GasCalculator gasCalculator) { - super(0x1d, "SAR", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x1d, "SAR", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfBalanceOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfBalanceOperation.java index 1158d122b5..6cb9d63a94 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfBalanceOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfBalanceOperation.java @@ -25,7 +25,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class SelfBalanceOperation extends AbstractFixedCostOperation { public SelfBalanceOperation(final GasCalculator gasCalculator) { - super(0x47, "SELFBALANCE", 0, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x47, "SELFBALANCE", 0, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java index 7741b9f8b4..48b13271ad 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java @@ -27,7 +27,7 @@ import org.hyperledger.besu.evm.internal.Words; public class SelfDestructOperation extends AbstractOperation { public SelfDestructOperation(final GasCalculator gasCalculator) { - super(0xFF, "SELFDESTRUCT", 1, 0, 1, gasCalculator); + super(0xFF, "SELFDESTRUCT", 1, 0, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ShlOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ShlOperation.java index 1bc56940c7..244806125b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ShlOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ShlOperation.java @@ -28,7 +28,7 @@ public class ShlOperation extends AbstractFixedCostOperation { static final OperationResult shlSuccess = new OperationResult(3, null); public ShlOperation(final GasCalculator gasCalculator) { - super(0x1b, "SHL", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x1b, "SHL", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ShrOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ShrOperation.java index fc6033a55b..bce0f8544f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ShrOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ShrOperation.java @@ -28,7 +28,7 @@ public class ShrOperation extends AbstractFixedCostOperation { static final OperationResult shrSuccess = new OperationResult(3, null); public ShrOperation(final GasCalculator gasCalculator) { - super(0x1c, "SHR", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x1c, "SHR", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SignExtendOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SignExtendOperation.java index 11145e7796..e797ab1818 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SignExtendOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SignExtendOperation.java @@ -26,7 +26,7 @@ public class SignExtendOperation extends AbstractFixedCostOperation { private static final OperationResult signExtendSuccess = new OperationResult(5, null); public SignExtendOperation(final GasCalculator gasCalculator) { - super(0x0B, "SIGNEXTEND", 2, 1, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + super(0x0B, "SIGNEXTEND", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/StaticCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/StaticCallOperation.java index d6022651a4..b6ddba1705 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/StaticCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/StaticCallOperation.java @@ -26,7 +26,7 @@ import org.hyperledger.besu.evm.internal.Words; public class StaticCallOperation extends AbstractCallOperation { public StaticCallOperation(final GasCalculator gasCalculator) { - super(0xFA, "STATICCALL", 6, 1, 1, gasCalculator); + super(0xFA, "STATICCALL", 6, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/StopOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/StopOperation.java index c4e4769654..511374e7e4 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/StopOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/StopOperation.java @@ -25,7 +25,7 @@ public class StopOperation extends AbstractFixedCostOperation { static final OperationResult stopSuccess = new OperationResult(0, null); public StopOperation(final GasCalculator gasCalculator) { - super(0x00, "STOP", 0, 0, 1, gasCalculator, gasCalculator.getZeroTierGasCost()); + super(0x00, "STOP", 0, 0, gasCalculator, gasCalculator.getZeroTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SubOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SubOperation.java index 0ca8cb0ae4..22b9ca43d6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SubOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SubOperation.java @@ -25,7 +25,7 @@ public class SubOperation extends AbstractFixedCostOperation { static final OperationResult subSuccess = new OperationResult(3, null); public SubOperation(final GasCalculator gasCalculator) { - super(0x03, "SUB", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x03, "SUB", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SwapOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SwapOperation.java index 0bda339e25..53fe7ef14d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SwapOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SwapOperation.java @@ -35,7 +35,6 @@ public class SwapOperation extends AbstractFixedCostOperation { "SWAP" + index, index + 1, index + 1, - 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); this.index = index; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/TimestampOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/TimestampOperation.java index a8a29138a8..fb80629a9e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/TimestampOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/TimestampOperation.java @@ -23,7 +23,7 @@ import org.apache.tuweni.units.bigints.UInt256; public class TimestampOperation extends AbstractFixedCostOperation { public TimestampOperation(final GasCalculator gasCalculator) { - super(0x42, "TIMESTAMP", 0, 1, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); + super(0x42, "TIMESTAMP", 0, 1, gasCalculator, gasCalculator.getBaseTierGasCost()); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/VirtualOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/VirtualOperation.java index 4b0e3648e5..32157063fa 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/VirtualOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/VirtualOperation.java @@ -52,11 +52,6 @@ public class VirtualOperation implements Operation { return delegate.getStackItemsProduced(); } - @Override - public int getOpSize() { - return delegate.getOpSize(); - } - @Override public boolean isVirtualOperation() { return true; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/XorOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/XorOperation.java index f7aa7eb8e0..20d9fe18f9 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/XorOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/XorOperation.java @@ -25,7 +25,7 @@ public class XorOperation extends AbstractFixedCostOperation { static final OperationResult xorSuccess = new OperationResult(3, null); public XorOperation(final GasCalculator gasCalculator) { - super(0x18, "XOR", 2, 1, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); + super(0x18, "XOR", 2, 1, gasCalculator, gasCalculator.getVeryLowTierGasCost()); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java new file mode 100644 index 0000000000..826bada647 --- /dev/null +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java @@ -0,0 +1,187 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.hyperledger.besu.evm.code; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.evm.Code; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +class CodeFactoryTest { + + @Test + void invalidCodeIncompleteMagic() { + invalidCode("0xEF"); + } + + @Test + void invalidCodeInvalidMagic() { + invalidCode("0xEFFF0101000302000400600000AABBCCDD"); + } + + @Test + void invalidCodeNoVersion() { + invalidCode("0xEF00"); + } + + @Test + void invalidCodeInvalidVersion0x00() { + invalidCode("EF000001000302000400600000AABBCCDD"); + } + + @Test + void invalidCodeInvalidVersion0x02() { + invalidCode("EF000201000302000400600000AABBCCDD"); + } + + @Test + void invalidCodeInvalidVersion0xFF() { + invalidCode("EF00FF01000302000400600000AABBCCDD"); + } + + @Test + void invalidCodeNoHeader() { + invalidCode("0xEF0001"); + } + + @Test + void invalidCodeNoCodeSection() { + invalidCode("0xEF000100"); + } + + @Test + void invalidCodeNoCodeSectionSize() { + invalidCode("0xEF000101"); + } + + @Test + void invalidCodeCodeSectionSizeIncomplete() { + invalidCode("0xEF00010100"); + } + + @Test + void invalidCodeNoSectionTerminator0x03() { + invalidCode("0xEF0001010003"); + } + + @Test + void invalidCodeNoSectionTerminator0x03600000() { + invalidCode("0xEF0001010003600000"); + } + + @Test + void invalidCodeNoCodeSectionContents() { + invalidCode("0xEF000101000200"); + } + + @Test + void invalidCodeCodeSectionContentsIncomplete() { + invalidCode("0xEF00010100020060"); + } + + @Test + void invalidCodeTrailingBytesAfterCodeSection() { + invalidCode("0xEF000101000300600000DEADBEEF"); + } + + @Test + void invalidCodeMultipleCodeSections() { + invalidCode("0xEF000101000301000300600000600000"); + } + + @Test + void invalidCodeEmptyCodeSection() { + invalidCode("0xEF000101000000"); + } + + @Test + void invalidCodeEmptyCodeSectionWithNonEmptyDataSection() { + invalidCode("0xEF000101000002000200AABB"); + } + + @Test + void invalidCodeDataSectionPrecedingCodeSection() { + invalidCode("0xEF000102000401000300AABBCCDD600000"); + } + + @Test + void invalidCodeDataSectionWithoutCodeSection() { + invalidCode("0xEF000102000400AABBCCDD"); + } + + @Test + void invalidCodeNoDataSectionSize() { + invalidCode("0xEF000101000202"); + } + + @Test + void invalidCodeDataSectionSizeIncomplete() { + invalidCode("0xEF00010100020200"); + } + + @Test + void invalidCodeNoSectionTerminator0x03020004() { + invalidCode("0xEF0001010003020004"); + } + + @Test + void invalidCodeNoSectionTerminator0x03020004600000AABBCCDD() { + invalidCode("0xEF0001010003020004600000AABBCCDD"); + } + + @Test + void invalidCodeNoDataSectionContents() { + invalidCode("0xEF000101000302000400600000"); + } + + @Test + void invalidCodeDataSectionContentsIncomplete() { + invalidCode("0xEF000101000302000400600000AABBCC"); + } + + @Test + void invalidCodeTrailingBytesAfterDataSection() { + invalidCode("0xEF000101000302000400600000AABBCCDDEE"); + } + + @Test + void invalidCodeMultipleDataSections() { + invalidCode("0xEF000101000302000402000400600000AABBCCDDAABBCCDD"); + } + + @Test + void invalidCodeMultipleCodeAndDataSections() { + invalidCode("0xEF000101000101000102000102000100FEFEAABB"); + } + + @Test + void invalidCodeEmptyDataSection() { + invalidCode("0xEF000101000302000000600000"); + } + + @Test + void invalidCodeUnknownSectionId3() { + invalidCode("0xEF0001010002030004006000AABBCCDD"); + } + + private static void invalidCode(final String str) { + Code code = CodeFactory.createCode(Bytes.fromHexString(str), Hash.EMPTY, 1, true); + assertThat(code.isValid()).isFalse(); + } +} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java index 45d5413273..9b8ae10b78 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java @@ -18,11 +18,20 @@ package org.hyperledger.besu.evm.code; import static org.assertj.core.api.Assertions.assertThat; +import java.util.stream.IntStream; +import java.util.stream.Stream; + import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; class CodeV1Test { + public static final String ZERO_HEX = String.format("%02x", 0); + @Test void calculatesJumpDestMap() { String codeHex = "0xEF000101000F006001600055600D5660026000555B00"; @@ -32,4 +41,305 @@ class CodeV1Test { assertThat(jumpDest).containsExactly(0x2000); } + + @ParameterizedTest + @ValueSource( + strings = {"3000", "5000", "5c000000", "60005d000000", "60005e01000000", "fe00", "0000"}) + void testValidOpcodes(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + @ParameterizedTest + @ValueSource(strings = {"00", "f3", "fd", "fe"}) + void testValidCodeTerminator(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + @ParameterizedTest + @MethodSource("testPushValidImmediateArguments") + void testPushValidImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + private static Stream testPushValidImmediateArguments() { + final int codeBegin = 96; + return IntStream.range(0, 32) + .mapToObj(i -> String.format("%02x", codeBegin + i) + ZERO_HEX.repeat(i + 1) + ZERO_HEX) + .map(Arguments::arguments); + } + + @ParameterizedTest + @MethodSource("testRjumpValidImmediateArguments") + void testRjumpValidImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + private static Stream testRjumpValidImmediateArguments() { + return Stream.of( + "5c000000", + "5c00010000", + "5c00010000000000", + "5c0100" + ZERO_HEX.repeat(256) + ZERO_HEX, + "5c7fff" + ZERO_HEX.repeat(32767) + ZERO_HEX, + "5cfffd0000", + "005cfffc00", + ZERO_HEX.repeat(253) + "5cff0000", + ZERO_HEX.repeat(32765) + "5c800000") + .map(Arguments::arguments); + } + + @ParameterizedTest + @MethodSource("testRjumpiValidImmediateArguments") + void testRjumpiValidImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + private static Stream testRjumpiValidImmediateArguments() { + return Stream.of( + "60015d000000", + "60015d00010000", + "60015d00010000000000", + "60015d0100" + "5b".repeat(256) + ZERO_HEX, + "60015d7fff" + "5b".repeat(32767) + ZERO_HEX, + "60015dfffd0000", + "60015dfffb00", + ZERO_HEX.repeat(252) + "60015dff0000", + ZERO_HEX.repeat(32763) + "60015d800000", + "5d000000") + .map(Arguments::arguments); + } + + @ParameterizedTest + @MethodSource("rjumptableValidImmediateArguments") + void testRjumptableValidImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + private static Stream rjumptableValidImmediateArguments() { + return Stream.of( + "60015e01000000", + "60015e02000000010000", + "60015e03000000040100" + "5b".repeat(256) + ZERO_HEX, + "60015e040000000401007fff" + "5b".repeat(32767) + ZERO_HEX, + "60015e01fffc0000", + "5b".repeat(248) + "60015e02fffaff0000", + "5b".repeat(32760) + "60015e02fffa800000", + "5e01000000") + .map(Arguments::arguments); + } + + @ParameterizedTest + @MethodSource("invalidCodeArguments") + void testInvalidCode(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + private static Stream invalidCodeArguments() { + return Stream.of( + IntStream.rangeClosed(0x0c, 0x0f), + IntStream.of(0x1e, 0x1f), + IntStream.rangeClosed(0x21, 0x2f), + IntStream.rangeClosed(0x49, 0x4f), + // IntStream.of(0x5f), // PUSH0 + IntStream.rangeClosed(0xa5, 0xaf), + IntStream.rangeClosed(0xb0, 0xbf), + IntStream.rangeClosed(0xc0, 0xcf), + IntStream.rangeClosed(0xd0, 0xdf), + IntStream.rangeClosed(0xe0, 0xef), + IntStream.of(0xf6, 0xf7, 0xf8, 0xf9, 0xfb, 0xfc)) + .flatMapToInt(i -> i) + .mapToObj(i -> String.format("%02x", i) + ZERO_HEX) + .map(Arguments::arguments); + } + + @ParameterizedTest + @MethodSource("pushTruncatedImmediateArguments") + void testPushTruncatedImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + private static Stream pushTruncatedImmediateArguments() { + return Stream.concat( + Stream.of("60"), + IntStream.range(0, 31) + .mapToObj(i -> String.format("%02x", 0x61 + i) + ZERO_HEX.repeat(i + 1))) + .map(Arguments::arguments); + } + + @ParameterizedTest + @ValueSource(strings = {"5c", "5c00", "5c0000"}) + void testRjumpTruncatedImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + @ParameterizedTest + @ValueSource(strings = {"60015d", "60015d00", "60015d0000"}) + void testRjumpiTruncatedImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + @ParameterizedTest + @ValueSource( + strings = { + "60015e", + "60015e01", + "60015e0100", + "60015e030000", + "60015e0300000001", + "60015e030000000100" + }) + void testRjumpvTruncatedImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + @ParameterizedTest + @ValueSource( + strings = { + "5c000100", + "5cfffc00", + "60015d000100", + "60015dfffa00", + "60015e01000100", + "60015e01fff900" + }) + void testRjumpsOutOfBounds(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + @ParameterizedTest + @MethodSource("rjumpsIntoImmediateExtraArguments") + @ValueSource( + strings = { + // RJUMP into RJUMP immediate + "5cffff00", + "5cfffe00", + "5c00015c000000", + "5c00025c000000", + // RJUMPI into RJUMP immediate + "60015d00015c000000", + "60015d00025c000000", + // RJUMPV into RJUMP immediate + "60015e0100015c000000", + "60015e0100025c000000", + // RJUMP into RJUMPI immediate + "5c000360015d000000", + "5c000460015d000000", + // RJUMPI into RJUMPI immediate + "60015dffff00", + "60015dfffe00", + "60015d000360015d000000", + "60015d000460015d000000", + // RJUMPV into RJUMPI immediate + "60015e01000360015d000000", + "60015e01000460015d000000", + // RJUMP into RJUMPV immediate + "5c00015e01000000", + "5c00025e01000000", + "5c00035e01000000", + // RJUMPI into RJUMPV immediate + "60015d00015e01000000", + "60015d00025e01000000", + "60015d00035e01000000", + // RJUMPV into RJUMPV immediate + "60015e01ffff00", + "60015e01fffe00", + "60015e01fffd00", + "60015e0100015e01000000", + "60015e0100025e01000000", + "60015e0100035e01000000", + "60015e0100015e020000fff400", + "60015e0100025e020000fff400", + "60015e0100035e020000fff400", + "60015e0100045e020000fff400", + "60015e0100055e020000fff400" + }) + void testRjumpsIntoImmediate(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + private static Stream rjumpsIntoImmediateExtraArguments() { + return IntStream.range(1, 33) + .mapToObj( + n -> + IntStream.range(1, n + 1) + .mapToObj( + offset -> + Stream.of( + String.format("5c00%02x", offset) + + // RJUMP offset + String.format("%02x", 0x60 + n - 1) + + // PUSHn + ZERO_HEX.repeat(n) + + // push data + ZERO_HEX, // STOP + String.format("60015d00%02x", offset) + + // PUSH1 1 RJUMI offset + String.format("%02x", 0x60 + n - 1) + + // PUSHn + ZERO_HEX.repeat(n) + + // push data + ZERO_HEX, // STOP + String.format("60015e0100%02x", offset) + + String.format("%02x", 0x60 + n - 1) + + // PUSHn + ZERO_HEX.repeat(n) + + // push data + ZERO_HEX // STOP + ))) + .flatMap(i -> i) + .flatMap(i -> i) + .map(Arguments::arguments); + } + + @ParameterizedTest + @ValueSource(strings = {"60015e0000"}) + void testRjumpvEmptyTable(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNull(); + } + + @ParameterizedTest + @MethodSource("immediateContainsOpcodeArguments") + void testImmediateContainsOpcode(final String code) { + final long[] jumpDest = OpcodesV1.validateAndCalculateJumpDests(Bytes.fromHexString(code)); + assertThat(jumpDest).isNotNull(); + } + + private static Stream immediateContainsOpcodeArguments() { + return Stream.of( + // 0x5c byte which could be interpreted a RJUMP, but it's not because it's in PUSH data + "605c001000", + "61005c001000", + // 0x5d byte which could be interpreted a RJUMPI, but it's not because it's in PUSH data + "605d001000", + "61005d001000", + // 0x5e byte which could be interpreted a RJUMPV, but it's not because it's in PUSH data + "605e01000000", + "61005e01000000", + // 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMP data + // offset = -160 + "5b".repeat(160) + "5cff6000", + // 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMPI + // data + // offset = -160 + "5b".repeat(160) + "5dff6000", + // 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMPV + // data + // offset = -160 + "5b".repeat(160) + "5e01ff6000") + .map(Arguments::arguments); + } }