Extend simulate transaction on pending block plugin API (#8174)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
This commit is contained in:
Fabio Di Fabio
2025-01-28 19:03:59 +01:00
committed by GitHub
parent b3192a5960
commit b5d507d659
6 changed files with 88 additions and 91 deletions

View File

@@ -5,6 +5,8 @@
### Upcoming Breaking Changes
### Additions and Improvements
- Adds timestamps to enable Prague hardfork on Sepolia and Holesky test networks. [#8163](https://github.com/hyperledger/besu/pull/8163)
- Extend simulate transaction on pending block plugin API [#8174](https://github.com/hyperledger/besu/pull/8174)
### Bug fixes

View File

@@ -14,11 +14,15 @@
*/
package org.hyperledger.besu.services;
import static org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams.transactionSimulator;
import static org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams.transactionSimulatorAllowExceedingBalance;
import static org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams.transactionSimulatorAllowExceedingBalanceAndFutureNonce;
import static org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams.transactionSimulatorAllowFutureNonce;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.StateOverrideMap;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
@@ -26,6 +30,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
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,19 +56,21 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe
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));
@@ -79,22 +86,37 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe
.process(
callParameter,
isAllowExceedingBalance
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
? transactionSimulatorAllowExceedingBalance()
: 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 boolean isAllowFutureNonce) {
final CallParameter callParameter = CallParameter.fromTransaction(transaction);
return transactionSimulator
.processOnPending(
callParameter,
maybeStateOverrides,
isAllowExceedingBalance
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
? isAllowFutureNonce
? transactionSimulatorAllowExceedingBalanceAndFutureNonce()
: transactionSimulatorAllowExceedingBalance()
: isAllowFutureNonce
? transactionSimulatorAllowFutureNonce()
: transactionSimulator(),
operationTracer,
transactionSimulator.simulatePendingBlockHeader())
(org.hyperledger.besu.ethereum.core.ProcessableBlockHeader) pendingBlockHeader)
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}
}

View File

@@ -35,9 +35,15 @@ public interface TransactionValidationParams {
TransactionValidationParams transactionSimulatorParams =
ImmutableTransactionValidationParams.of(false, false, false, false, false, true);
TransactionValidationParams transactionSimulatorParamsAllowFutureNonce =
ImmutableTransactionValidationParams.of(true, false, false, false, false, true);
TransactionValidationParams transactionSimulatorAllowExceedingBalanceParams =
ImmutableTransactionValidationParams.of(false, true, false, false, false, true);
TransactionValidationParams transactionSimulatorAllowExceedingBalanceAndFutureNonceParams =
ImmutableTransactionValidationParams.of(true, true, false, false, false, true);
@Value.Default
default boolean isAllowFutureNonce() {
return false;
@@ -72,10 +78,18 @@ public interface TransactionValidationParams {
return transactionSimulatorParams;
}
static TransactionValidationParams transactionSimulatorAllowFutureNonce() {
return transactionSimulatorParamsAllowFutureNonce;
}
static TransactionValidationParams transactionSimulatorAllowExceedingBalance() {
return transactionSimulatorAllowExceedingBalanceParams;
}
static TransactionValidationParams transactionSimulatorAllowExceedingBalanceAndFutureNonce() {
return transactionSimulatorAllowExceedingBalanceAndFutureNonceParams;
}
static TransactionValidationParams processingBlock() {
return processingBlockParams;
}

View File

@@ -174,7 +174,7 @@ public class TransactionSimulator {
operationTracer,
pendingBlockHeader,
updater,
Address.ZERO);
pendingBlockHeader.getCoinbase());
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@@ -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 = 'gZIQWjSStog+2qxsbGPPp0OwpYjl8QDM5pv9QWdtADA='
}
check.dependsOn('checkAPIChanges')

View File

@@ -19,6 +19,7 @@ import org.hyperledger.besu.datatypes.StateOverrideMap;
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 @@ import java.util.Optional;
@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, 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,27 @@ public interface TransactionSimulationService extends BesuService {
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?
* @param isAllowFutureNonce should skip strict check on sequential nonce?
* @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,
boolean isAllowFutureNonce);
}