Skip to content

Commit

Permalink
Refactor max code size (hyperledger#7523)
Browse files Browse the repository at this point in the history
* 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 <danno@numisight.com>

---------

Signed-off-by: Danno Ferrin <danno@numisight.com>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
  • Loading branch information
shemnon and macfarla authored Aug 28, 2024
1 parent 5eb6700 commit 078523d
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 50 deletions.
5 changes: 0 additions & 5 deletions evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
}
12 changes: 2 additions & 10 deletions evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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(
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 078523d

Please sign in to comment.