Merge branch 'fix/issue-7706/warmup_to_when_delegated' into pectra-devnet3-block-110500-issue

pectra-devnet3-block-110500-issue
Daniel Lehrner 1 month ago
commit dcefdce450
  1. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  2. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
  3. 10
      evm/src/main/java/org/hyperledger/besu/evm/account/BaseDelegatedCodeAccount.java
  4. 7
      evm/src/main/java/org/hyperledger/besu/evm/account/DelegatedCodeAccount.java
  5. 7
      evm/src/main/java/org/hyperledger/besu/evm/account/MutableDelegatedCodeAccount.java
  6. 10
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java
  7. 5
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java
  8. 14
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeGasCostHelper.java
  9. 17
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java
  10. 6
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java

@ -286,7 +286,7 @@ public class MainnetTransactionProcessor {
final TransactionValidationParams transactionValidationParams, final TransactionValidationParams transactionValidationParams,
final PrivateMetadataUpdater privateMetadataUpdater, final PrivateMetadataUpdater privateMetadataUpdater,
final Wei blobGasPrice) { final Wei blobGasPrice) {
final EVMWorldUpdater evmWorldUpdater = new EVMWorldUpdater(worldState); final EVMWorldUpdater evmWorldUpdater = new EVMWorldUpdater(worldState, gasCalculator);
try { try {
final var transactionValidator = transactionValidatorFactory.get(); final var transactionValidator = transactionValidatorFactory.get();
LOG.trace("Starting execution of {}", transaction); LOG.trace("Starting execution of {}", transaction);
@ -444,6 +444,7 @@ public class MainnetTransactionProcessor {
@SuppressWarnings("OptionalGetWithoutIsPresent") // isContractCall tests isPresent @SuppressWarnings("OptionalGetWithoutIsPresent") // isContractCall tests isPresent
final Address to = transaction.getTo().get(); final Address to = transaction.getTo().get();
final Optional<Account> maybeContract = Optional.ofNullable(evmWorldUpdater.get(to)); final Optional<Account> maybeContract = Optional.ofNullable(evmWorldUpdater.get(to));
initialFrame = initialFrame =
commonMessageFrameBuilder commonMessageFrameBuilder
.type(MessageFrame.Type.MESSAGE_CALL) .type(MessageFrame.Type.MESSAGE_CALL)

@ -177,6 +177,12 @@ public class MainnetTransactionValidator implements TransactionValidator {
"Invalid signature for code delegation. S value must be less or equal than the half curve order."); "Invalid signature for code delegation. S value must be less or equal than the half curve order.");
} }
if (codeDelegation.nonce() == MAX_NONCE) {
return ValidationResult.invalid(
TransactionInvalidReason.NONCE_OVERFLOW,
"Nonce of code delegation must be less than 2^64-1");
}
if (codeDelegation.signature().getRecId() != 0 if (codeDelegation.signature().getRecId() != 0
&& codeDelegation.signature().getRecId() != 1) { && codeDelegation.signature().getRecId() != 1) {
return ValidationResult.invalid( return ValidationResult.invalid(

@ -17,6 +17,7 @@ package org.hyperledger.besu.evm.account;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Optional; import java.util.Optional;
@ -25,13 +26,17 @@ import org.apache.tuweni.bytes.Bytes;
class BaseDelegatedCodeAccount { class BaseDelegatedCodeAccount {
private final WorldUpdater worldUpdater; private final WorldUpdater worldUpdater;
private final GasCalculator gasCalculator;
/** The address of the account that has delegated code to be loaded into it. */ /** The address of the account that has delegated code to be loaded into it. */
protected final Address delegatedCodeAddress; protected final Address delegatedCodeAddress;
protected BaseDelegatedCodeAccount( protected BaseDelegatedCodeAccount(
final WorldUpdater worldUpdater, final Address delegatedCodeAddress) { final WorldUpdater worldUpdater,
final Address delegatedCodeAddress,
final GasCalculator gasCalculator) {
this.worldUpdater = worldUpdater; this.worldUpdater = worldUpdater;
this.gasCalculator = gasCalculator;
this.delegatedCodeAddress = delegatedCodeAddress; this.delegatedCodeAddress = delegatedCodeAddress;
} }
@ -86,6 +91,9 @@ class BaseDelegatedCodeAccount {
} }
private Bytes resolveDelegatedCode() { private Bytes resolveDelegatedCode() {
if (gasCalculator.isPrecompile(delegatedCodeAddress)) {
return Bytes.EMPTY;
}
return getDelegatedAccount().map(Account::getUnprocessedCode).orElse(Bytes.EMPTY); return getDelegatedAccount().map(Account::getUnprocessedCode).orElse(Bytes.EMPTY);
} }

@ -17,6 +17,7 @@ package org.hyperledger.besu.evm.account;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.NavigableMap; import java.util.NavigableMap;
@ -37,12 +38,14 @@ public class DelegatedCodeAccount extends BaseDelegatedCodeAccount implements Ac
* @param worldUpdater the world updater. * @param worldUpdater the world updater.
* @param wrappedAccount the account that has delegated code to be loaded into it. * @param wrappedAccount the account that has delegated code to be loaded into it.
* @param codeDelegationAddress the address of the delegated code. * @param codeDelegationAddress the address of the delegated code.
* @param gasCalculator the gas calculator to check for precompiles.
*/ */
public DelegatedCodeAccount( public DelegatedCodeAccount(
final WorldUpdater worldUpdater, final WorldUpdater worldUpdater,
final Account wrappedAccount, final Account wrappedAccount,
final Address codeDelegationAddress) { final Address codeDelegationAddress,
super(worldUpdater, codeDelegationAddress); final GasCalculator gasCalculator) {
super(worldUpdater, codeDelegationAddress, gasCalculator);
this.wrappedAccount = wrappedAccount; this.wrappedAccount = wrappedAccount;
} }

@ -17,6 +17,7 @@ package org.hyperledger.besu.evm.account;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Map; import java.util.Map;
@ -39,12 +40,14 @@ public class MutableDelegatedCodeAccount extends BaseDelegatedCodeAccount
* @param worldUpdater the world updater. * @param worldUpdater the world updater.
* @param wrappedAccount the account that has delegated code to be loaded into it. * @param wrappedAccount the account that has delegated code to be loaded into it.
* @param codeDelegationAddress the address of the delegated code. * @param codeDelegationAddress the address of the delegated code.
* @param gasCalculator the gas calculator to check for precompiles.
*/ */
public MutableDelegatedCodeAccount( public MutableDelegatedCodeAccount(
final WorldUpdater worldUpdater, final WorldUpdater worldUpdater,
final MutableAccount wrappedAccount, final MutableAccount wrappedAccount,
final Address codeDelegationAddress) { final Address codeDelegationAddress,
super(worldUpdater, codeDelegationAddress); final GasCalculator gasCalculator) {
super(worldUpdater, codeDelegationAddress, gasCalculator);
this.wrappedAccount = wrappedAccount; this.wrappedAccount = wrappedAccount;
} }

@ -666,14 +666,4 @@ public interface GasCalculator {
default long calculateDelegateCodeGasRefund(final long alreadyExistingAccountSize) { default long calculateDelegateCodeGasRefund(final long alreadyExistingAccountSize) {
return 0L; return 0L;
} }
/**
* Returns the gas cost for resolving the code of a delegate account.
*
* @param isWarm whether the account is warm
* @return the gas cost
*/
default long delegatedCodeResolutionGasCost(final boolean isWarm) {
return 0L;
}
} }

@ -52,9 +52,4 @@ public class PragueGasCalculator extends CancunGasCalculator {
public long calculateDelegateCodeGasRefund(final long alreadyExistingAccounts) { public long calculateDelegateCodeGasRefund(final long alreadyExistingAccounts) {
return existingAccountGasRefund * alreadyExistingAccounts; return existingAccountGasRefund * alreadyExistingAccounts;
} }
@Override
public long delegatedCodeResolutionGasCost(final boolean isWarm) {
return isWarm ? getWarmStorageReadCost() : getColdAccountAccessCost();
}
} }

@ -14,6 +14,7 @@
*/ */
package org.hyperledger.besu.evm.worldstate; package org.hyperledger.besu.evm.worldstate;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator;
@ -66,9 +67,9 @@ public class DelegatedCodeGasCostHelper {
throw new RuntimeException("A delegated code account must have a delegated code address"); throw new RuntimeException("A delegated code account must have a delegated code address");
} }
final boolean delegatedCodeIsWarm = frame.warmUpAddress(account.delegatedCodeAddress().get());
final long delegatedCodeResolutionGas = final long delegatedCodeResolutionGas =
gasCalculator.delegatedCodeResolutionGasCost(delegatedCodeIsWarm); calculateDelegatedCodeResolutionGas(
frame, gasCalculator, account.delegatedCodeAddress().get());
if (frame.getRemainingGas() < delegatedCodeResolutionGas) { if (frame.getRemainingGas() < delegatedCodeResolutionGas) {
return new Result(delegatedCodeResolutionGas, Status.INSUFFICIENT_GAS); return new Result(delegatedCodeResolutionGas, Status.INSUFFICIENT_GAS);
@ -77,4 +78,13 @@ public class DelegatedCodeGasCostHelper {
frame.decrementRemainingGas(delegatedCodeResolutionGas); frame.decrementRemainingGas(delegatedCodeResolutionGas);
return new Result(delegatedCodeResolutionGas, Status.SUCCESS); return new Result(delegatedCodeResolutionGas, Status.SUCCESS);
} }
private static long calculateDelegatedCodeResolutionGas(
final MessageFrame frame, final GasCalculator gasCalculator, final Address delegateeAddress) {
final boolean delegatedCodeIsWarm =
frame.warmUpAddress(delegateeAddress) || gasCalculator.isPrecompile(delegateeAddress);
return delegatedCodeIsWarm
? gasCalculator.getWarmStorageReadCost()
: gasCalculator.getColdAccountAccessCost();
}
} }

@ -19,6 +19,7 @@ import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.DelegatedCodeAccount; import org.hyperledger.besu.evm.account.DelegatedCodeAccount;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.account.MutableDelegatedCodeAccount; import org.hyperledger.besu.evm.account.MutableDelegatedCodeAccount;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
@ -27,8 +28,16 @@ public class DelegatedCodeService {
private static final Bytes DELEGATED_CODE_PREFIX = Bytes.fromHexString("ef0100"); private static final Bytes DELEGATED_CODE_PREFIX = Bytes.fromHexString("ef0100");
private static final int DELEGATED_CODE_SIZE = DELEGATED_CODE_PREFIX.size() + Address.SIZE; private static final int DELEGATED_CODE_SIZE = DELEGATED_CODE_PREFIX.size() + Address.SIZE;
/** Creates a new DelegatedCodeService. */ private final GasCalculator gasCalculator;
public DelegatedCodeService() {}
/**
* Creates a new DelegatedCodeService.
*
* @param gasCalculator the gas calculator to check for pre compiles.
*/
public DelegatedCodeService(final GasCalculator gasCalculator) {
this.gasCalculator = gasCalculator;
}
/** /**
* Add the delegated code to the given account. * Add the delegated code to the given account.
@ -64,7 +73,7 @@ public class DelegatedCodeService {
} }
return new DelegatedCodeAccount( return new DelegatedCodeAccount(
worldUpdater, account, resolveDelegatedAddress(account.getCode())); worldUpdater, account, resolveDelegatedAddress(account.getCode()), gasCalculator);
} }
/** /**
@ -82,7 +91,7 @@ public class DelegatedCodeService {
} }
return new MutableDelegatedCodeAccount( return new MutableDelegatedCodeAccount(
worldUpdater, account, resolveDelegatedAddress(account.getCode())); worldUpdater, account, resolveDelegatedAddress(account.getCode()), gasCalculator);
} }
/** /**

@ -19,6 +19,7 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
@ -35,9 +36,10 @@ public class EVMWorldUpdater implements WorldUpdater {
* Instantiates a new EVM world updater. * Instantiates a new EVM world updater.
* *
* @param rootWorldUpdater the root world updater * @param rootWorldUpdater the root world updater
* @param gasCalculator the gas calculator to check for precompiles.
*/ */
public EVMWorldUpdater(final WorldUpdater rootWorldUpdater) { public EVMWorldUpdater(final WorldUpdater rootWorldUpdater, final GasCalculator gasCalculator) {
this(rootWorldUpdater, new DelegatedCodeService()); this(rootWorldUpdater, new DelegatedCodeService(gasCalculator));
} }
private EVMWorldUpdater( private EVMWorldUpdater(

Loading…
Cancel
Save