use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.
the class GasCalculatorHederaV22 method transactionIntrinsicGasCost.
@Override
public Gas transactionIntrinsicGasCost(final Bytes payload, final boolean isContractCreation) {
int zeros = 0;
for (int i = 0; i < payload.size(); i++) {
if (payload.get(i) == 0) {
++zeros;
}
}
final int nonZeros = payload.size() - zeros;
Gas cost = TX_BASE_COST.plus(TX_DATA_ZERO_COST.times(zeros)).plus(ISTANBUL_TX_DATA_NON_ZERO_COST.times(nonZeros));
return isContractCreation ? cost.plus(txCreateExtraGasCost()) : cost;
}
use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.
the class AbstractRecordingCreateOperation method execute.
@Override
public Operation.OperationResult execute(final MessageFrame frame, final EVM evm) {
// We have a feature flag for CREATE2
if (!isEnabled()) {
return INVALID_RESPONSE;
}
// manual check because some reads won't come until the "complete" step.
if (frame.stackSize() < getStackItemsConsumed()) {
return UNDERFLOW_RESPONSE;
}
final Gas cost = cost(frame);
final Optional<Gas> optionalCost = Optional.ofNullable(cost);
if (cost != null) {
if (frame.isStatic()) {
return haltWith(optionalCost, ILLEGAL_STATE_CHANGE);
} else if (frame.getRemainingGas().compareTo(cost) < 0) {
return new Operation.OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
}
final Wei value = Wei.wrap(frame.getStackItem(0));
final Address address = frame.getRecipientAddress();
final MutableAccount account = frame.getWorldUpdater().getAccount(address).getMutable();
frame.clearReturnData();
if (value.compareTo(account.getBalance()) > 0 || frame.getMessageStackDepth() >= MAX_STACK_DEPTH) {
fail(frame);
} else {
spawnChildMessage(frame);
}
}
return new Operation.OperationResult(optionalCost, Optional.empty());
}
use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.
the class AbstractRecordingCreateOperation method spawnChildMessage.
private void spawnChildMessage(final MessageFrame frame) {
// memory cost needs to be calculated prior to memory expansion
final Gas cost = cost(frame);
frame.decrementRemainingGas(cost);
final Address address = frame.getRecipientAddress();
final MutableAccount account = frame.getWorldUpdater().getAccount(address).getMutable();
account.incrementNonce();
final Wei value = Wei.wrap(frame.getStackItem(0));
final long inputOffset = clampedToLong(frame.getStackItem(1));
final long inputSize = clampedToLong(frame.getStackItem(2));
final Bytes inputData = frame.readMemory(inputOffset, inputSize);
final Address contractAddress = targetContractAddress(frame);
final Gas childGasStipend = gasCalculator().gasAvailableForChildCreate(frame.getRemainingGas());
frame.decrementRemainingGas(childGasStipend);
final MessageFrame childFrame = MessageFrame.builder().type(MessageFrame.Type.CONTRACT_CREATION).messageFrameStack(frame.getMessageFrameStack()).worldUpdater(frame.getWorldUpdater().updater()).initialGas(childGasStipend).address(contractAddress).originator(frame.getOriginatorAddress()).contract(contractAddress).gasPrice(frame.getGasPrice()).inputData(Bytes.EMPTY).sender(frame.getRecipientAddress()).value(value).apparentValue(value).code(new Code(inputData, Hash.EMPTY)).blockValues(frame.getBlockValues()).depth(frame.getMessageStackDepth() + 1).completer(child -> complete(frame, child)).miningBeneficiary(frame.getMiningBeneficiary()).blockHashLookup(frame.getBlockHashLookup()).maxStackSize(frame.getMaxStackSize()).build();
frame.incrementRemainingGas(cost);
frame.getMessageFrameStack().addFirst(childFrame);
frame.setState(MessageFrame.State.CODE_SUSPENDED);
}
use of org.hyperledger.besu.evm.Gas in project hedera-services by hashgraph.
the class HederaExtCodeHashOperation method execute.
@Override
public OperationResult execute(MessageFrame frame, EVM evm) {
try {
final Address address = Words.toAddress(frame.popStackItem());
if (!addressValidator.test(address, frame)) {
return new OperationResult(Optional.of(cost(true)), Optional.of(HederaExceptionalHaltReason.INVALID_SOLIDITY_ADDRESS));
}
final var account = frame.getWorldUpdater().get(address);
boolean accountIsWarm = frame.warmUpAddress(address) || this.gasCalculator().isPrecompile(address);
Optional<Gas> optionalCost = Optional.of(this.cost(accountIsWarm));
if (frame.getRemainingGas().compareTo(optionalCost.get()) < 0) {
return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
} else {
if (!account.isEmpty()) {
frame.pushStackItem(UInt256.fromBytes(account.getCodeHash()));
} else {
frame.pushStackItem(UInt256.ZERO);
}
return new OperationResult(optionalCost, Optional.empty());
}
} catch (final FixedStack.UnderflowException ufe) {
return new OperationResult(Optional.of(cost(true)), Optional.of(ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS));
}
}
use of org.hyperledger.besu.evm.Gas 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));
}
}
Aggregations