return no code if account has delegated code to precompile, treat precompile always as warm account when resolving code

Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
pull/7717/head
Daniel Lehrner 2 months ago
parent 67bab68118
commit 196bf10413
  1. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  2. 10
      evm/src/main/java/org/hyperledger/besu/evm/account/BaseDelegatedCodeAccount.java
  3. 7
      evm/src/main/java/org/hyperledger/besu/evm/account/DelegatedCodeAccount.java
  4. 7
      evm/src/main/java/org/hyperledger/besu/evm/account/MutableDelegatedCodeAccount.java
  5. 10
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java
  6. 5
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java
  7. 14
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeGasCostHelper.java
  8. 17
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java
  9. 6
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java

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

@ -17,6 +17,7 @@ package org.hyperledger.besu.evm.account;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Optional;
@ -25,13 +26,17 @@ import org.apache.tuweni.bytes.Bytes;
class BaseDelegatedCodeAccount {
private final WorldUpdater worldUpdater;
private final GasCalculator gasCalculator;
/** The address of the account that has delegated code to be loaded into it. */
protected final Address delegatedCodeAddress;
protected BaseDelegatedCodeAccount(
final WorldUpdater worldUpdater, final Address delegatedCodeAddress) {
final WorldUpdater worldUpdater,
final Address delegatedCodeAddress,
final GasCalculator gasCalculator) {
this.worldUpdater = worldUpdater;
this.gasCalculator = gasCalculator;
this.delegatedCodeAddress = delegatedCodeAddress;
}
@ -86,6 +91,9 @@ class BaseDelegatedCodeAccount {
}
private Bytes resolveDelegatedCode() {
if (gasCalculator.isPrecompile(delegatedCodeAddress)) {
return 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.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.NavigableMap;
@ -37,12 +38,14 @@ public class DelegatedCodeAccount extends BaseDelegatedCodeAccount implements Ac
* @param worldUpdater the world updater.
* @param wrappedAccount the account that has delegated code to be loaded into it.
* @param codeDelegationAddress the address of the delegated code.
* @param gasCalculator the gas calculator to check for precompiles.
*/
public DelegatedCodeAccount(
final WorldUpdater worldUpdater,
final Account wrappedAccount,
final Address codeDelegationAddress) {
super(worldUpdater, codeDelegationAddress);
final Address codeDelegationAddress,
final GasCalculator gasCalculator) {
super(worldUpdater, codeDelegationAddress, gasCalculator);
this.wrappedAccount = wrappedAccount;
}

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

@ -666,14 +666,4 @@ public interface GasCalculator {
default long calculateDelegateCodeGasRefund(final long alreadyExistingAccountSize) {
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) {
return existingAccountGasRefund * alreadyExistingAccounts;
}
@Override
public long delegatedCodeResolutionGasCost(final boolean isWarm) {
return isWarm ? getWarmStorageReadCost() : getColdAccountAccessCost();
}
}

@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.evm.worldstate;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.frame.MessageFrame;
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");
}
final boolean delegatedCodeIsWarm = frame.warmUpAddress(account.delegatedCodeAddress().get());
final long delegatedCodeResolutionGas =
gasCalculator.delegatedCodeResolutionGasCost(delegatedCodeIsWarm);
calculateDelegatedCodeResolutionGas(
frame, gasCalculator, account.delegatedCodeAddress().get());
if (frame.getRemainingGas() < delegatedCodeResolutionGas) {
return new Result(delegatedCodeResolutionGas, Status.INSUFFICIENT_GAS);
@ -77,4 +78,13 @@ public class DelegatedCodeGasCostHelper {
frame.decrementRemainingGas(delegatedCodeResolutionGas);
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.MutableAccount;
import org.hyperledger.besu.evm.account.MutableDelegatedCodeAccount;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
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 int DELEGATED_CODE_SIZE = DELEGATED_CODE_PREFIX.size() + Address.SIZE;
/** Creates a new DelegatedCodeService. */
public DelegatedCodeService() {}
private final GasCalculator gasCalculator;
/**
* 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.
@ -64,7 +73,7 @@ public class DelegatedCodeService {
}
return new DelegatedCodeAccount(
worldUpdater, account, resolveDelegatedAddress(account.getCode()));
worldUpdater, account, resolveDelegatedAddress(account.getCode()), gasCalculator);
}
/**
@ -82,7 +91,7 @@ public class DelegatedCodeService {
}
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.MutableAccount;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import java.util.Collection;
import java.util.Optional;
@ -35,9 +36,10 @@ public class EVMWorldUpdater implements WorldUpdater {
* Instantiates a new EVM world updater.
*
* @param rootWorldUpdater the root world updater
* @param gasCalculator the gas calculator to check for precompiles.
*/
public EVMWorldUpdater(final WorldUpdater rootWorldUpdater) {
this(rootWorldUpdater, new DelegatedCodeService());
public EVMWorldUpdater(final WorldUpdater rootWorldUpdater, final GasCalculator gasCalculator) {
this(rootWorldUpdater, new DelegatedCodeService(gasCalculator));
}
private EVMWorldUpdater(

Loading…
Cancel
Save