From 078523df6414b32fb316a43efeab64f2e66053fd Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Wed, 28 Aug 2024 00:41:33 -0600 Subject: [PATCH] Refactor max code size (#7523) * Refactor max code size Refactor the max code size to no longer be a part of the operation but instead is queried from the EVM version specification. Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- .../org/hyperledger/besu/evm/ClassicEVMs.java | 5 ----- .../org/hyperledger/besu/evm/MainnetEVMs.java | 12 ++---------- .../evm/operation/AbstractCreateOperation.java | 8 +------- .../besu/evm/operation/Create2Operation.java | 5 ++--- .../besu/evm/operation/CreateOperation.java | 5 ++--- .../besu/evm/operation/EOFCreateOperation.java | 2 +- .../operation/AbstractCreateOperationTest.java | 7 +++---- .../evm/operation/Create2OperationTest.java | 10 +++------- .../besu/evm/operation/CreateOperationTest.java | 17 +++++++---------- 9 files changed, 21 insertions(+), 50 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java b/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java index 7cd02bbf65a..07b0f2c87f5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java @@ -14,13 +14,10 @@ */ package org.hyperledger.besu.evm; -import static org.hyperledger.besu.evm.MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT; import static org.hyperledger.besu.evm.MainnetEVMs.registerIstanbulOperations; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.Create2Operation; -import org.hyperledger.besu.evm.operation.CreateOperation; import org.hyperledger.besu.evm.operation.OperationRegistry; import org.hyperledger.besu.evm.operation.Push0Operation; @@ -62,8 +59,6 @@ public static OperationRegistry spiralOperations( OperationRegistry registry = new OperationRegistry(); registerIstanbulOperations(registry, gasCalculator, chainId); registry.put(new Push0Operation(gasCalculator)); - registry.put(new CreateOperation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); - registry.put(new Create2Operation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); return registry; } } 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 06ef2da2536..998776d7140 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -147,12 +147,6 @@ public class MainnetEVMs { /** The constant DEV_NET_CHAIN_ID. */ public static final BigInteger DEV_NET_CHAIN_ID = BigInteger.valueOf(1337); - /** The constant SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT. */ - public static final int SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT = 0x6000; - - /** The constant SHANGHAI_INIT_CODE_SIZE_LIMIT. */ - public static final int SHANGHAI_INIT_CODE_SIZE_LIMIT = 2 * SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT; - private MainnetEVMs() { // utility class } @@ -264,7 +258,7 @@ public static void registerFrontierOperations( registry.put(new InvalidOperation(gasCalculator)); registry.put(new StopOperation(gasCalculator)); registry.put(new SelfDestructOperation(gasCalculator)); - registry.put(new CreateOperation(gasCalculator, Integer.MAX_VALUE)); + registry.put(new CreateOperation(gasCalculator)); registry.put(new CallOperation(gasCalculator)); registry.put(new CallCodeOperation(gasCalculator)); @@ -474,7 +468,7 @@ public static OperationRegistry constantinopleOperations(final GasCalculator gas public static void registerConstantinopleOperations( final OperationRegistry registry, final GasCalculator gasCalculator) { registerByzantiumOperations(registry, gasCalculator); - registry.put(new Create2Operation(gasCalculator, Integer.MAX_VALUE)); + registry.put(new Create2Operation(gasCalculator)); registry.put(new SarOperation(gasCalculator)); registry.put(new ShlOperation(gasCalculator)); registry.put(new ShrOperation(gasCalculator)); @@ -809,8 +803,6 @@ public static void registerShanghaiOperations( final BigInteger chainID) { registerParisOperations(registry, gasCalculator, chainID); registry.put(new Push0Operation(gasCalculator)); - registry.put(new CreateOperation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); - registry.put(new Create2Operation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); } /** 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 3bc712341ba..3a78016f2de 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 @@ -45,9 +45,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation { protected static final OperationResult INVALID_OPERATION = new OperationResult(0L, ExceptionalHaltReason.INVALID_OPERATION); - /** The maximum init code size */ - protected final int maxInitcodeSize; - /** The EOF Version this create operation requires initcode to be in */ protected final int eofVersion; @@ -59,7 +56,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation { * @param stackItemsConsumed the stack items consumed * @param stackItemsProduced the stack items produced * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size * @param eofVersion the EOF version this create operation is valid in */ protected AbstractCreateOperation( @@ -68,10 +64,8 @@ protected AbstractCreateOperation( final int stackItemsConsumed, final int stackItemsProduced, final GasCalculator gasCalculator, - final int maxInitcodeSize, final int eofVersion) { super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator); - this.maxInitcodeSize = maxInitcodeSize; this.eofVersion = eofVersion; } @@ -103,7 +97,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { Code code = codeSupplier.get(); - if (code != null && code.getSize() > maxInitcodeSize) { + if (code != null && code.getSize() > evm.getEvmVersion().getMaxInitcodeSize()) { frame.popStackItems(getStackItemsConsumed()); return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE); } 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 1fe3ef6469d..3338a1e26a9 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 @@ -39,10 +39,9 @@ public class Create2Operation extends AbstractCreateOperation { * Instantiates a new Create2 operation. * * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size */ - public Create2Operation(final GasCalculator gasCalculator, final int maxInitcodeSize) { - super(0xF5, "CREATE2", 4, 1, gasCalculator, maxInitcodeSize, 0); + public Create2Operation(final GasCalculator gasCalculator) { + super(0xF5, "CREATE2", 4, 1, gasCalculator, 0); } @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 a82288fff71..9537c5012d2 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 @@ -36,10 +36,9 @@ public class CreateOperation extends AbstractCreateOperation { * Instantiates a new Create operation. * * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size */ - public CreateOperation(final GasCalculator gasCalculator, final int maxInitcodeSize) { - super(0xF0, "CREATE", 3, 1, gasCalculator, maxInitcodeSize, 0); + public CreateOperation(final GasCalculator gasCalculator) { + super(0xF0, "CREATE", 3, 1, gasCalculator, 0); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java index 11d361e54c0..3ea3ef1407f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java @@ -44,7 +44,7 @@ public class EOFCreateOperation extends AbstractCreateOperation { * @param gasCalculator the gas calculator */ public EOFCreateOperation(final GasCalculator gasCalculator) { - super(OPCODE, "EOFCREATE", 4, 1, gasCalculator, Integer.MAX_VALUE, 1); + super(OPCODE, "EOFCREATE", 4, 1, gasCalculator, 1); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java index d066b4e9abf..4c5da84f318 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java @@ -57,7 +57,7 @@ class AbstractCreateOperationTest { private final MutableAccount account = mock(MutableAccount.class); private final MutableAccount newAccount = mock(MutableAccount.class); private final FakeCreateOperation operation = - new FakeCreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); + new FakeCreateOperation(new ConstantinopleGasCalculator()); private static final Bytes SIMPLE_CREATE = Bytes.fromHexString( @@ -100,10 +100,9 @@ public static class FakeCreateOperation extends AbstractCreateOperation { * Instantiates a new Create operation. * * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size */ - public FakeCreateOperation(final GasCalculator gasCalculator, final int maxInitcodeSize) { - super(0xEF, "FAKECREATE", 3, 1, gasCalculator, maxInitcodeSize, 0); + public FakeCreateOperation(final GasCalculator gasCalculator) { + super(0xEF, "FAKECREATE", 3, 1, gasCalculator, 0); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java index a08fd2916fd..4b2a5449ed0 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java @@ -60,11 +60,7 @@ public class Create2OperationTest { private final MutableAccount newAccount = mock(MutableAccount.class); private final Create2Operation operation = - new Create2Operation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); - - private final Create2Operation maxInitCodeOperation = - new Create2Operation( - new ConstantinopleGasCalculator(), MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT); + new Create2Operation(new ConstantinopleGasCalculator()); private static final String TOPIC = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 32 FFs @@ -221,7 +217,7 @@ void shanghaiMaxInitCodeSizeCreate() { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM myEVM = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, myEVM); + var result = operation.execute(messageFrame, myEVM); final MessageFrame createFrame = messageFrame.getMessageFrameStack().peek(); final ContractCreationProcessor ccp = new ContractCreationProcessor(myEVM, false, List.of(), 0, List.of()); @@ -250,7 +246,7 @@ void shanghaiMaxInitCodeSizePlus1Create() { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, evm); + var result = operation.execute(messageFrame, evm); assertThat(result.getHaltReason()).isEqualTo(CODE_TOO_LARGE); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java index c10d8f3d6c8..482df37fd65 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java @@ -52,12 +52,7 @@ class CreateOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); private final MutableAccount newAccount = mock(MutableAccount.class); - private final CreateOperation operation = - new CreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); - private final CreateOperation maxInitCodeOperation = - new CreateOperation( - new ConstantinopleGasCalculator(), MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT); - private final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private final CreateOperation operation = new CreateOperation(new ConstantinopleGasCalculator()); private static final String TOPIC = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 32 FFs @@ -82,7 +77,7 @@ class CreateOperationTest { @Test void createFromMemoryMutationSafe() { - // Given: Execute a CREATE operation with a contract that logs in the constructor + // Given: Execute a CREATE operation with a contract that logs in the constructor final UInt256 memoryOffset = UInt256.fromHexString("0xFF"); final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size()); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); @@ -190,7 +185,7 @@ void shanghaiMaxInitCodeSizeCreate() { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, evm); + var result = operation.execute(messageFrame, evm); final MessageFrame createFrame = messageFrame.getMessageFrameStack().peek(); final ContractCreationProcessor ccp = new ContractCreationProcessor(evm, false, List.of(), 0, List.of()); @@ -218,17 +213,18 @@ void shanghaiMaxInitCodeSizePlus1Create() { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, evm); + var result = operation.execute(messageFrame, evm); assertThat(result.getHaltReason()).isEqualTo(CODE_TOO_LARGE); } @Test void eofV1CannotCall() { + final EVM pragueEvm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); final UInt256 memoryOffset = UInt256.fromHexString("0xFF"); final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size()); final MessageFrame messageFrame = new TestMessageFrameBuilder() - .code(evm.getCodeUncached(SIMPLE_EOF)) + .code(pragueEvm.getCodeUncached(SIMPLE_EOF)) .pushStackItem(memoryLength) .pushStackItem(memoryOffset) .pushStackItem(Bytes.EMPTY) @@ -252,6 +248,7 @@ private MessageFrame testMemoryFrame( final UInt256 memoryLength, final UInt256 value, final int depth) { + final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); final MessageFrame messageFrame = MessageFrame.builder() .type(MessageFrame.Type.CONTRACT_CREATION)