Search in sources :

Example 1 with HederaWorldUpdater

use of com.hedera.services.store.contracts.HederaWorldUpdater in project hedera-services by hashgraph.

the class HederaCreateOperation method targetContractAddress.

@Override
protected Address targetContractAddress(final MessageFrame frame) {
    final var updater = (HederaWorldUpdater) frame.getWorldUpdater();
    final Address address = updater.newContractAddress(frame.getRecipientAddress());
    frame.warmUpAddress(address);
    return address;
}
Also used : Address(org.hyperledger.besu.datatypes.Address) HederaWorldUpdater(com.hedera.services.store.contracts.HederaWorldUpdater)

Example 2 with HederaWorldUpdater

use of com.hedera.services.store.contracts.HederaWorldUpdater in project hedera-services by hashgraph.

the class HederaOperationUtil method newContractExpiryIn.

/**
 * Returns the expiry to be used for a new contract. Climbs the {@link MessageFrame} and searches for the parent
 * {@link com.hedera.services.store.contracts.HederaWorldState.WorldStateAccount}. The expiry to be used is
 * the expiry of the first account found in the stack
 *
 * @param frame Current message frame
 * @return Expiry to be used for new contracts
 */
public static long newContractExpiryIn(MessageFrame frame) {
    long expiry = 0;
    HederaWorldState.WorldStateAccount hederaAccount;
    Iterator<MessageFrame> framesIterator = frame.getMessageFrameStack().iterator();
    MessageFrame messageFrame;
    while (framesIterator.hasNext()) {
        messageFrame = framesIterator.next();
        /* if this is the initial frame from the deque, check context vars first */
        if (!framesIterator.hasNext()) {
            OptionalLong expiryOptional = messageFrame.getContextVariable("expiry");
            if (expiryOptional.isPresent()) {
                expiry = expiryOptional.getAsLong();
                break;
            }
        }
        /* check if this messageFrame's sender account can be retrieved from state */
        final var updater = (HederaWorldUpdater) messageFrame.getWorldUpdater();
        hederaAccount = updater.getHederaAccount(frame.getSenderAddress());
        if (hederaAccount != null) {
            expiry = hederaAccount.getExpiry();
            break;
        }
    }
    return expiry;
}
Also used : HederaWorldUpdater(com.hedera.services.store.contracts.HederaWorldUpdater) MessageFrame(org.hyperledger.besu.evm.frame.MessageFrame) HederaWorldState(com.hedera.services.store.contracts.HederaWorldState) OptionalLong(java.util.OptionalLong)

Example 3 with HederaWorldUpdater

use of com.hedera.services.store.contracts.HederaWorldUpdater 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)

Aggregations

HederaWorldUpdater (com.hedera.services.store.contracts.HederaWorldUpdater)3 HederaWorldState (com.hedera.services.store.contracts.HederaWorldState)2 Address (org.hyperledger.besu.datatypes.Address)2 OptionalLong (java.util.OptionalLong)1 UInt256 (org.apache.tuweni.units.bigints.UInt256)1 Wei (org.hyperledger.besu.datatypes.Wei)1 Gas (org.hyperledger.besu.evm.Gas)1 MutableAccount (org.hyperledger.besu.evm.account.MutableAccount)1 MessageFrame (org.hyperledger.besu.evm.frame.MessageFrame)1