Skip to content

Commit

Permalink
Expose the simulated pending block header to plugin API
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <[email protected]>
  • Loading branch information
fab-10 committed Jan 28, 2025
1 parent b3192a5 commit f0bb128
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.plugin.Unstable;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
import org.hyperledger.besu.plugin.data.TransactionSimulationResult;
import org.hyperledger.besu.plugin.services.TransactionSimulationService;

Expand All @@ -51,40 +52,52 @@ public void init(final Blockchain blockchain, final TransactionSimulator transac
this.transactionSimulator = transactionSimulator;
}

@Override
public ProcessableBlockHeader simulatePendingBlockHeader() {
return transactionSimulator.simulatePendingBlockHeader();
}

@Override
public Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Optional<StateOverrideMap> maybeStateOverrides,
final Optional<Hash> maybeBlockHash,
final Hash blockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {

final CallParameter callParameter = CallParameter.fromTransaction(transaction);

if (maybeBlockHash.isPresent()) {
final Hash blockHash = maybeBlockHash.get();
final var maybeBlockHeader =
blockchain.getBlockHeader(blockHash).or(() -> blockchain.getBlockHeaderSafe(blockHash));

final var maybeBlockHeader =
blockchain.getBlockHeader(blockHash).or(() -> blockchain.getBlockHeaderSafe(blockHash));
if (maybeBlockHeader.isEmpty()) {
return Optional.of(
new TransactionSimulationResult(
transaction,
TransactionProcessingResult.invalid(
ValidationResult.invalid(TransactionInvalidReason.BLOCK_NOT_FOUND))));
}

if (maybeBlockHeader.isEmpty()) {
return Optional.of(
new TransactionSimulationResult(
transaction,
TransactionProcessingResult.invalid(
ValidationResult.invalid(TransactionInvalidReason.BLOCK_NOT_FOUND))));
}
return transactionSimulator
.process(
callParameter,
isAllowExceedingBalance
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
operationTracer,
maybeBlockHeader.get())
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}

return transactionSimulator
.process(
callParameter,
isAllowExceedingBalance
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
operationTracer,
maybeBlockHeader.get())
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}
@Override
public Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Optional<StateOverrideMap> maybeStateOverrides,
final ProcessableBlockHeader pendingBlockHeader,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {

final CallParameter callParameter = CallParameter.fromTransaction(transaction);

return transactionSimulator
.processOnPending(
Expand All @@ -94,7 +107,7 @@ public Optional<TransactionSimulationResult> simulate(
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
operationTracer,
transactionSimulator.simulatePendingBlockHeader())
(org.hyperledger.besu.ethereum.core.ProcessableBlockHeader) pendingBlockHeader)
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public Optional<TransactionSimulatorResult> processOnPending(
operationTracer,
pendingBlockHeader,
updater,
Address.ZERO);
pendingBlockHeader.getCoinbase());
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
2 changes: 1 addition & 1 deletion plugin-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'E2b/W+IKnNxo6L7cHuijBMBUewHHRrkQ8dEVlcql5KE='
knownHash = 'iy+e0qmPmjT+hD0LI39QnlXJzreSUjKgCj1tlNqIUzQ='
}
check.dependsOn('checkAPIChanges')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.plugin.Unstable;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
import org.hyperledger.besu.plugin.data.TransactionSimulationResult;

import java.util.Optional;
Expand All @@ -27,91 +28,47 @@
@Unstable
public interface TransactionSimulationService extends BesuService {

/**
* Return a simulation of what could be current pending block, it can also be passed to {@link
* #simulate(Transaction, Optional, ProcessableBlockHeader, OperationTracer, boolean)}
*
* @return the simulated pending block header
*/
ProcessableBlockHeader simulatePendingBlockHeader();

/**
* Simulate transaction execution at the block identified by the hash if present, otherwise on the
* pending block, with optional state overrides that can be applied before the simulation.
*
* @param transaction tx
* @param stateOverrides state overrides to apply to this simulation
* @param maybeBlockHash optional hash of the block, empty to simulate on pending block
* @param blockHash hash of the block
* @param operationTracer the tracer
* @param isAllowExceedingBalance should ignore the sender balance during the simulation?
* @return the result of the simulation
*/
Optional<TransactionSimulationResult> simulate(
Transaction transaction,
Optional<StateOverrideMap> stateOverrides,
Optional<Hash> maybeBlockHash,
Hash blockHash,
OperationTracer operationTracer,
boolean isAllowExceedingBalance);

/**
* Simulate transaction execution at the block identified by the hash if present, otherwise on the
* pending block
*
* @param transaction tx
* @param maybeBlockHash optional hash of the block, empty to simulate on pending block
* @param operationTracer the tracer
* @param isAllowExceedingBalance should ignore the sender balance during the simulation?
* @return the result of the simulation
*/
default Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Optional<Hash> maybeBlockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {
return simulate(
transaction, Optional.empty(), maybeBlockHash, operationTracer, isAllowExceedingBalance);
}

/**
* Simulate transaction execution at the block identified by the hash
*
* @param transaction tx
* @param blockHash then hash of the block
* @param operationTracer the tracer
* @param isAllowExceedingBalance should ignore the sender balance during the simulation?
* @return the result of the simulation
* @deprecated use {@link #simulate(Transaction, Optional, OperationTracer, boolean)}
*/
@Deprecated(since = "24.12", forRemoval = true)
default Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Hash blockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {
return simulate(
transaction,
Optional.empty(),
Optional.of(blockHash),
operationTracer,
isAllowExceedingBalance);
}

/**
* Simulate transaction execution at the block identified by the hash, with optional state
* overrides that can be applied before the simulation.
* pending block, with optional state overrides that can be applied before the simulation.
*
* @param transaction tx
* @param stateOverrides state overrides to apply to this simulation
* @param blockHash the hash of the block
* @param processableBlockHeader block header to simulate on pending block
* @param operationTracer the tracer
* @param isAllowExceedingBalance should ignore the sender balance during the simulation?
* @return the result of the simulation
* @deprecated use {@link #simulate(Transaction, Optional, Optional, OperationTracer, boolean)}
*/
@Deprecated(since = "24.12", forRemoval = true)
default Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Optional<StateOverrideMap> stateOverrides,
final Hash blockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {
return simulate(
transaction,
stateOverrides,
Optional.of(blockHash),
operationTracer,
isAllowExceedingBalance);
}
Optional<TransactionSimulationResult> simulate(
Transaction transaction,
Optional<StateOverrideMap> stateOverrides,
ProcessableBlockHeader processableBlockHeader,
OperationTracer operationTracer,
boolean isAllowExceedingBalance);
}

0 comments on commit f0bb128

Please sign in to comment.