diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java index d8e12a2be7f5..2e01c76c8d7f 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java @@ -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; @@ -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 simulate( final Transaction transaction, final Optional maybeStateOverrides, - final Optional 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 simulate( + final Transaction transaction, + final Optional maybeStateOverrides, + final ProcessableBlockHeader pendingBlockHeader, + final OperationTracer operationTracer, + final boolean isAllowExceedingBalance) { + + final CallParameter callParameter = CallParameter.fromTransaction(transaction); return transactionSimulator .processOnPending( @@ -94,7 +107,7 @@ public Optional simulate( ? TransactionValidationParams.transactionSimulatorAllowExceedingBalance() : TransactionValidationParams.transactionSimulator(), operationTracer, - transactionSimulator.simulatePendingBlockHeader()) + (org.hyperledger.besu.ethereum.core.ProcessableBlockHeader) pendingBlockHeader) .map(res -> new TransactionSimulationResult(transaction, res.result())); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java index bf8c966f8c9f..7c089c5aa8be 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java @@ -174,7 +174,7 @@ public Optional processOnPending( operationTracer, pendingBlockHeader, updater, - Address.ZERO); + pendingBlockHeader.getCoinbase()); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 3844f76480ec..a2e9d320e5d2 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -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') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java index 508e6eeff7d1..98b08597d35b 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java @@ -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; @@ -27,13 +28,21 @@ @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 @@ -41,77 +50,25 @@ public interface TransactionSimulationService extends BesuService { Optional simulate( Transaction transaction, Optional stateOverrides, - Optional 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 simulate( - final Transaction transaction, - final Optional 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 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 simulate( - final Transaction transaction, - final Optional stateOverrides, - final Hash blockHash, - final OperationTracer operationTracer, - final boolean isAllowExceedingBalance) { - return simulate( - transaction, - stateOverrides, - Optional.of(blockHash), - operationTracer, - isAllowExceedingBalance); - } + Optional simulate( + Transaction transaction, + Optional stateOverrides, + ProcessableBlockHeader processableBlockHeader, + OperationTracer operationTracer, + boolean isAllowExceedingBalance); }