use of org.hyperledger.besu.evm.frame.ExceptionalHaltReason in project besu by hyperledger.
the class EVM method executeNextOperation.
private void executeNextOperation(final MessageFrame frame, final OperationTracer operationTracer) {
frame.setCurrentOperation(operationAtOffset(frame.getCode(), frame.getPC()));
operationTracer.traceExecution(frame, () -> {
OperationResult result;
final Operation operation = frame.getCurrentOperation();
try {
result = operation.execute(frame, this);
} catch (final OverflowException oe) {
result = OVERFLOW_RESPONSE;
} catch (final UnderflowException ue) {
result = UNDERFLOW_RESPONSE;
}
logState(frame, result.getGasCost().orElse(0L));
final Optional<ExceptionalHaltReason> haltReason = result.getHaltReason();
if (haltReason.isPresent()) {
LOG.trace("MessageFrame evaluation halted because of {}", haltReason.get());
frame.setExceptionalHaltReason(haltReason);
frame.setState(State.EXCEPTIONAL_HALT);
} else if (result.getGasCost().isPresent()) {
frame.decrementRemainingGas(result.getGasCost().getAsLong());
}
if (frame.getState() == State.CODE_EXECUTING) {
final int currentPC = frame.getPC();
final int opSize = result.getPcIncrement();
frame.setPC(currentPC + opSize);
}
return result;
});
}
use of org.hyperledger.besu.evm.frame.ExceptionalHaltReason in project besu by hyperledger.
the class ContractCreationProcessor method codeSuccess.
@Override
public void codeSuccess(final MessageFrame frame, final OperationTracer operationTracer) {
final Bytes contractCode = frame.getOutputData();
final long depositFee = gasCalculator.codeDepositGasCost(contractCode.size());
if (frame.getRemainingGas() < depositFee) {
LOG.trace("Not enough gas to pay the code deposit fee for {}: " + "remaining gas = {} < {} = deposit fee", frame.getContractAddress(), frame.getRemainingGas(), depositFee);
if (requireCodeDepositToSucceed) {
LOG.trace("Contract creation error: insufficient funds for code deposit");
frame.setExceptionalHaltReason(Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
frame.setState(MessageFrame.State.EXCEPTIONAL_HALT);
operationTracer.traceAccountCreationResult(frame, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
} else {
frame.setState(MessageFrame.State.COMPLETED_SUCCESS);
}
} else {
final var invalidReason = contractValidationRules.stream().map(rule -> rule.validate(frame)).filter(Optional::isPresent).findFirst();
if (invalidReason.isEmpty()) {
frame.decrementRemainingGas(depositFee);
// Finalize contract creation, setting the contract code.
final MutableAccount contract = frame.getWorldUpdater().getOrCreate(frame.getContractAddress()).getMutable();
contract.setCode(contractCode);
LOG.trace("Successful creation of contract {} with code of size {} (Gas remaining: {})", frame.getContractAddress(), contractCode.size(), frame.getRemainingGas());
frame.setState(MessageFrame.State.COMPLETED_SUCCESS);
} else {
final Optional<ExceptionalHaltReason> exceptionalHaltReason = invalidReason.get();
frame.setExceptionalHaltReason(exceptionalHaltReason);
frame.setState(MessageFrame.State.EXCEPTIONAL_HALT);
operationTracer.traceAccountCreationResult(frame, exceptionalHaltReason);
}
}
}
Aggregations