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));
}
}
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());
}
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));
}
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());
}
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);
}
Aggregations