From f19e24279753b2a99af03b5f4f645961b632adca Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Fri, 30 Aug 2024 07:58:40 -0600 Subject: [PATCH] moar unit tests Signed-off-by: Danno Ferrin --- .../besu/evm/operation/ExtCallOperation.java | 5 ++- .../operation/ExtDelegateCallOperation.java | 5 ++- .../evm/operation/ExtStaticCallOperation.java | 5 ++- .../evm/operation/ExtCallOperationTest.java | 31 ++++++++++++++++++ .../ExtDelegateCallOperationTest.java | 32 +++++++++++++++++++ .../operation/ExtStaticCallOperationTest.java | 32 +++++++++++++++++++ 6 files changed, 107 insertions(+), 3 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java index 5914f0e966a..7fc41ac85c5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java @@ -24,6 +24,9 @@ /** The Call operation. */ public class ExtCallOperation extends AbstractExtCallOperation { + /** The constant OPCODE. */ + public static final int OPCODE = 0xF8; + static final int STACK_VALUE = 3; /** @@ -32,7 +35,7 @@ public class ExtCallOperation extends AbstractExtCallOperation { * @param gasCalculator the gas calculator */ public ExtCallOperation(final GasCalculator gasCalculator) { - super(0xF8, "EXTCALL", 4, 1, gasCalculator); + super(OPCODE, "EXTCALL", 4, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java index db851ee5a0b..49b0a2a54af 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java @@ -24,13 +24,16 @@ /** The Delegate call operation. */ public class ExtDelegateCallOperation extends AbstractExtCallOperation { + /** The constant OPCODE. */ + public static final int OPCODE = 0xF9; + /** * Instantiates a new Delegate call operation. * * @param gasCalculator the gas calculator */ public ExtDelegateCallOperation(final GasCalculator gasCalculator) { - super(0xF9, "EXTDELEGATECALL", 3, 1, gasCalculator); + super(OPCODE, "EXTDELEGATECALL", 3, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java index ef3dc042d9c..7413213779f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java @@ -24,13 +24,16 @@ /** The Static call operation. */ public class ExtStaticCallOperation extends AbstractExtCallOperation { + /** The constant OPCODE. */ + public static final int OPCODE = 0xFB; + /** * Instantiates a new Static call operation. * * @param gasCalculator the gas calculator */ public ExtStaticCallOperation(final GasCalculator gasCalculator) { - super(0xFB, "EXTSTATICCALL", 3, 1, gasCalculator); + super(OPCODE, "EXTSTATICCALL", 3, 1, gasCalculator); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java index 237b7ae13e0..93b10115015 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java @@ -45,6 +45,8 @@ public class ExtCallOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + public static final Code LEGACY_CODE = + EOF_EVM.getCodeUncached(Bytes.of(ExtCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = EOF_EVM.getCodeUncached(Bytes.fromHexString("0xEF00010100040200010001040000000080000000")); public static final Code INVALID_EOF = @@ -276,4 +278,33 @@ void overflowTest() { assertThat(parentFrame.getStackItem(0)) .isEqualTo(AbstractExtCallOperation.EOF1_EXCEPTION_STACK_ITEM); } + + @Test + void legacyTest() { + final ExtCallOperation operation = new ExtCallOperation(new PragueEOFGasCalculator()); + + final var messageFrame = + new TestMessageFrameBuilder() + .initialGas(400000) + .code(LEGACY_CODE) + .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(CONTRACT_ADDRESS) + .worldUpdater(worldUpdater) + .build(); + messageFrame.warmUpAddress(CONTRACT_ADDRESS); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getCodeHash()).thenReturn(SIMPLE_EOF.getCodeHash()); + when(account.getCode()).thenReturn(SIMPLE_EOF.getBytes()); + when(worldUpdater.get(any())).thenReturn(account); + when(worldUpdater.getAccount(any())).thenReturn(account); + when(worldUpdater.updater()).thenReturn(worldUpdater); + + var result = operation.execute(messageFrame, EOF_EVM); + + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java index 4e932788b3e..62a10dcc2d7 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java @@ -46,6 +46,8 @@ public class ExtDelegateCallOperationTest { private final MutableAccount account = mock(MutableAccount.class); // private final MutableAccount targetAccount = mock(MutableAccount.class); private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + public static final Code LEGACY_CODE = + EOF_EVM.getCodeUncached(Bytes.of(ExtDelegateCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = EOF_EVM.getCodeUncached(Bytes.fromHexString("0xEF00010100040200010001040000000080000000")); public static final Code SIMPLE_LEGACY = EOF_EVM.getCodeUncached(Bytes.fromHexString("0x00")); @@ -259,4 +261,34 @@ void overflowTest() { assertThat(parentFrame.getStackItem(0)) .isEqualTo(AbstractExtCallOperation.EOF1_EXCEPTION_STACK_ITEM); } + + @Test + void legacyTest() { + final ExtDelegateCallOperation operation = + new ExtDelegateCallOperation(new PragueEOFGasCalculator()); + + final var messageFrame = + new TestMessageFrameBuilder() + .initialGas(400000) + .code(LEGACY_CODE) + .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(CONTRACT_ADDRESS) + .worldUpdater(worldUpdater) + .build(); + messageFrame.warmUpAddress(CONTRACT_ADDRESS); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getCodeHash()).thenReturn(SIMPLE_EOF.getCodeHash()); + when(account.getCode()).thenReturn(SIMPLE_EOF.getBytes()); + when(worldUpdater.get(any())).thenReturn(account); + when(worldUpdater.getAccount(any())).thenReturn(account); + when(worldUpdater.updater()).thenReturn(worldUpdater); + + var result = operation.execute(messageFrame, EOF_EVM); + + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java index 2488764c5b6..ed306e89c7d 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java @@ -45,6 +45,8 @@ public class ExtStaticCallOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + public static final Code LEGACY_CODE = + EOF_EVM.getCodeUncached(Bytes.of(ExtStaticCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = EOF_EVM.getCodeUncached(Bytes.fromHexString("0xEF00010100040200010001040000000080000000")); public static final Code INVALID_EOF = @@ -185,4 +187,34 @@ void overflowTest() { assertThat(parentFrame.getStackItem(0)) .isEqualTo(AbstractExtCallOperation.EOF1_EXCEPTION_STACK_ITEM); } + + @Test + void legacyTest() { + final ExtStaticCallOperation operation = + new ExtStaticCallOperation(new PragueEOFGasCalculator()); + + final var messageFrame = + new TestMessageFrameBuilder() + .initialGas(400000) + .code(LEGACY_CODE) + .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(CONTRACT_ADDRESS) + .worldUpdater(worldUpdater) + .build(); + messageFrame.warmUpAddress(CONTRACT_ADDRESS); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getCodeHash()).thenReturn(SIMPLE_EOF.getCodeHash()); + when(account.getCode()).thenReturn(SIMPLE_EOF.getBytes()); + when(worldUpdater.get(any())).thenReturn(account); + when(worldUpdater.getAccount(any())).thenReturn(account); + when(worldUpdater.updater()).thenReturn(worldUpdater); + + var result = operation.execute(messageFrame, EOF_EVM); + + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } }