Search in sources :

Example 1 with UInt256

use of org.apache.tuweni.units.bigints.UInt256 in project hedera-services by hashgraph.

the class HederaSLoadOperation method execute.

@Override
public OperationResult execute(final MessageFrame frame, final EVM evm) {
    try {
        final Account account = frame.getWorldUpdater().get(frame.getRecipientAddress());
        final Address address = account.getAddress();
        final Bytes32 key = UInt256.fromBytes(frame.popStackItem());
        final boolean slotIsWarm = frame.warmUpStorage(address, key);
        final Optional<Gas> optionalCost = slotIsWarm ? warmCost : coldCost;
        if (frame.getRemainingGas().compareTo(optionalCost.orElse(Gas.ZERO)) < 0) {
            return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
        } else {
            UInt256 storageValue = account.getStorageValue(UInt256.fromBytes(key));
            if (dynamicProperties.shouldEnableTraceability()) {
                HederaOperationUtil.cacheExistingValue(frame, address, key, storageValue);
            }
            frame.pushStackItem(storageValue);
            return slotIsWarm ? warmSuccess : coldSuccess;
        }
    } catch (final UnderflowException ufe) {
        return new OperationResult(warmCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS));
    } catch (final OverflowException ofe) {
        return new OperationResult(warmCost, Optional.of(ExceptionalHaltReason.TOO_MANY_STACK_ITEMS));
    }
}
Also used : Account(org.hyperledger.besu.evm.account.Account) Address(org.hyperledger.besu.datatypes.Address) Gas(org.hyperledger.besu.evm.Gas) UnderflowException(org.hyperledger.besu.evm.internal.FixedStack.UnderflowException) OverflowException(org.hyperledger.besu.evm.internal.FixedStack.OverflowException) Bytes32(org.apache.tuweni.bytes.Bytes32) UInt256(org.apache.tuweni.units.bigints.UInt256)

Example 2 with UInt256

use of org.apache.tuweni.units.bigints.UInt256 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 3 with UInt256

use of org.apache.tuweni.units.bigints.UInt256 in project hedera-services by hashgraph.

the class HederaSLoadOperationTest method givenValidContext.

private void givenValidContext(Bytes key, Bytes value) {
    final UInt256 keyBytes = UInt256.fromBytes(key);
    final UInt256 valueBytes = UInt256.fromBytes(value);
    final var recipientAccount = Address.fromHexString("0x0001");
    given(messageFrame.popStackItem()).willReturn(keyBytes).willReturn(valueBytes);
    given(messageFrame.getWorldUpdater()).willReturn(worldUpdater);
    given(messageFrame.getRecipientAddress()).willReturn(recipientAccount);
    given(worldUpdater.get(recipientAccount)).willReturn(evmAccount);
    given(evmAccount.getAddress()).willReturn(Address.fromHexString("0x123"));
    given(gasCalculator.getSloadOperationGasCost()).willReturn(Gas.of(10));
    given(gasCalculator.getWarmStorageReadCost()).willReturn(Gas.of(20));
    given(gasCalculator.getColdSloadCost()).willReturn(Gas.of(10));
}
Also used : UInt256(org.apache.tuweni.units.bigints.UInt256)

Example 4 with UInt256

use of org.apache.tuweni.units.bigints.UInt256 in project hedera-services by hashgraph.

the class HederaSStoreOperationTest method executesWithZero.

@Test
void executesWithZero() {
    final UInt256 keyBytes = UInt256.fromBytes(keyBytesMock);
    final UInt256 valueBytes = UInt256.fromBytes(Bytes.fromHexString("0x12345678"));
    givenValidContext(keyBytes, valueBytes);
    given(mutableAccount.getStorageValue(any())).willReturn(UInt256.ZERO);
    final var expectedExpiry = 20L;
    Deque<MessageFrame> frameDeque = new ArrayDeque<>();
    frameDeque.add(messageFrame);
    given(messageFrame.getMessageFrameStack()).willReturn(frameDeque);
    given(messageFrame.getContextVariable("expiry")).willReturn(OptionalLong.of(expectedExpiry));
    given(messageFrame.getContextVariable("sbh")).willReturn(5L);
    given(messageFrame.getBlockValues()).willReturn(hederaBlockValues);
    given(messageFrame.getGasPrice()).willReturn(Wei.of(50000L));
    given(hederaBlockValues.getTimestamp()).willReturn(10L);
    final var result = subject.execute(messageFrame, evm);
    final var expected = new Operation.OperationResult(Optional.of(Gas.of(10)), Optional.empty());
    assertEquals(expected.getGasCost(), result.getGasCost());
    assertEquals(expected.getHaltReason(), result.getHaltReason());
    verify(mutableAccount).setStorageValue(any(), any());
    verify(messageFrame).storageWasUpdated(any(), any());
}
Also used : MessageFrame(org.hyperledger.besu.evm.frame.MessageFrame) UInt256(org.apache.tuweni.units.bigints.UInt256) ArrayDeque(java.util.ArrayDeque) Test(org.junit.jupiter.api.Test)

Example 5 with UInt256

use of org.apache.tuweni.units.bigints.UInt256 in project hedera-services by hashgraph.

the class HederaSStoreOperationTest method givenValidContext.

private void givenValidContext(Bytes key, Bytes value) {
    final UInt256 keyBytes = UInt256.fromBytes(key);
    final UInt256 valueBytes = UInt256.fromBytes(value);
    final var recipientAccount = Address.fromHexString("0x0001");
    given(messageFrame.popStackItem()).willReturn(keyBytes).willReturn(valueBytes);
    given(messageFrame.getWorldUpdater()).willReturn(worldUpdater);
    given(messageFrame.getRecipientAddress()).willReturn(recipientAccount);
    given(worldUpdater.getAccount(recipientAccount)).willReturn(evmAccount);
    given(evmAccount.getMutable()).willReturn(mutableAccount);
    given(gasCalculator.calculateStorageCost(any(), any(), any())).willReturn(Gas.of(10));
    given(messageFrame.warmUpStorage(any(), any())).willReturn(true);
    given(messageFrame.isStatic()).willReturn(false);
    given(messageFrame.getRemainingGas()).willReturn(Gas.of(300));
    given(mutableAccount.getStorageValue(any())).willReturn(keyBytes);
}
Also used : UInt256(org.apache.tuweni.units.bigints.UInt256)

Aggregations

UInt256 (org.apache.tuweni.units.bigints.UInt256)82 Test (org.junit.Test)22 Address (org.hyperledger.besu.datatypes.Address)18 Hash (org.hyperledger.besu.datatypes.Hash)16 Bytes (org.apache.tuweni.bytes.Bytes)15 Bytes32 (org.apache.tuweni.bytes.Bytes32)10 MutableAccount (org.hyperledger.besu.evm.account.MutableAccount)10 MessageFrame (org.hyperledger.besu.evm.frame.MessageFrame)10 Map (java.util.Map)9 WorldUpdater (org.hyperledger.besu.evm.worldstate.WorldUpdater)9 Test (org.junit.jupiter.api.Test)9 Wei (org.hyperledger.besu.datatypes.Wei)7 MutableWorldState (org.hyperledger.besu.ethereum.core.MutableWorldState)7 Account (org.hyperledger.besu.evm.account.Account)7 BigInteger (java.math.BigInteger)6 HashMap (java.util.HashMap)6 Optional (java.util.Optional)6 ArrayDeque (java.util.ArrayDeque)5 BlockHeader (org.hyperledger.besu.ethereum.core.BlockHeader)5 StateTrieAccountValue (org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue)5