From a81879370e0bdc9644cbc0e4f6cd5505140a883c Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 5 Feb 2025 21:31:09 +0100 Subject: [PATCH] Use PendingTransaction interface in block creation classes (#8254) Signed-off-by: Fabio Di Fabio --- .../besu/datatypes/PendingTransaction.java | 14 ++++++++++++++ .../txselection/BlockTransactionSelector.java | 10 +++++----- .../txselection/TransactionEvaluationContext.java | 9 +++++---- .../MinPriorityFeePerGasTransactionSelector.java | 12 ++++++------ .../selectors/PriceTransactionSelector.java | 3 +-- .../AbstractBlockTransactionSelectorTest.java | 14 +++++--------- .../eth/transactions/PendingTransaction.java | 2 ++ plugin-api/build.gradle | 2 +- .../txselection/PluginTransactionSelector.java | 14 ++++++-------- .../txselection/TransactionEvaluationContext.java | 6 ++---- 10 files changed, 47 insertions(+), 39 deletions(-) diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java index fd62c866e1c..91e645c7e72 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java @@ -43,4 +43,18 @@ public interface PendingTransaction { * @return timestamp */ long getAddedAt(); + + /** + * Return the estimated amount memory that this pending transaction occupies + * + * @return the estimated memory size + */ + int memorySize(); + + /** + * Formats a string with detailed information about the pending transaction for debug purposes + * + * @return a string + */ + String toTraceLog(); } diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java index fcb31e21eb7..5873acb8b32 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java @@ -290,7 +290,7 @@ private TransactionSelectionResult evaluateTransaction( final WorldUpdater txWorldStateUpdater = blockWorldStateUpdater.updater(); final TransactionProcessingResult processingResult = - processTransaction(pendingTransaction, txWorldStateUpdater); + processTransaction(evaluationContext.getTransaction(), txWorldStateUpdater); var postProcessingSelectionResult = evaluatePostProcessing(evaluationContext, processingResult); @@ -370,12 +370,12 @@ private TransactionSelectionResult evaluatePostProcessing( /** * Processes a transaction * - * @param pendingTransaction The transaction to be processed. + * @param transaction The transaction to be processed. * @param worldStateUpdater The world state updater. * @return The result of the transaction processing. */ private TransactionProcessingResult processTransaction( - final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) { + final Transaction transaction, final WorldUpdater worldStateUpdater) { final BlockHashLookup blockHashLookup = blockSelectionContext .blockHashProcessor() @@ -383,7 +383,7 @@ private TransactionProcessingResult processTransaction( return transactionProcessor.processTransaction( worldStateUpdater, blockSelectionContext.pendingBlockHeader(), - pendingTransaction.getTransaction(), + transaction, blockSelectionContext.miningBeneficiary(), operationTracer, blockHashLookup, @@ -528,7 +528,7 @@ private boolean transactionTookTooLong( .setMessage( "Transaction {} is too late for inclusion, with result {}, evaluated in {} that is over the max limit of {}ms" + ", {}") - .addArgument(evaluationContext.getPendingTransaction()::getHash) + .addArgument(evaluationContext.getTransaction()::getHash) .addArgument(selectionResult) .addArgument(evaluationTimer) .addArgument(blockTxsSelectionMaxTime) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java index 7fce600a1a6..6ce0f49c828 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java @@ -14,16 +14,15 @@ */ package org.hyperledger.besu.ethereum.blockcreation.txselection; +import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import com.google.common.base.Stopwatch; public class TransactionEvaluationContext - implements org.hyperledger.besu.plugin.services.txselection.TransactionEvaluationContext< - PendingTransaction> { + implements org.hyperledger.besu.plugin.services.txselection.TransactionEvaluationContext { private final ProcessableBlockHeader pendingBlockHeader; private final PendingTransaction pendingTransaction; private final Stopwatch evaluationTimer; @@ -44,7 +43,9 @@ public TransactionEvaluationContext( } public Transaction getTransaction() { - return pendingTransaction.getTransaction(); + // ToDo: can we avoid this cast? either by always using the interface + // or moving our Transaction implementation in the datatypes package + return (Transaction) pendingTransaction.getTransaction(); } @Override diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java index c6dae8a144e..88f74e2d013 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionEvaluationContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; -import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -47,7 +46,7 @@ public MinPriorityFeePerGasTransactionSelector(final BlockSelectionContext conte public TransactionSelectionResult evaluateTransactionPreProcessing( final TransactionEvaluationContext evaluationContext, final TransactionSelectionResults transactionSelectionResults) { - if (isPriorityFeePriceBelowMinimum(evaluationContext.getPendingTransaction())) { + if (isPriorityFeePriceBelowMinimum(evaluationContext)) { return TransactionSelectionResult.PRIORITY_FEE_PER_GAS_BELOW_CURRENT_MIN; } return TransactionSelectionResult.SELECTED; @@ -56,17 +55,18 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( /** * Checks if the priority fee price is below the minimum. * - * @param pendingTransaction The transaction to check. + * @param evaluationContext The current selection session data. * @return boolean. Returns true if the minimum priority fee price is below the minimum, false * otherwise. */ - private boolean isPriorityFeePriceBelowMinimum(final PendingTransaction pendingTransaction) { + private boolean isPriorityFeePriceBelowMinimum( + final TransactionEvaluationContext evaluationContext) { // Priority txs are exempt from this check - if (pendingTransaction.hasPriority()) { + if (evaluationContext.getPendingTransaction().hasPriority()) { return false; } Wei priorityFeePerGas = - pendingTransaction + evaluationContext .getTransaction() .getEffectivePriorityFeePerGas(context.pendingBlockHeader().getBaseFee()); return priorityFeePerGas.lessThan(context.miningConfiguration().getMinPriorityFeePerGas()); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/PriceTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/PriceTransactionSelector.java index d3c3047f688..0ede0bfae6d 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/PriceTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/PriceTransactionSelector.java @@ -17,7 +17,6 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionEvaluationContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; -import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -71,7 +70,7 @@ public TransactionSelectionResult evaluateTransactionPostProcessing( */ private boolean transactionCurrentPriceBelowMin( final TransactionEvaluationContext evaluationContext) { - final PendingTransaction pendingTransaction = evaluationContext.getPendingTransaction(); + final var pendingTransaction = evaluationContext.getPendingTransaction(); // Priority txs are exempt from this check if (!pendingTransaction.hasPriority()) { diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java index 9875a0149c0..242694fa9c1 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java @@ -653,8 +653,7 @@ public void transactionSelectionPluginShouldWork_PreProcessing() { new PluginTransactionSelector() { @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - final TransactionEvaluationContext - evaluationContext) { + final TransactionEvaluationContext evaluationContext) { if (evaluationContext .getPendingTransaction() .getTransaction() @@ -670,8 +669,7 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - final TransactionEvaluationContext - evaluationContext, + final TransactionEvaluationContext evaluationContext, final org.hyperledger.besu.plugin.data.TransactionProcessingResult processingResult) { return SELECTED; @@ -727,15 +725,13 @@ public void transactionSelectionPluginShouldWork_PostProcessing() { new PluginTransactionSelector() { @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - final TransactionEvaluationContext - evaluationContext) { + final TransactionEvaluationContext evaluationContext) { return SELECTED; } @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - final TransactionEvaluationContext - evaluationContext, + final TransactionEvaluationContext evaluationContext, final org.hyperledger.besu.plugin.data.TransactionProcessingResult processingResult) { // the transaction with max gas +1 should fail @@ -808,7 +804,7 @@ public void transactionSelectionPluginShouldBeNotifiedWhenTransactionSelectionCo selector.buildTransactionListForBlock(); @SuppressWarnings("unchecked") - ArgumentCaptor> argumentCaptor = + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(TransactionEvaluationContext.class); // selected transaction must be notified to the selector diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index e2e0166789d..b0eeea81167 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -121,6 +121,7 @@ public long getAddedAt() { return addedAt; } + @Override public int memorySize() { if (memorySize == NOT_INITIALIZED) { memorySize = computeMemorySize(); @@ -291,6 +292,7 @@ public String toString() { + '}'; } + @Override public String toTraceLog() { return "{sequence: " + sequence diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 097e0c2da42..ba8c074f208 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 = 'FEieWer0x6AdCmvf02G7yGQxS5JRxsIYrRDpqsNgQ+0=' + knownHash = 'U/zVfjqq/stLY920xHh1N26KU+KoAdgEiV2nPWIFRIs=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/PluginTransactionSelector.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/PluginTransactionSelector.java index e0bf1cf3130..71503591db3 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/PluginTransactionSelector.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/PluginTransactionSelector.java @@ -16,7 +16,6 @@ import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED; -import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.plugin.Unstable; import org.hyperledger.besu.plugin.data.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -30,13 +29,13 @@ public interface PluginTransactionSelector { new PluginTransactionSelector() { @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - TransactionEvaluationContext evaluationContext) { + TransactionEvaluationContext evaluationContext) { return SELECTED; } @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - TransactionEvaluationContext evaluationContext, + TransactionEvaluationContext evaluationContext, TransactionProcessingResult processingResult) { return SELECTED; } @@ -60,7 +59,7 @@ default BlockAwareOperationTracer getOperationTracer() { * @return TransactionSelectionResult that indicates whether to include the transaction */ TransactionSelectionResult evaluateTransactionPreProcessing( - TransactionEvaluationContext evaluationContext); + TransactionEvaluationContext evaluationContext); /** * Method called to decide whether a processed transaction is added to a block. The result can @@ -71,8 +70,7 @@ TransactionSelectionResult evaluateTransactionPreProcessing( * @return TransactionSelectionResult that indicates whether to include the transaction */ TransactionSelectionResult evaluateTransactionPostProcessing( - TransactionEvaluationContext evaluationContext, - TransactionProcessingResult processingResult); + TransactionEvaluationContext evaluationContext, TransactionProcessingResult processingResult); /** * Method called when a transaction is selected to be added to a block. @@ -81,7 +79,7 @@ TransactionSelectionResult evaluateTransactionPostProcessing( * @param processingResult The result of processing the selected transaction. */ default void onTransactionSelected( - final TransactionEvaluationContext evaluationContext, + final TransactionEvaluationContext evaluationContext, final TransactionProcessingResult processingResult) {} /** @@ -91,6 +89,6 @@ default void onTransactionSelected( * @param transactionSelectionResult The transaction selection result */ default void onTransactionNotSelected( - final TransactionEvaluationContext evaluationContext, + final TransactionEvaluationContext evaluationContext, final TransactionSelectionResult transactionSelectionResult) {} } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java index 8938ef881b4..27cf19e5137 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java @@ -23,10 +23,8 @@ /** * This interface defines the context for evaluating a transaction. It provides methods to get the * pending transaction, the evaluation timer, and the transaction gas price. - * - * @param the type of the pending transaction */ -public interface TransactionEvaluationContext { +public interface TransactionEvaluationContext { /** * Gets the pending block header @@ -40,7 +38,7 @@ public interface TransactionEvaluationContext { * * @return the pending transaction */ - PT getPendingTransaction(); + PendingTransaction getPendingTransaction(); /** * Gets the stopwatch used for timing the evaluation.