Search in sources :

Example 6 with Gas

use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.

the class HederaSStoreOperation method execute.

@Override
public Operation.OperationResult execute(final MessageFrame frame, final EVM evm) {
    final UInt256 key = UInt256.fromBytes(frame.popStackItem());
    final UInt256 value = UInt256.fromBytes(frame.popStackItem());
    final MutableAccount account = frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getMutable();
    if (account == null) {
        return ILLEGAL_STATE_CHANGE;
    }
    UInt256 currentValue = account.getStorageValue(key);
    boolean currentZero = currentValue.isZero();
    boolean newZero = value.isZero();
    boolean checkCalculator = checkSuperCost;
    Gas gasCost = Gas.ZERO;
    if (currentZero && !newZero) {
        final var updater = (HederaWorldUpdater) frame.getWorldUpdater();
        HederaWorldState.WorldStateAccount hederaAccount = updater.getHederaAccount(frame.getRecipientAddress());
        long durationInSeconds = Math.max(0, (hederaAccount != null ? hederaAccount.getExpiry() : HederaOperationUtil.newContractExpiryIn(frame)) - frame.getBlockValues().getTimestamp());
        long sbh = frame.getMessageFrameStack().getLast().getContextVariable("sbh");
        Wei gasPrice = frame.getGasPrice();
        gasCost = Gas.of(calculateStorageGasNeeded(64, /*two 256-bit words*/
        durationInSeconds, sbh, gasPrice.toLong()));
        ((HederaWorldUpdater) frame.getWorldUpdater()).addSbhRefund(gasCost);
    } else {
        checkCalculator = true;
    }
    if (checkCalculator) {
        Address address = account.getAddress();
        boolean slotIsWarm = frame.warmUpStorage(address, key);
        gasCost = gasCost.max(gasCalculator().calculateStorageCost(account, key, value).plus(slotIsWarm ? Gas.ZERO : this.gasCalculator().getColdSloadCost()));
        frame.incrementGasRefund(gasCalculator().calculateStorageRefundAmount(account, key, value));
    }
    Optional<Gas> optionalCost = Optional.of(gasCost);
    final Gas remainingGas = frame.getRemainingGas();
    if (frame.isStatic()) {
        return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.ILLEGAL_STATE_CHANGE));
    } else if (remainingGas.compareTo(gasCost) < 0) {
        return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
    }
    if (dynamicProperties.shouldEnableTraceability()) {
        HederaOperationUtil.cacheExistingValue(frame, account.getAddress(), key, currentValue);
    }
    account.setStorageValue(key, value);
    frame.storageWasUpdated(key, value);
    return new Operation.OperationResult(optionalCost, Optional.empty());
}
Also used : Address(org.hyperledger.besu.datatypes.Address) HederaWorldState(com.hedera.services.store.contracts.HederaWorldState) HederaWorldUpdater(com.hedera.services.store.contracts.HederaWorldUpdater) Gas(org.hyperledger.besu.evm.Gas) MutableAccount(org.hyperledger.besu.evm.account.MutableAccount) Wei(org.hyperledger.besu.datatypes.Wei) UInt256(org.apache.tuweni.units.bigints.UInt256)

Example 7 with Gas

use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.

the class EvmTxProcessor method calculateGasUsedByTX.

private Gas calculateGasUsedByTX(final long txGasLimit, final MessageFrame initialFrame) {
    Gas gasUsedByTransaction = Gas.of(txGasLimit).minus(initialFrame.getRemainingGas());
    /* Return leftover gas */
    final Gas selfDestructRefund = gasCalculator.getSelfDestructRefundAmount().times(initialFrame.getSelfDestructs().size()).min(gasUsedByTransaction.dividedBy(gasCalculator.getMaxRefundQuotient()));
    gasUsedByTransaction = gasUsedByTransaction.minus(selfDestructRefund).minus(initialFrame.getGasRefund());
    final var maxRefundPercent = dynamicProperties.maxGasRefundPercentage();
    gasUsedByTransaction = Gas.of(Math.max(gasUsedByTransaction.toLong(), txGasLimit - txGasLimit * maxRefundPercent / 100));
    return gasUsedByTransaction;
}
Also used : Gas(org.hyperledger.besu.evm.Gas)

Example 8 with Gas

use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.

the class HederaMessageCallProcessor method executeHederaPrecompile.

void executeHederaPrecompile(final PrecompiledContract contract, final MessageFrame frame, final OperationTracer operationTracer) {
    // EVM value transfers are not allowed
    if (!Objects.equals(Wei.ZERO, frame.getValue())) {
        frame.setRevertReason(INVALID_TRANSFER);
        frame.setState(REVERT);
        return;
    }
    final Bytes output = contract.compute(frame.getInputData(), frame);
    final Gas gasRequirement = contract.gasRequirement(frame.getInputData());
    operationTracer.tracePrecompileCall(frame, gasRequirement, output);
    if (frame.getRemainingGas().compareTo(gasRequirement) < 0) {
        frame.decrementRemainingGas(frame.getRemainingGas());
        frame.setExceptionalHaltReason(Optional.of(INSUFFICIENT_GAS));
        frame.setState(EXCEPTIONAL_HALT);
    } else if (output != null) {
        frame.decrementRemainingGas(gasRequirement);
        frame.setOutputData(output);
        frame.setState(COMPLETED_SUCCESS);
    } else {
        frame.setState(EXCEPTIONAL_HALT);
    }
}
Also used : Bytes(org.apache.tuweni.bytes.Bytes) Gas(org.hyperledger.besu.evm.Gas)

Example 9 with Gas

use of org.hyperledger.besu.evm.Gas in project besu by hyperledger.

the class MessageCallProcessor method executePrecompile.

/**
 * Executes this message call knowing that it is a call to the provided pre-compiled contract.
 *
 * @param contract The contract this is a message call to.
 */
private void executePrecompile(final PrecompiledContract contract, final MessageFrame frame, final OperationTracer operationTracer) {
    final Gas gasRequirement = contract.gasRequirement(frame.getInputData());
    if (frame.getRemainingGas().compareTo(gasRequirement) < 0) {
        LOG.trace("Not enough gas available for pre-compiled contract code {}: requiring " + "{} but only {} gas available", contract, gasRequirement, frame.getRemainingGas());
        frame.setExceptionalHaltReason(Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
        frame.setState(MessageFrame.State.EXCEPTIONAL_HALT);
    } else {
        frame.decrementRemainingGas(gasRequirement);
        final PrecompiledContract.PrecompileContractResult result = contract.computePrecompile(frame.getInputData(), frame);
        operationTracer.tracePrecompileCall(frame, gasRequirement, result.getOutput());
        if (result.isRefundGas()) {
            frame.incrementRemainingGas(gasRequirement);
        }
        if (frame.getState() == MessageFrame.State.REVERT) {
            frame.setRevertReason(result.getOutput());
        } else {
            frame.setOutputData(result.getOutput());
        }
        frame.setState(result.getState());
        frame.setExceptionalHaltReason(result.getHaltReason());
        LOG.trace("Precompiled contract {} {} (gasComsumed: {})", contract.getName(), result.getState(), result.isRefundGas() ? Gas.ZERO : gasRequirement);
    }
}
Also used : PrecompiledContract(org.hyperledger.besu.evm.precompile.PrecompiledContract) Gas(org.hyperledger.besu.evm.Gas)

Example 10 with Gas

use of org.hyperledger.besu.evm.Gas in project besu by hyperledger.

the class MainnetTransactionProcessor method refunded.

protected Gas refunded(final Transaction transaction, final Gas gasRemaining, final Gas gasRefund) {
    // Integer truncation takes care of the the floor calculation needed after the divide.
    final Gas maxRefundAllowance = Gas.of(transaction.getGasLimit()).minus(gasRemaining).dividedBy(gasCalculator.getMaxRefundQuotient());
    final Gas refundAllowance = maxRefundAllowance.min(gasRefund);
    return gasRemaining.plus(refundAllowance);
}
Also used : Gas(org.hyperledger.besu.evm.Gas)

Aggregations

Gas (org.hyperledger.besu.evm.Gas)29 Address (org.hyperledger.besu.datatypes.Address)6 Bytes (org.apache.tuweni.bytes.Bytes)5 Wei (org.hyperledger.besu.datatypes.Wei)4 MutableAccount (org.hyperledger.besu.evm.account.MutableAccount)4 UInt256 (org.apache.tuweni.units.bigints.UInt256)3 MessageFrame (org.hyperledger.besu.evm.frame.MessageFrame)3 HederaWorldState (com.hedera.services.store.contracts.HederaWorldState)2 HederaWorldUpdater (com.hedera.services.store.contracts.HederaWorldUpdater)2 ImmutableList (com.google.common.collect.ImmutableList)1 InvalidTransactionException (com.hedera.services.exceptions.InvalidTransactionException)1 HederaStackedWorldStateUpdater (com.hedera.services.store.contracts.HederaStackedWorldStateUpdater)1 ArrayDeque (java.util.ArrayDeque)1 Map (java.util.Map)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1 BadBlockManager (org.hyperledger.besu.ethereum.chain.BadBlockManager)1 MutableWorldState (org.hyperledger.besu.ethereum.core.MutableWorldState)1 MutableProtocolSchedule (org.hyperledger.besu.ethereum.mainnet.MutableProtocolSchedule)1 ProtocolSpec (org.hyperledger.besu.ethereum.mainnet.ProtocolSpec)1 PrivateTransactionValidator (org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator)1