Plumb maxCode overriddes into EVM (#7557)

* Plumb maxCode overriddes into EVM

Restore lost functionality: the maxcodesize and maxinitcodesize should
be plumed into the operations and validation rules when set.

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>
pull/7566/head
Danno Ferrin 3 months ago committed by GitHub
parent d3705506b6
commit 65240fdf46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  3. 2
      ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/eof/EOFReferenceTestTools.java
  4. 18
      evm/src/main/java/org/hyperledger/besu/evm/EVM.java
  5. 10
      evm/src/main/java/org/hyperledger/besu/evm/contractvalidation/MaxCodeSizeRule.java
  6. 17
      evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java
  7. 2
      evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java
  8. 2
      evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnContractOperation.java
  9. 6
      evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java

@ -10,6 +10,7 @@
- Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) - Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485)
### Bug fixes ### Bug fixes
- The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/issues/7557)
## 24.9.0 ## 24.9.0

@ -650,7 +650,7 @@ public abstract class MainnetProtocolSpecs {
TransactionType.FRONTIER, TransactionType.FRONTIER,
TransactionType.ACCESS_LIST, TransactionType.ACCESS_LIST,
TransactionType.EIP1559), TransactionType.EIP1559),
evm.getEvmVersion().getMaxInitcodeSize())) evm.getMaxInitcodeSize()))
.withdrawalsProcessor(new WithdrawalsProcessor()) .withdrawalsProcessor(new WithdrawalsProcessor())
.withdrawalsValidator(new WithdrawalsValidator.AllowedWithdrawals()) .withdrawalsValidator(new WithdrawalsValidator.AllowedWithdrawals())
.name("Shanghai"); .name("Shanghai");
@ -730,7 +730,7 @@ public abstract class MainnetProtocolSpecs {
TransactionType.ACCESS_LIST, TransactionType.ACCESS_LIST,
TransactionType.EIP1559, TransactionType.EIP1559,
TransactionType.BLOB), TransactionType.BLOB),
evm.getEvmVersion().getMaxInitcodeSize())) evm.getMaxInitcodeSize()))
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::cancun) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::cancun)
.blockHeaderValidatorBuilder(MainnetBlockHeaderValidator::cancunBlockHeaderValidator) .blockHeaderValidatorBuilder(MainnetBlockHeaderValidator::cancunBlockHeaderValidator)
.blockHashProcessor(new CancunBlockHashProcessor()) .blockHashProcessor(new CancunBlockHashProcessor())
@ -814,7 +814,7 @@ public abstract class MainnetProtocolSpecs {
TransactionType.EIP1559, TransactionType.EIP1559,
TransactionType.BLOB, TransactionType.BLOB,
TransactionType.SET_CODE), TransactionType.SET_CODE),
evm.getEvmVersion().getMaxInitcodeSize())) evm.getMaxInitcodeSize()))
// EIP-2935 Blockhash processor // EIP-2935 Blockhash processor
.blockHashProcessor(new PragueBlockHashProcessor()) .blockHashProcessor(new PragueBlockHashProcessor())

@ -124,7 +124,7 @@ public class EOFReferenceTestTools {
// hardwire in the magic byte transaction checks // hardwire in the magic byte transaction checks
if (evm.getMaxEOFVersion() < 1) { if (evm.getMaxEOFVersion() < 1) {
assertThat(expected.exception()).isEqualTo("EOF_InvalidCode"); assertThat(expected.exception()).isEqualTo("EOF_InvalidCode");
} else if (code.size() > evm.getEvmVersion().getMaxInitcodeSize()) { } else if (code.size() > evm.getMaxInitcodeSize()) {
// this check is in EOFCREATE and Transaction validator, but unit tests sniff it out. // this check is in EOFCREATE and Transaction validator, but unit tests sniff it out.
assertThat(false) assertThat(false)
.withFailMessage( .withFailMessage(

@ -142,6 +142,24 @@ public class EVM {
return evmSpecVersion.maxEofVersion; return evmSpecVersion.maxEofVersion;
} }
/**
* Gets the max code size, taking configuration and version into account
*
* @return The max code size override, if not set the max code size for the EVM version.
*/
public int getMaxCodeSize() {
return evmConfiguration.maxCodeSizeOverride().orElse(evmSpecVersion.maxCodeSize);
}
/**
* Gets the max initcode Size, taking configuration and version into account
*
* @return The max initcode size override, if not set the max initcode size for the EVM version.
*/
public int getMaxInitcodeSize() {
return evmConfiguration.maxInitcodeSizeOverride().orElse(evmSpecVersion.maxInitcodeSize);
}
/** /**
* Returns the non-fork related configuration parameters of the EVM. * Returns the non-fork related configuration parameters of the EVM.
* *

@ -18,6 +18,7 @@ import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.EvmSpecVersion;
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import java.util.Optional; import java.util.Optional;
@ -75,16 +76,19 @@ public class MaxCodeSizeRule implements ContractValidationRule {
* @return the contract validation rule * @return the contract validation rule
*/ */
public static ContractValidationRule from(final EVM evm) { public static ContractValidationRule from(final EVM evm) {
return from(evm.getEvmVersion()); return from(evm.getEvmVersion(), evm.getEvmConfiguration());
} }
/** /**
* Fluent MaxCodeSizeRule from the EVM it is working with. * Fluent MaxCodeSizeRule from the EVM it is working with.
* *
* @param evmspec The evm spec version to get the size rules from. * @param evmspec The evm spec version to get the size rules from.
* @param evmConfiguration The evm configuration, including overrides
* @return the contract validation rule * @return the contract validation rule
*/ */
public static ContractValidationRule from(final EvmSpecVersion evmspec) { public static ContractValidationRule from(
return new MaxCodeSizeRule(evmspec.getMaxCodeSize()); final EvmSpecVersion evmspec, final EvmConfiguration evmConfiguration) {
return new MaxCodeSizeRule(
evmConfiguration.maxCodeSizeOverride().orElse(evmspec.getMaxCodeSize()));
} }
} }

@ -77,7 +77,9 @@ public class EVMExecutor {
private OperationTracer tracer = OperationTracer.NO_TRACING; private OperationTracer tracer = OperationTracer.NO_TRACING;
private boolean requireDeposit = true; private boolean requireDeposit = true;
private List<ContractValidationRule> contractValidationRules = private List<ContractValidationRule> contractValidationRules =
List.of(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON), PrefixCodeRule.of()); List.of(
MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON, EvmConfiguration.DEFAULT),
PrefixCodeRule.of());
private long initialNonce = 1; private long initialNonce = 1;
private Collection<Address> forceCommitAddresses = List.of(Address.fromHexString("0x03")); private Collection<Address> forceCommitAddresses = List.of(Address.fromHexString("0x03"));
private Set<Address> accessListWarmAddresses = new BytesTrieSet<>(Address.SIZE); private Set<Address> accessListWarmAddresses = new BytesTrieSet<>(Address.SIZE);
@ -241,8 +243,7 @@ public class EVMExecutor {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.spuriousDragon(evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.spuriousDragon(evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.frontier(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.frontier(executor.evm.getGasCalculator());
executor.contractValidationRules = executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm));
List.of(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON));
return executor; return executor;
} }
@ -256,7 +257,7 @@ public class EVMExecutor {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.byzantium(evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.byzantium(evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator());
executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.BYZANTIUM)); executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm));
return executor; return executor;
} }
@ -270,7 +271,7 @@ public class EVMExecutor {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.constantinople(evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.constantinople(evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator());
executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.CONSTANTINOPLE)); executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm));
return executor; return executor;
} }
@ -284,7 +285,7 @@ public class EVMExecutor {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.petersburg(evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.petersburg(evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator());
executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.PETERSBURG)); executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm));
return executor; return executor;
} }
@ -319,7 +320,7 @@ public class EVMExecutor {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.istanbul(chainId, evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.istanbul(chainId, evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.istanbul(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.istanbul(executor.evm.getGasCalculator());
executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.ISTANBUL)); executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm));
return executor; return executor;
} }
@ -354,7 +355,7 @@ public class EVMExecutor {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.berlin(chainId, evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.berlin(chainId, evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.istanbul(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.istanbul(executor.evm.getGasCalculator());
executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.BERLIN)); executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm));
return executor; return executor;
} }

@ -97,7 +97,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
Code code = codeSupplier.get(); Code code = codeSupplier.get();
if (code != null && code.getSize() > evm.getEvmVersion().getMaxInitcodeSize()) { if (code != null && code.getSize() > evm.getMaxInitcodeSize()) {
frame.popStackItems(getStackItemsConsumed()); frame.popStackItems(getStackItemsConsumed());
return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE); return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE);
} }

@ -64,7 +64,7 @@ public class ReturnContractOperation extends AbstractOperation {
} }
Bytes auxData = frame.readMemory(from, length); Bytes auxData = frame.readMemory(from, length);
if (code.getDataSize() + auxData.size() > evm.getEvmVersion().getMaxCodeSize()) { if (code.getDataSize() + auxData.size() > evm.getMaxCodeSize()) {
return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE); return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE);
} }
if (code.getDataSize() + auxData.size() < code.getDeclaredDataSize()) { if (code.getDataSize() + auxData.size() < code.getDeclaredDataSize()) {

@ -206,7 +206,8 @@ class ContractCreationProcessorTest
new ContractCreationProcessor( new ContractCreationProcessor(
evm, evm,
true, true,
Collections.singletonList(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON)), Collections.singletonList(
MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON, EvmConfiguration.DEFAULT)),
1, 1,
Collections.emptyList()); Collections.emptyList());
final Bytes contractCode = final Bytes contractCode =
@ -227,7 +228,8 @@ class ContractCreationProcessorTest
new ContractCreationProcessor( new ContractCreationProcessor(
evm, evm,
true, true,
Collections.singletonList(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON)), Collections.singletonList(
MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON, EvmConfiguration.DEFAULT)),
1, 1,
Collections.emptyList()); Collections.emptyList());
final Bytes contractCode = final Bytes contractCode =

Loading…
Cancel
Save