From 987d33c63aa67194d8eb44c2532e7d6d483cc8ac Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 2 Oct 2023 10:41:21 +0200 Subject: [PATCH 1/3] Use PendingTransaction in BlockTransactionSelector (#5966) Signed-off-by: Fabio Di Fabio --- .../besu/datatypes/PendingTransaction.java | 39 ++++++++++ .../txselection/BlockTransactionSelector.java | 33 +++++--- .../AbstractTransactionSelector.java | 11 +-- .../BlobPriceTransactionSelector.java | 9 ++- .../BlockSizeTransactionSelector.java | 12 +-- .../selectors/PriceTransactionSelector.java | 16 ++-- .../ProcessingResultTransactionSelector.java | 10 ++- .../AbstractBlockTransactionSelectorTest.java | 8 +- .../core/AccountTransactionOrderTest.java | 73 ------------------ .../eth/transactions/PendingTransaction.java | 11 ++- .../eth/transactions/PendingTransactions.java | 2 +- .../layered/LayeredPendingTransactions.java | 3 +- .../AbstractPendingTransactionsSorter.java | 15 ++-- .../sorter}/AccountTransactionOrder.java | 24 +++--- .../LayeredPendingTransactionsTest.java | 34 ++++----- .../AbstractPendingTransactionsTestBase.java | 28 +++---- .../sorter/AccountTransactionOrderTest.java | 75 +++++++++++++++++++ plugin-api/build.gradle | 2 +- .../txselection/TransactionSelector.java | 7 +- 19 files changed, 237 insertions(+), 175 deletions(-) create mode 100644 datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrderTest.java rename ethereum/{core/src/main/java/org/hyperledger/besu/ethereum/core => eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter}/AccountTransactionOrder.java (70%) create mode 100644 ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrderTest.java diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java new file mode 100644 index 00000000000..4a8f5795ff8 --- /dev/null +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/PendingTransaction.java @@ -0,0 +1,39 @@ +/* + * Copyright Hyperledger Besu Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.datatypes; + +/** Represent a transaction that has not confirmed yet, and stays in the transaction pool */ +public interface PendingTransaction { + /** + * Get the underlying transaction + * + * @return the underlying transaction + */ + Transaction getTransaction(); + + /** + * Has this transaction been received from the RPC API? + * + * @return true if it is a local sent transaction + */ + boolean isReceivedFromLocalSource(); + + /** + * Timestamp in millisecond when this transaction has been added to the pool + * + * @return timestamp + */ + long getAddedAt(); +} 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 68ea7444060..679daa8b5e4 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 @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; @@ -142,7 +143,8 @@ public TransactionSelectionResults buildTransactionListForBlock() { pendingTransaction -> { final var res = evaluateTransaction(pendingTransaction); if (!res.selected()) { - transactionSelectionResults.updateNotSelected(pendingTransaction, res); + transactionSelectionResults.updateNotSelected( + pendingTransaction.getTransaction(), res); } return res; }); @@ -165,7 +167,7 @@ public TransactionSelectionResults buildTransactionListForBlock() { public TransactionSelectionResults evaluateTransactions(final List transactions) { transactions.forEach( transaction -> { - final var res = evaluateTransaction(transaction); + final var res = evaluateTransaction(new PendingTransaction.Local(transaction)); if (!res.selected()) { transactionSelectionResults.updateNotSelected(transaction, res); } @@ -182,12 +184,16 @@ public TransactionSelectionResults evaluateTransactions(final List * the space remaining in the block. * */ - private TransactionSelectionResult evaluateTransaction(final Transaction transaction) { + private TransactionSelectionResult evaluateTransaction( + final PendingTransaction pendingTransaction) { if (isCancelled.get()) { throw new CancellationException("Cancelled during transaction selection."); } - TransactionSelectionResult selectionResult = evaluateTransactionPreProcessing(transaction); + final Transaction transaction = pendingTransaction.getTransaction(); + + TransactionSelectionResult selectionResult = + evaluateTransactionPreProcessing(pendingTransaction); if (!selectionResult.selected()) { return selectionResult; } @@ -209,7 +215,7 @@ private TransactionSelectionResult evaluateTransaction(final Transaction transac blockSelectionContext.blobGasPrice()); var transactionWithProcessingContextResult = - evaluateTransactionPostProcessing(transaction, effectiveResult); + evaluateTransactionPostProcessing(pendingTransaction, effectiveResult); if (!transactionWithProcessingContextResult.selected()) { return transactionWithProcessingContextResult; } @@ -243,16 +249,17 @@ private TransactionSelectionResult evaluateTransaction(final Transaction transac * it then processes it through external selectors. If the transaction is selected by all * selectors, it returns SELECTED. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @return The result of the transaction selection process. */ private TransactionSelectionResult evaluateTransactionPreProcessing( - final Transaction transaction) { + final PendingTransaction pendingTransaction) { // Process the transaction through internal selectors for (var selector : transactionSelectors) { TransactionSelectionResult result = - selector.evaluateTransactionPreProcessing(transaction, transactionSelectionResults); + selector.evaluateTransactionPreProcessing( + pendingTransaction, transactionSelectionResults); // If the transaction is not selected by any internal selector, return the result if (!result.equals(TransactionSelectionResult.SELECTED)) { return result; @@ -261,7 +268,8 @@ private TransactionSelectionResult evaluateTransactionPreProcessing( // Process the transaction through external selectors for (var selector : externalTransactionSelectors) { - TransactionSelectionResult result = selector.evaluateTransactionPreProcessing(transaction); + TransactionSelectionResult result = + selector.evaluateTransactionPreProcessing(pendingTransaction); // If the transaction is not selected by any external selector, return the result if (!result.equals(TransactionSelectionResult.SELECTED)) { return result; @@ -277,18 +285,19 @@ private TransactionSelectionResult evaluateTransactionPreProcessing( * whether the transaction should be included in a block. If the transaction is selected by all * selectors, it returns SELECTED. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @param processingResult The result of the transaction processing. * @return The result of the transaction selection process. */ private TransactionSelectionResult evaluateTransactionPostProcessing( - final Transaction transaction, final TransactionProcessingResult processingResult) { + final PendingTransaction pendingTransaction, + final TransactionProcessingResult processingResult) { // Process the transaction through internal selectors for (var selector : transactionSelectors) { TransactionSelectionResult result = selector.evaluateTransactionPostProcessing( - transaction, transactionSelectionResults, processingResult); + pendingTransaction, transactionSelectionResults, processingResult); // If the transaction is not selected by any selector, return the result if (!result.equals(TransactionSelectionResult.SELECTED)) { return result; diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/AbstractTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/AbstractTransactionSelector.java index 3e89bb61006..205e803e820 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/AbstractTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/AbstractTransactionSelector.java @@ -16,7 +16,7 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; -import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -34,24 +34,25 @@ public AbstractTransactionSelector(final BlockSelectionContext context) { /** * Evaluates a transaction in the context of other transactions in the same block. * - * @param transaction The transaction to be evaluated within a block. + * @param pendingTransaction The transaction to be evaluated within a block. * @param blockTransactionResults The results of other transaction evaluations in the same block. * @return The result of the transaction evaluation */ public abstract TransactionSelectionResult evaluateTransactionPreProcessing( - final Transaction transaction, final TransactionSelectionResults blockTransactionResults); + final PendingTransaction pendingTransaction, + final TransactionSelectionResults blockTransactionResults); /** * Evaluates a transaction considering other transactions in the same block and a transaction * processing result. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @param blockTransactionResults The results of other transaction evaluations in the same block. * @param processingResult The result of transaction processing. * @return The result of the transaction evaluation */ public abstract TransactionSelectionResult evaluateTransactionPostProcessing( - final Transaction transaction, + final PendingTransaction pendingTransaction, final TransactionSelectionResults blockTransactionResults, final TransactionProcessingResult processingResult); } diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobPriceTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobPriceTransactionSelector.java index abf38621fd2..56a17c28434 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobPriceTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobPriceTransactionSelector.java @@ -17,6 +17,7 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -38,14 +39,14 @@ public BlobPriceTransactionSelector(final BlockSelectionContext context) { /** * Evaluates a transaction considering its blob price. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @param ignored The results of other transaction evaluations in the same block. * @return The result of the transaction selection. */ @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - final Transaction transaction, final TransactionSelectionResults ignored) { - if (transactionBlobPriceBelowMin(transaction)) { + final PendingTransaction pendingTransaction, final TransactionSelectionResults ignored) { + if (transactionBlobPriceBelowMin(pendingTransaction.getTransaction())) { return TransactionSelectionResult.BLOB_PRICE_BELOW_CURRENT_MIN; } return TransactionSelectionResult.SELECTED; @@ -53,7 +54,7 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - final Transaction transaction, + final PendingTransaction pendingTransaction, final TransactionSelectionResults blockTransactionResults, final TransactionProcessingResult processingResult) { // All necessary checks were done in the pre-processing method, so nothing to do here. diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java index 7cef4995e5e..5d60ef8fc62 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java @@ -17,6 +17,7 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -39,19 +40,20 @@ public BlockSizeTransactionSelector(final BlockSelectionContext context) { * Evaluates a transaction considering other transactions in the same block. If the transaction is * too large for the block returns a selection result based on block occupancy. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @param transactionSelectionResults The results of other transaction evaluations in the same * block. * @return The result of the transaction selection. */ @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - final Transaction transaction, + final PendingTransaction pendingTransaction, final TransactionSelectionResults transactionSelectionResults) { - if (transactionTooLargeForBlock(transaction, transactionSelectionResults)) { + if (transactionTooLargeForBlock( + pendingTransaction.getTransaction(), transactionSelectionResults)) { LOG.atTrace() .setMessage("Transaction {} too large to select for block creation") - .addArgument(transaction::toTraceLog) + .addArgument(pendingTransaction::toTraceLog) .log(); if (blockOccupancyAboveThreshold(transactionSelectionResults)) { LOG.trace("Block occupancy above threshold, completing operation"); @@ -68,7 +70,7 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - final Transaction transaction, + final PendingTransaction pendingTransaction, final TransactionSelectionResults blockTransactionResults, final TransactionProcessingResult processingResult) { // All necessary checks were done in the pre-processing method, so nothing to do here. 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 15755100e5c..a6c1889e497 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 @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -40,14 +41,14 @@ public PriceTransactionSelector(final BlockSelectionContext context) { * Evaluates a transaction considering its price. If the transaction's current price is below the * minimum, it returns a selection result indicating the reason. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @param ignored The results of other transaction evaluations in the same block. * @return The result of the transaction selection. */ @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - final Transaction transaction, final TransactionSelectionResults ignored) { - if (transactionCurrentPriceBelowMin(transaction)) { + final PendingTransaction pendingTransaction, final TransactionSelectionResults ignored) { + if (transactionCurrentPriceBelowMin(pendingTransaction)) { return TransactionSelectionResult.CURRENT_TX_PRICE_BELOW_MIN; } return TransactionSelectionResult.SELECTED; @@ -55,7 +56,7 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - final Transaction transaction, + final PendingTransaction pendingTransaction, final TransactionSelectionResults blockTransactionResults, final TransactionProcessingResult processingResult) { // All necessary checks were done in the pre-processing method, so nothing to do here. @@ -65,14 +66,15 @@ public TransactionSelectionResult evaluateTransactionPostProcessing( /** * Checks if the transaction's current price is below the minimum. * - * @param transaction The transaction to be checked. + * @param pendingTransaction The transaction to be checked. * @return True if the transaction's current price is below the minimum, false otherwise. */ - private boolean transactionCurrentPriceBelowMin(final Transaction transaction) { + private boolean transactionCurrentPriceBelowMin(final PendingTransaction pendingTransaction) { + final Transaction transaction = pendingTransaction.getTransaction(); // Here we only care about EIP1159 since for Frontier and local transactions the checks // that we do when accepting them in the pool are enough if (transaction.getType().supports1559FeeMarket() - && !context.transactionPool().isLocalSender(transaction.getSender())) { + && !pendingTransaction.isReceivedFromLocalSource()) { // For EIP1559 transactions, the price is dynamic and depends on network conditions, so we can // only calculate at this time the current minimum price the transaction is willing to pay diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java index 1fe71ee48f9..8a2778eda03 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java @@ -17,6 +17,7 @@ import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; @@ -40,7 +41,8 @@ public ProcessingResultTransactionSelector(final BlockSelectionContext context) @Override public TransactionSelectionResult evaluateTransactionPreProcessing( - final Transaction transaction, final TransactionSelectionResults blockTransactionResults) { + final PendingTransaction pendingTransaction, + final TransactionSelectionResults blockTransactionResults) { // All checks depend on processingResult and will be done in the post-processing method, so // nothing to do here. return TransactionSelectionResult.SELECTED; @@ -51,20 +53,20 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( * result. If the processing result is invalid, it determines the selection result for the invalid * result. * - * @param transaction The transaction to be evaluated. + * @param pendingTransaction The transaction to be evaluated. * @param blockTransactionResults The results of other transaction evaluations in the same block. * @param processingResult The processing result of the transaction. * @return The result of the transaction selection. */ @Override public TransactionSelectionResult evaluateTransactionPostProcessing( - final Transaction transaction, + final PendingTransaction pendingTransaction, final TransactionSelectionResults blockTransactionResults, final TransactionProcessingResult processingResult) { if (processingResult.isInvalid()) { return transactionSelectionResultForInvalidResult( - transaction, processingResult.getValidationResult()); + pendingTransaction.getTransaction(), processingResult.getValidationResult()); } return TransactionSelectionResult.SELECTED; } 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 b15e61354b4..d1af32dfe08 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 @@ -552,10 +552,10 @@ public void transactionSelectionPluginShouldWork() { final TransactionSelectorFactory transactionSelectorFactory = () -> - (tx) -> { - if (tx.equals(notSelectedTransient)) + pendingTx -> { + if (pendingTx.getTransaction().equals(notSelectedTransient)) return TransactionSelectionResult.invalidTransient("transient"); - if (tx.equals(notSelectedInvalid)) + if (pendingTx.getTransaction().equals(notSelectedInvalid)) return TransactionSelectionResult.invalid("invalid"); return TransactionSelectionResult.SELECTED; }; @@ -572,7 +572,7 @@ public void transactionSelectionPluginShouldWork() { transactionSelectorFactory); transactionPool.addRemoteTransactions( - List.of(selected, notSelectedInvalid, notSelectedTransient)); + List.of(selected, notSelectedTransient, notSelectedInvalid)); final TransactionSelectionResults transactionSelectionResults = selector.buildTransactionListForBlock(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrderTest.java deleted file mode 100644 index 8f6c76ce03d..00000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrderTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.ethereum.core; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; - -import java.util.stream.Stream; - -import org.junit.jupiter.api.Test; - -public class AccountTransactionOrderTest { - - private static final KeyPair KEYS = SignatureAlgorithmFactory.getInstance().generateKeyPair(); - - private final Transaction transaction1 = transaction(1); - private final Transaction transaction2 = transaction(2); - private final Transaction transaction3 = transaction(3); - private final Transaction transaction4 = transaction(4); - private final AccountTransactionOrder accountTransactionOrder = - new AccountTransactionOrder( - Stream.of(transaction1, transaction2, transaction3, transaction4)); - - @Test - public void shouldProcessATransactionImmediatelyIfItsTheLowestNonce() { - assertThat(accountTransactionOrder.transactionsToProcess(transaction1)) - .containsExactly(transaction1); - } - - @Test - public void shouldDeferProcessingATransactionIfItIsNotTheLowestNonce() { - assertThat(accountTransactionOrder.transactionsToProcess(transaction2)).isEmpty(); - } - - @Test - public void shouldProcessDeferredTransactionsAfterPrerequisiteIsProcessed() { - assertThat(accountTransactionOrder.transactionsToProcess(transaction2)).isEmpty(); - assertThat(accountTransactionOrder.transactionsToProcess(transaction3)).isEmpty(); - - assertThat(accountTransactionOrder.transactionsToProcess(transaction1)) - .containsExactly(transaction1, transaction2, transaction3); - } - - @Test - public void shouldNotProcessDeferredTransactionsThatAreNotYetDue() { - assertThat(accountTransactionOrder.transactionsToProcess(transaction2)).isEmpty(); - assertThat(accountTransactionOrder.transactionsToProcess(transaction4)).isEmpty(); - - assertThat(accountTransactionOrder.transactionsToProcess(transaction1)) - .containsExactly(transaction1, transaction2); - - assertThat(accountTransactionOrder.transactionsToProcess(transaction3)) - .containsExactly(transaction3, transaction4); - } - - private Transaction transaction(final int nonce) { - return new TransactionTestFixture().nonce(nonce).createTransaction(KEYS); - } -} 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 264537e1251..a716b1675e3 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 @@ -28,7 +28,8 @@ * Tracks the additional metadata associated with transactions to enable prioritization for mining * and deciding which transactions to drop when the transaction pool reaches its size limit. */ -public abstract class PendingTransaction { +public abstract class PendingTransaction + implements org.hyperledger.besu.datatypes.PendingTransaction { static final int NOT_INITIALIZED = -1; static final int FRONTIER_BASE_MEMORY_SIZE = 944; static final int ACCESS_LIST_BASE_MEMORY_SIZE = 944; @@ -52,6 +53,7 @@ protected PendingTransaction(final Transaction transaction, final long addedAt) this.sequence = TRANSACTIONS_ADDED.getAndIncrement(); } + @Override public Transaction getTransaction() { return transaction; } @@ -72,12 +74,11 @@ public Address getSender() { return transaction.getSender(); } - public abstract boolean isReceivedFromLocalSource(); - public Hash getHash() { return transaction.getHash(); } + @Override public long getAddedAt() { return addedAt; } @@ -184,6 +185,8 @@ public String toString() { + addedAt + ", sequence=" + sequence + + ", isLocal=" + + isReceivedFromLocalSource() + '}'; } @@ -192,6 +195,8 @@ public String toTraceLog() { + sequence + ", addedAt: " + addedAt + + ", isLocal=" + + isReceivedFromLocalSource() + ", " + transaction.toTraceLog() + "}"; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactions.java index b8474d3d50b..199e88675e0 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactions.java @@ -88,6 +88,6 @@ default void signalInvalidAndRemoveDependentTransactions(final Transaction trans @FunctionalInterface interface TransactionSelector { - TransactionSelectionResult evaluateTransaction(Transaction transaction); + TransactionSelectionResult evaluateTransaction(PendingTransaction pendingTransaction); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java index 0a802a7dd7d..5502e9a6f1a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java @@ -342,8 +342,7 @@ public synchronized void selectTransactions( .forEach( candidatePendingTx -> { alreadyChecked.add(candidatePendingTx.getHash()); - final var res = - selector.evaluateTransaction(candidatePendingTx.getTransaction()); + final var res = selector.evaluateTransaction(candidatePendingTx); LOG.atTrace() .setMessage("Selection result {} for transaction {}") diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java index 83424ae22fd..ea12b3c4f6a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java @@ -22,7 +22,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.AccountTransactionOrder; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; @@ -259,16 +258,15 @@ public void selectTransactions(final TransactionSelector selector) { accountTransactions.computeIfAbsent( highestPriorityPendingTransaction.getSender(), this::createSenderTransactionOrder); - for (final Transaction transactionToProcess : - accountTransactionOrder.transactionsToProcess( - highestPriorityPendingTransaction.getTransaction())) { + for (final PendingTransaction transactionToProcess : + accountTransactionOrder.transactionsToProcess(highestPriorityPendingTransaction)) { final TransactionSelectionResult result = selector.evaluateTransaction(transactionToProcess); if (result.discard()) { - transactionsToRemove.add(transactionToProcess); + transactionsToRemove.add(transactionToProcess.getTransaction()); transactionsToRemove.addAll( - signalInvalidAndGetDependentTransactions(transactionToProcess)); + signalInvalidAndGetDependentTransactions(transactionToProcess.getTransaction())); } if (result.stop()) { @@ -283,10 +281,7 @@ public void selectTransactions(final TransactionSelector selector) { private AccountTransactionOrder createSenderTransactionOrder(final Address address) { return new AccountTransactionOrder( - transactionsBySender - .get(address) - .streamPendingTransactions() - .map(PendingTransaction::getTransaction)); + transactionsBySender.get(address).streamPendingTransactions()); } private TransactionAddedResult addTransactionForSenderAndNonce( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrder.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrder.java similarity index 70% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrder.java rename to ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrder.java index 721056103cc..b85f88d556b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AccountTransactionOrder.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrder.java @@ -12,7 +12,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.core; +package org.hyperledger.besu.ethereum.eth.transactions.sorter; + +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import java.util.ArrayList; import java.util.Comparator; @@ -23,12 +25,14 @@ public class AccountTransactionOrder { - private static final Comparator SORT_BY_NONCE = - Comparator.comparing(Transaction::getNonce); - private final NavigableSet transactionsForSender = new TreeSet<>(SORT_BY_NONCE); - private final NavigableSet deferredTransactions = new TreeSet<>(SORT_BY_NONCE); + private static final Comparator SORT_BY_NONCE = + Comparator.comparing(PendingTransaction::getNonce); + private final NavigableSet transactionsForSender = + new TreeSet<>(SORT_BY_NONCE); + private final NavigableSet deferredTransactions = + new TreeSet<>(SORT_BY_NONCE); - public AccountTransactionOrder(final Stream senderTransactions) { + public AccountTransactionOrder(final Stream senderTransactions) { senderTransactions.forEach(this.transactionsForSender::add); } @@ -44,14 +48,14 @@ public AccountTransactionOrder(final Stream senderTransactions) { * order. Must be from the sender this instance is ordering. * @return the transactions from this sender that are now due to be processed, in order. */ - public Iterable transactionsToProcess( - final Transaction nextTransactionInPriorityOrder) { + public Iterable transactionsToProcess( + final PendingTransaction nextTransactionInPriorityOrder) { deferredTransactions.add(nextTransactionInPriorityOrder); - final List transactionsToApply = new ArrayList<>(); + final List transactionsToApply = new ArrayList<>(); while (!deferredTransactions.isEmpty() && !transactionsForSender.isEmpty() && deferredTransactions.first().equals(transactionsForSender.first())) { - final Transaction transaction = deferredTransactions.first(); + final PendingTransaction transaction = deferredTransactions.first(); transactionsToApply.add(transaction); deferredTransactions.remove(transaction); transactionsForSender.remove(transaction); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java index f3135045ad5..7d044de859a 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java @@ -302,8 +302,8 @@ public void selectTransactionsUntilSelectorRequestsNoMore( final List parsedTransactions = new ArrayList<>(); pendingTransactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTX -> { + parsedTransactions.add(pendingTX.getTransaction()); return selectionResult; }); @@ -322,8 +322,8 @@ public void selectTransactionsUntilPendingIsEmpty() { final List parsedTransactions = new ArrayList<>(); pendingTransactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return SELECTED; }); @@ -342,8 +342,8 @@ public void notSelectReplacedTransaction() { final List parsedTransactions = new ArrayList<>(); pendingTransactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return SELECTED; }); @@ -363,8 +363,8 @@ public void selectTransactionsFromSameSenderInNonceOrder() { final List iterationOrder = new ArrayList<>(3); pendingTransactions.selectTransactions( - transaction -> { - iterationOrder.add(transaction); + pendingTx -> { + iterationOrder.add(pendingTx.getTransaction()); return SELECTED; }); @@ -387,10 +387,10 @@ public void ignoreSenderTransactionsAfterASkippedOne( final List iterationOrder = new ArrayList<>(3); pendingTransactions.selectTransactions( - transaction -> { - iterationOrder.add(transaction); + pendingTx -> { + iterationOrder.add(pendingTx.getTransaction()); // pretending that the 2nd tx of the 1st sender is not selected - return transaction.getNonce() == 1 ? skipSelectionResult : SELECTED; + return pendingTx.getNonce() == 1 ? skipSelectionResult : SELECTED; }); // the 3rd tx of the 1st must not be processed, since the 2nd is skipped @@ -420,8 +420,8 @@ public void notForceNonceOrderWhenSendersDiffer() { final List iterationOrder = new ArrayList<>(2); pendingTransactions.selectTransactions( - transaction -> { - iterationOrder.add(transaction); + pendingTx -> { + iterationOrder.add(pendingTx.getTransaction()); return SELECTED; }); @@ -435,8 +435,8 @@ public void invalidTransactionIsDeletedFromPendingTransactions() { final List parsedTransactions = new ArrayList<>(1); pendingTransactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return TransactionSelectionResult.invalid(UPFRONT_COST_EXCEEDS_BALANCE.name()); }); @@ -455,8 +455,8 @@ public void temporarilyInvalidTransactionIsKeptInPendingTransactions() { final List parsedTransactions = new ArrayList<>(1); pendingTransactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return TransactionSelectionResult.invalidTransient( GAS_PRICE_BELOW_CURRENT_BASE_FEE.name()); }); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java index 1aff575f2e5..f1d9ce1016d 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java @@ -315,8 +315,8 @@ public void selectTransactionsUntilSelectorRequestsNoMore() { final List parsedTransactions = Lists.newArrayList(); transactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return TransactionSelectionResult.BLOCK_OCCUPANCY_ABOVE_THRESHOLD; }); @@ -331,8 +331,8 @@ public void selectTransactionsUntilPendingIsEmpty() { final List parsedTransactions = Lists.newArrayList(); transactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return SELECTED; }); @@ -351,8 +351,8 @@ public void shouldNotSelectReplacedTransaction() { final List parsedTransactions = Lists.newArrayList(); transactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return SELECTED; }); @@ -366,8 +366,8 @@ public void invalidTransactionIsDeletedFromPendingTransactions() { final List parsedTransactions = Lists.newArrayList(); transactions.selectTransactions( - transaction -> { - parsedTransactions.add(transaction); + pendingTx -> { + parsedTransactions.add(pendingTx.getTransaction()); return TransactionSelectionResult.invalid( TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE.name()); }); @@ -535,8 +535,8 @@ public void shouldIterateTransactionsFromSameSenderInNonceOrder() { final List iterationOrder = new ArrayList<>(); transactions.selectTransactions( - transaction -> { - iterationOrder.add(transaction); + pendingTx -> { + iterationOrder.add(pendingTx.getTransaction()); return SELECTED; }); @@ -553,8 +553,8 @@ public void shouldNotForceNonceOrderWhenSendersDiffer() { final List iterationOrder = new ArrayList<>(); transactions.selectTransactions( - transaction -> { - iterationOrder.add(transaction); + pendingTx -> { + iterationOrder.add(pendingTx.getTransaction()); return SELECTED; }); @@ -575,8 +575,8 @@ public void shouldNotIncreasePriorityOfTransactionsBecauseOfNonceOrder() { final List iterationOrder = new ArrayList<>(); transactions.selectTransactions( - transaction -> { - iterationOrder.add(transaction); + pendingTx -> { + iterationOrder.add(pendingTx.getTransaction()); return SELECTED; }); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrderTest.java new file mode 100644 index 00000000000..b4bd59acb88 --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AccountTransactionOrderTest.java @@ -0,0 +1,75 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.eth.transactions.sorter; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.core.TransactionTestFixture; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +public class AccountTransactionOrderTest { + + private static final KeyPair KEYS = SignatureAlgorithmFactory.getInstance().generateKeyPair(); + + private final PendingTransaction pendingTx1 = new PendingTransaction.Remote((transaction(1))); + private final PendingTransaction pendingTx2 = new PendingTransaction.Remote((transaction(2))); + private final PendingTransaction pendingTx3 = new PendingTransaction.Remote((transaction(3))); + private final PendingTransaction pendingTx4 = new PendingTransaction.Remote((transaction(4))); + private final AccountTransactionOrder accountTransactionOrder = + new AccountTransactionOrder(Stream.of(pendingTx1, pendingTx2, pendingTx3, pendingTx4)); + + @Test + public void shouldProcessATransactionImmediatelyIfItsTheLowestNonce() { + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx1)) + .containsExactly(pendingTx1); + } + + @Test + public void shouldDeferProcessingATransactionIfItIsNotTheLowestNonce() { + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx2)).isEmpty(); + } + + @Test + public void shouldProcessDeferredTransactionsAfterPrerequisiteIsProcessed() { + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx2)).isEmpty(); + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx3)).isEmpty(); + + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx1)) + .containsExactly(pendingTx1, pendingTx2, pendingTx3); + } + + @Test + public void shouldNotProcessDeferredTransactionsThatAreNotYetDue() { + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx2)).isEmpty(); + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx4)).isEmpty(); + + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx1)) + .containsExactly(pendingTx1, pendingTx2); + + assertThat(accountTransactionOrder.transactionsToProcess(pendingTx3)) + .containsExactly(pendingTx3, pendingTx4); + } + + private Transaction transaction(final int nonce) { + return new TransactionTestFixture().nonce(nonce).createTransaction(KEYS); + } +} diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index b66f7fef949..79b4cbee850 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -69,7 +69,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 = 'ON5/4jw14IPAL/Civ3ld6tvwrLsGS9eI38w5C0xRzdY=' + knownHash = 'gfZY0boUMYJoAHwou3eEhcz7A/xFvJKnjMUONZ6hY3I=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionSelector.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionSelector.java index c2682b5d8ab..601158a0fa2 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionSelector.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionSelector.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.plugin.services.txselection; -import org.hyperledger.besu.datatypes.Transaction; +import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.plugin.Unstable; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; @@ -26,8 +26,9 @@ public interface TransactionSelector { * Method called to decide whether a transaction is added to a block. The result can also indicate * that no further transactions can be added to the block. * - * @param transaction candidate transaction + * @param pendingTransaction candidate transaction * @return TransactionSelectionResult that indicates whether to include the transaction */ - TransactionSelectionResult evaluateTransactionPreProcessing(Transaction transaction); + TransactionSelectionResult evaluateTransactionPreProcessing( + PendingTransaction pendingTransaction); } From 7ee5b736f393ceb15a75a0443ebccb2dea6f0a12 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 3 Oct 2023 20:15:31 +0200 Subject: [PATCH 2/3] Target to use about 25MB for the new layered txpool by default (#5974) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 3 ++- .../eth/transactions/TransactionPoolConfiguration.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b098443f6dc..2d46af4a852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ ### Additions and Improvements - Add access to an immutable world view to start/end transaction hooks in the tracing API[#5836](https://github.com/hyperledger/besu/pull/5836) -- Layered transaction pool implementation is now stable and enabled by default. If you want still to use the legacy implementation, use `--tx-pool=legacy` [#5772](https://github.com/hyperledger/besu) +- Layered transaction pool implementation is now stable and enabled by default. If you want still to use the legacy implementation, use `--tx-pool=legacy`. + By default, the new transaction pool is capped at using 25MB of memory, this limit can be raised using `--layered-tx-pool-layer-max-capacity` options [#5772](https://github.com/hyperledger/besu) - Tune G1GC to reduce Besu memory footprint, and new `besu-untuned` start scripts to run without any specific G1GC flags [#5879](https://github.com/hyperledger/besu/pull/5879) - Reduce `engine_forkchoiceUpdatedV?` response time by asynchronously process block added events in the transaction pool [#5909](https://github.com/hyperledger/besu/pull/5909) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java index fbab05d2337..aaf8c326c0a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java @@ -64,7 +64,7 @@ enum Implementation { boolean DEFAULT_ENABLE_SAVE_RESTORE = false; File DEFAULT_SAVE_FILE = new File(DEFAULT_SAVE_FILE_NAME); - long DEFAULT_PENDING_TRANSACTIONS_LAYER_MAX_CAPACITY_BYTES = 50_000_000L; + long DEFAULT_PENDING_TRANSACTIONS_LAYER_MAX_CAPACITY_BYTES = 12_500_000L; int DEFAULT_MAX_PRIORITIZED_TRANSACTIONS = 2000; int DEFAULT_MAX_FUTURE_BY_SENDER = 200; Implementation DEFAULT_TX_POOL_IMPLEMENTATION = Implementation.LAYERED; From 10b956f75fb028a74e7289a1023f52d44477c30b Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Wed, 4 Oct 2023 19:18:49 +1100 Subject: [PATCH 3/3] Expose getSize to transaction interface (#5983) Signed-off-by: Gabriel-Trintinalia --- .../java/org/hyperledger/besu/datatypes/Transaction.java | 7 +++++++ .../org/hyperledger/besu/ethereum/core/Transaction.java | 1 + 2 files changed, 8 insertions(+) diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java index d70ceda40dc..3407513ca74 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java @@ -219,4 +219,11 @@ default Optional getMaxFeePerBlobGas() { * @return the encoded transaction as Bytes */ Bytes encoded(); + + /** + * Returns the size in bytes of the encoded transaction. + * + * @return the size in bytes of the encoded transaction. + */ + int getSize(); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index a7cad4b8d85..0133e0bd723 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -670,6 +670,7 @@ public Hash getHash() { * * @return the size in bytes of the encoded transaction. */ + @Override public int getSize() { if (size == -1) { memoizeHashAndSize();