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