Do not leak references to PendingTransactions (#5693)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
pull/5701/head
Fabio Di Fabio 1 year ago committed by GitHub
parent 901661cb4f
commit 86b2b600a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
  2. 4
      besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java
  3. 2
      besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java
  4. 2
      besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java
  5. 4
      besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java
  6. 8
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java
  7. 10
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutor.java
  8. 49
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java
  9. 64
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java
  10. 8
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java
  11. 12
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java
  12. 33
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java
  13. 30
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java
  14. 8
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java
  15. 8
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java
  16. 47
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  17. 6
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java
  18. 107
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java
  19. 8
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java
  20. 4
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactoryTest.java
  21. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java
  22. 12
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java
  23. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/LatestNonceProvider.java
  24. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java
  25. 15
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java
  26. 11
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java
  27. 12
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuStatistics.java
  28. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuTransactions.java
  29. 3
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EeaJsonRpcMethods.java
  30. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java
  31. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TxPoolJsonRpcMethods.java
  32. 18
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/AbstractEthGraphQLHttpServiceTest.java
  33. 3
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java
  34. 10
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/LatestNonceProviderTest.java
  35. 20
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHashTest.java
  36. 20
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCountTest.java
  37. 14
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java
  38. 10
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuStatisticsTest.java
  39. 9
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuTransactionsTest.java
  40. 10
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
  41. 8
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMinerExecutor.java
  42. 14
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java
  43. 6
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java
  44. 8
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutor.java
  45. 35
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java
  46. 394
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java
  47. 78
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java
  48. 160
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java
  49. 76
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java
  50. 55
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutorTest.java
  51. 21
      ethereum/blockcreation/src/test/resources/block-transaction-selector/gas-price-genesis.json
  52. 23
      ethereum/blockcreation/src/test/resources/block-transaction-selector/london-genesis.json
  53. 33
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/AbstractIsolationTests.java
  54. 68
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  55. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolEvictionService.java
  56. 21
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java
  57. 16
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetPooledTransactionsFromPeerTaskTest.java
  58. 2
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java
  59. 18
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java
  60. 2
      ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/EthStatsService.java
  61. 5
      ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java
  62. 2
      ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java
  63. 2
      ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java

@ -83,7 +83,7 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
new CliqueMinerExecutor(
protocolContext,
protocolSchedule,
transactionPool.getPendingTransactions(),
transactionPool,
nodeKey,
miningParameters,
new CliqueBlockScheduler(

@ -146,7 +146,7 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
final BftProtocolSchedule bftProtocolSchedule = (BftProtocolSchedule) protocolSchedule;
final BftBlockCreatorFactory<?> blockCreatorFactory =
new BftBlockCreatorFactory<>(
transactionPool.getPendingTransactions(),
transactionPool,
protocolContext,
bftProtocolSchedule,
forksSchedule,
@ -310,7 +310,7 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
block.getHeader().getCoinbase().equals(localAddress) ? "Produced" : "Imported",
block.getHeader().getNumber(),
block.getBody().getTransactions().size(),
transactionPool.getPendingTransactions().size(),
transactionPool.count(),
block.getHeader().getGasUsed(),
(block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(),
block.getHash().toHexString()));

@ -49,7 +49,7 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
new PoWMinerExecutor(
protocolContext,
protocolSchedule,
transactionPool.getPendingTransactions(),
transactionPool,
miningParameters,
new DefaultBlockScheduler(
MainnetBlockHeaderValidator.MINIMUM_SECONDS_SINCE_PARENT,

@ -174,7 +174,7 @@ public class MergeBesuControllerBuilder extends BesuControllerBuilder {
LOG.debug("Block builder executor status {}", blockBuilderExecutor);
return CompletableFuture.runAsync(task, blockBuilderExecutor);
},
transactionPool.getPendingTransactions(),
transactionPool,
miningParameters,
backwardSyncContext,
depositContractAddress);

@ -184,7 +184,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
final BftProtocolSchedule bftProtocolSchedule = (BftProtocolSchedule) protocolSchedule;
final BftBlockCreatorFactory<?> blockCreatorFactory =
new QbftBlockCreatorFactory(
transactionPool.getPendingTransactions(),
transactionPool,
protocolContext,
bftProtocolSchedule,
qbftForksSchedule,
@ -381,7 +381,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
block.getHeader().getCoinbase().equals(localAddress) ? "Produced" : "Imported",
block.getHeader().getNumber(),
block.getBody().getTransactions().size(),
transactionPool.getPendingTransactions().size(),
transactionPool.count(),
block.getHeader().getGasUsed(),
(block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(),
block.getHash().toHexString()));

@ -33,7 +33,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
@ -52,7 +52,7 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
* @param coinbase the coinbase
* @param targetGasLimitSupplier the target gas limit supplier
* @param extraDataCalculator the extra data calculator
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param nodeKey the node key
@ -65,7 +65,7 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
final Address coinbase,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final NodeKey nodeKey,
@ -78,7 +78,7 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
__ -> Util.publicKeyToAddress(nodeKey.getPublicKey()),
targetGasLimitSupplier,
extraDataCalculator,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,

@ -28,7 +28,7 @@ import org.hyperledger.besu.ethereum.chain.PoWObserver;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.util.Subscribers;
@ -54,7 +54,7 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor<CliqueBlockMiner>
*
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param nodeKey the node key
* @param miningParams the mining params
* @param blockScheduler the block scheduler
@ -63,12 +63,12 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor<CliqueBlockMiner>
public CliqueMinerExecutor(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final NodeKey nodeKey,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler,
final EpochManager epochManager) {
super(protocolContext, protocolSchedule, pendingTransactions, miningParams, blockScheduler);
super(protocolContext, protocolSchedule, transactionPool, miningParams, blockScheduler);
this.nodeKey = nodeKey;
this.localAddress = Util.publicKeyToAddress(nodeKey.getPublicKey());
this.epochManager = epochManager;
@ -85,7 +85,7 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor<CliqueBlockMiner>
localAddress, // TOOD(tmm): This can be removed (used for voting not coinbase).
() -> targetGasLimit.map(AtomicLong::longValue),
this::calculateExtraData,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
nodeKey,

@ -18,6 +18,7 @@ import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -46,8 +47,14 @@ import org.hyperledger.besu.ethereum.core.AddressHelpers;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
@ -132,11 +139,7 @@ public class CliqueBlockCreatorTest {
coinbase,
() -> Optional.of(10_000_000L),
parent -> extraData,
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(5).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader),
createTransactionPool(),
protocolContext,
protocolSchedule,
proposerNodeKey,
@ -165,11 +168,7 @@ public class CliqueBlockCreatorTest {
coinbase,
() -> Optional.of(10_000_000L),
parent -> extraData,
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(5).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader),
createTransactionPool(),
protocolContext,
protocolSchedule,
proposerNodeKey,
@ -203,11 +202,7 @@ public class CliqueBlockCreatorTest {
coinbase,
() -> Optional.of(10_000_000L),
parent -> extraData,
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(5).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader),
createTransactionPool(),
protocolContext,
protocolSchedule,
proposerNodeKey,
@ -220,4 +215,28 @@ public class CliqueBlockCreatorTest {
assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.DROP_NONCE);
assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(Address.fromHexString("0"));
}
private TransactionPool createTransactionPool() {
final TransactionPoolConfiguration conf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(5).build();
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() ->
new GasPricePendingTransactionsSorter(
conf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader),
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
mock(MiningParameters.class),
new TransactionPoolMetrics(metricsSystem),
conf);
transactionPool.setEnabled();
return transactionPool;
}
}

@ -16,6 +16,7 @@ package org.hyperledger.besu.consensus.clique.blockcreation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -38,8 +39,13 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem;
@ -65,6 +71,8 @@ public class CliqueMinerExecutorTest {
private Address localAddress;
private final List<Address> validatorList = Lists.newArrayList();
private ProtocolContext cliqueProtocolContext;
private ProtocolSchedule cliqueProtocolSchedule;
private EthContext cliqueEthContext;
private BlockHeaderTestFixture blockHeaderBuilder;
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();
@ -82,6 +90,10 @@ public class CliqueMinerExecutorTest {
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext, Optional.empty());
cliqueProtocolSchedule =
CliqueProtocolSchedule.create(
GENESIS_CONFIG_OPTIONS, proposerNodeKey, false, EvmConfiguration.DEFAULT);
cliqueEthContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
blockHeaderBuilder = new BlockHeaderTestFixture();
}
@ -92,13 +104,8 @@ public class CliqueMinerExecutorTest {
final CliqueMinerExecutor executor =
new CliqueMinerExecutor(
cliqueProtocolContext,
CliqueProtocolSchedule.create(
GENESIS_CONFIG_OPTIONS, proposerNodeKey, false, EvmConfiguration.DEFAULT),
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
CliqueMinerExecutorTest::mockBlockHeader),
cliqueProtocolSchedule,
createTransactionPool(),
proposerNodeKey,
new MiningParameters.Builder()
.coinbase(AddressHelpers.ofValue(1))
@ -134,13 +141,8 @@ public class CliqueMinerExecutorTest {
final CliqueMinerExecutor executor =
new CliqueMinerExecutor(
cliqueProtocolContext,
CliqueProtocolSchedule.create(
GENESIS_CONFIG_OPTIONS, proposerNodeKey, false, EvmConfiguration.DEFAULT),
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
CliqueMinerExecutorTest::mockBlockHeader),
cliqueProtocolSchedule,
createTransactionPool(),
proposerNodeKey,
new MiningParameters.Builder()
.coinbase(AddressHelpers.ofValue(1))
@ -176,13 +178,8 @@ public class CliqueMinerExecutorTest {
final CliqueMinerExecutor executor =
new CliqueMinerExecutor(
cliqueProtocolContext,
CliqueProtocolSchedule.create(
GENESIS_CONFIG_OPTIONS, proposerNodeKey, false, EvmConfiguration.DEFAULT),
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
CliqueMinerExecutorTest::mockBlockHeader),
cliqueProtocolSchedule,
createTransactionPool(),
proposerNodeKey,
new MiningParameters.Builder()
.coinbase(AddressHelpers.ofValue(1))
@ -206,6 +203,31 @@ public class CliqueMinerExecutorTest {
assertThat(cliqueExtraData.getVanityData()).isEqualTo(modifiedVanityData);
}
private TransactionPool createTransactionPool() {
final var conf = ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build();
when(cliqueEthContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() ->
new GasPricePendingTransactionsSorter(
conf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
CliqueMinerExecutorTest::mockBlockHeader),
cliqueProtocolSchedule,
cliqueProtocolContext,
mock(TransactionBroadcaster.class),
cliqueEthContext,
mock(MiningParameters.class),
new TransactionPoolMetrics(metricsSystem),
conf);
transactionPool.setEnabled();
return transactionPool;
}
private static BlockHeader mockBlockHeader() {
final BlockHeader blockHeader = mock(BlockHeader.class);
when(blockHeader.getBaseFee()).thenReturn(Optional.empty());

@ -26,7 +26,7 @@ import org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import java.util.Optional;
@ -46,7 +46,7 @@ public class BftBlockCreator extends AbstractBlockCreator {
* @param localAddress the local address
* @param targetGasLimitSupplier the target gas limit supplier
* @param extraDataCalculator the extra data calculator
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param minTransactionGasPrice the min transaction gas price
@ -59,7 +59,7 @@ public class BftBlockCreator extends AbstractBlockCreator {
final Address localAddress,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final Wei minTransactionGasPrice,
@ -71,7 +71,7 @@ public class BftBlockCreator extends AbstractBlockCreator {
miningBeneficiaryCalculator(localAddress, forksSchedule),
targetGasLimitSupplier,
extraDataCalculator,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,

@ -32,7 +32,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.blockcreation.BlockCreator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@ -53,7 +53,7 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
/** The Forks schedule. */
protected final ForksSchedule<T> forksSchedule;
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
/** The Protocol context. */
protected final ProtocolContext protocolContext;
/** The Protocol schedule. */
@ -73,7 +73,7 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
/**
* Instantiates a new Bft block creator factory.
*
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param forksSchedule the forks schedule
@ -82,14 +82,14 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
* @param bftExtraDataCodec the bft extra data codec
*/
public BftBlockCreatorFactory(
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final ForksSchedule<T> forksSchedule,
final MiningParameters miningParams,
final Address localAddress,
final BftExtraDataCodec bftExtraDataCodec) {
this.pendingTransactions = pendingTransactions;
this.transactionPool = transactionPool;
this.protocolContext = protocolContext;
this.protocolSchedule = protocolSchedule;
this.forksSchedule = forksSchedule;
@ -114,7 +114,7 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
localAddress,
() -> targetGasLimit.map(AtomicLong::longValue),
ph -> createExtraData(round, ph),
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,

@ -17,7 +17,10 @@ package org.hyperledger.besu.consensus.ibft.support;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.BftConfigOptions;
import org.hyperledger.besu.config.BftFork;
@ -76,7 +79,12 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
@ -330,18 +338,33 @@ public class TestContextBuilder {
worldStateArchive,
new BftContext(validatorProvider, epochManager, blockInterface),
Optional.empty());
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build();
final GasPricePendingTransactionsSorter pendingTransactions =
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
clock,
metricsSystem,
blockChain::getChainHeadHeader);
poolConf, clock, metricsSystem, blockChain::getChainHeadHeader);
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
miningParams,
new TransactionPoolMetrics(metricsSystem),
poolConf);
transactionPool.setEnabled();
final Address localAddress = Util.publicKeyToAddress(nodeKey.getPublicKey());
final BftBlockCreatorFactory<?> blockCreatorFactory =
new BftBlockCreatorFactory<>(
pendingTransactions, // changed from IbftBesuController
transactionPool, // changed from IbftBesuController
protocolContext,
protocolSchedule,
forksSchedule,

@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftExtraDataEncoder;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -40,8 +41,14 @@ import org.hyperledger.besu.ethereum.core.AddressHelpers;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
@ -116,13 +123,32 @@ public class BftBlockCreatorTest {
setupContextWithBftExtraDataEncoder(initialValidatorList, bftExtraDataEncoder),
Optional.empty());
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build();
final GasPricePendingTransactionsSorter pendingTransactions =
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
poolConf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader);
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
protocolSchedule,
protContext,
mock(TransactionBroadcaster.class),
ethContext,
mock(MiningParameters.class),
new TransactionPoolMetrics(metricsSystem),
poolConf);
transactionPool.setEnabled();
final BftBlockCreator blockCreator =
new BftBlockCreator(
forksSchedule,
@ -136,7 +162,7 @@ public class BftBlockCreatorTest {
Optional.empty(),
0,
initialValidatorList)),
pendingTransactions,
transactionPool,
protContext,
protocolSchedule,
Wei.ZERO,

@ -24,7 +24,7 @@ import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import java.util.Collections;
@ -51,7 +51,7 @@ class MergeBlockCreator extends AbstractBlockCreator {
* @param coinbase the coinbase
* @param targetGasLimitSupplier the target gas limit supplier
* @param extraDataCalculator the extra data calculator
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param minTransactionGasPrice the min transaction gas price
@ -62,7 +62,7 @@ class MergeBlockCreator extends AbstractBlockCreator {
final Address coinbase,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final Wei minTransactionGasPrice,
@ -74,7 +74,7 @@ class MergeBlockCreator extends AbstractBlockCreator {
__ -> miningBeneficiary,
targetGasLimitSupplier,
extraDataCalculator,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,

@ -38,7 +38,7 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BadChainListener;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@ -101,7 +101,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param blockBuilderExecutor the block builder executor
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param miningParams the mining params
* @param backwardSyncContext the backward sync context
* @param depositContractAddress the address of the deposit contract
@ -110,7 +110,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final ProposalBuilderExecutor blockBuilderExecutor,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final MiningParameters miningParams,
final BackwardSyncContext backwardSyncContext,
final Optional<Address> depositContractAddress) {
@ -133,7 +133,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
address.or(miningParameters::getCoinbase).orElse(Address.ZERO),
() -> Optional.of(targetGasLimit.longValue()),
parent -> extraData.get(),
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
this.miningParameters.getMinTransactionGasPrice(),

@ -61,8 +61,13 @@ import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
@ -91,6 +96,7 @@ import org.apache.tuweni.units.bigints.UInt256;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Spy;
@ -122,6 +128,9 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
@Mock MergeContext mergeContext;
@Mock BackwardSyncContext backwardSyncContext;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
EthContext ethContext;
@Mock ProposalBuilderExecutor proposalBuilderExecutor;
private final Address coinbase = genesisAllocations(getPosGenesisConfigFile()).findFirst().get();
@ -152,16 +161,20 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
private final org.hyperledger.besu.metrics.StubMetricsSystem metricsSystem =
new StubMetricsSystem();
private final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder()
.txPoolMaxSize(10)
.txPoolLimitByAccountPercentage(100.0f)
.build();
private final BaseFeePendingTransactionsSorter transactions =
new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder()
.txPoolMaxSize(10)
.txPoolLimitByAccountPercentage(100.0f)
.build(),
poolConf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
MergeCoordinatorTest::mockBlockHeader);
private TransactionPool transactionPool;
CompletableFuture<Void> blockCreationTask = CompletableFuture.completedFuture(null);
private final BadBlockManager badBlockManager = spy(new BadBlockManager());
@ -202,12 +215,26 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
MergeConfigOptions.setMergeEnabled(true);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
this.transactionPool =
new TransactionPool(
() -> transactions,
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
miningParameters,
new TransactionPoolMetrics(metricsSystem),
poolConf);
this.transactionPool.setEnabled();
this.coordinator =
new MergeCoordinator(
protocolContext,
protocolSchedule,
proposalBuilderExecutor,
transactions,
transactionPool,
miningParameters,
backwardSyncContext,
Optional.empty());
@ -254,7 +281,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
address.or(miningParameters::getCoinbase).orElse(Address.ZERO),
() -> Optional.of(30000000L),
parent -> Bytes.EMPTY,
transactions,
transactionPool,
protocolContext,
protocolSchedule,
this.miningParameters.getMinTransactionGasPrice(),
@ -659,7 +686,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
protocolContext,
protocolSchedule,
proposalBuilderExecutor,
transactions,
transactionPool,
miningParameters,
backwardSyncContext,
Optional.empty());
@ -943,7 +970,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
mockProtocolContext,
protocolSchedule,
CompletableFuture::runAsync,
transactions,
transactionPool,
new MiningParameters.Builder().coinbase(coinbase).build(),
mock(BackwardSyncContext.class),
Optional.empty());
@ -1005,7 +1032,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
mockProtocolContext,
protocolSchedule,
CompletableFuture::runAsync,
transactions,
transactionPool,
new MiningParameters.Builder().coinbase(coinbase).build(),
mock(BackwardSyncContext.class),
Optional.empty());
@ -1153,7 +1180,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
mockProtocolContext,
protocolSchedule,
CompletableFuture::runAsync,
transactions,
transactionPool,
new MiningParameters.Builder().coinbase(coinbase).build(),
mock(BackwardSyncContext.class),
Optional.empty()));

@ -35,7 +35,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
@ -60,7 +60,7 @@ import org.mockito.quality.Strictness;
@MockitoSettings(strictness = Strictness.LENIENT)
public class MergeReorgTest implements MergeGenesisConfigHelper {
@Mock PendingTransactions mockPendingTransactions;
@Mock TransactionPool mockTransactionPool;
private MergeCoordinator coordinator;
@ -92,7 +92,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
protocolContext,
mockProtocolSchedule,
CompletableFuture::runAsync,
mockPendingTransactions,
mockTransactionPool,
new MiningParameters.Builder().coinbase(coinbase).build(),
mock(BackwardSyncContext.class),
Optional.empty());

@ -17,7 +17,10 @@ package org.hyperledger.besu.consensus.qbft.support;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.BftFork;
import org.hyperledger.besu.config.JsonQbftConfigOptions;
@ -90,7 +93,12 @@ import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive;
@ -122,61 +130,20 @@ import com.google.common.collect.Iterables;
import org.apache.tuweni.bytes.Bytes;
public class TestContextBuilder {
@SuppressWarnings(
"UnusedVariable") // false positive https://github.com/google/error-prone/issues/2713
private record ControllerAndState(
BftExecutors bftExecutors,
BftEventHandler eventHandler,
BftFinalState finalState,
EventMultiplexer eventMultiplexer,
MessageFactory messageFactory,
ValidatorProvider validatorProvider) {}
private static final MetricsSystem metricsSystem = new NoOpMetricsSystem();
private boolean useValidatorContract;
private boolean useLondonMilestone = false;
private boolean useZeroBaseFee = false;
private static class ControllerAndState {
private final BftExecutors bftExecutors;
private final BftEventHandler eventHandler;
private final BftFinalState finalState;
private final EventMultiplexer eventMultiplexer;
private final MessageFactory messageFactory;
private final ValidatorProvider validatorProvider;
public ControllerAndState(
final BftExecutors bftExecutors,
final BftEventHandler eventHandler,
final BftFinalState finalState,
final EventMultiplexer eventMultiplexer,
final MessageFactory messageFactory,
final ValidatorProvider validatorProvider) {
this.bftExecutors = bftExecutors;
this.eventHandler = eventHandler;
this.finalState = finalState;
this.eventMultiplexer = eventMultiplexer;
this.messageFactory = messageFactory;
this.validatorProvider = validatorProvider;
}
public BftExecutors getBftExecutors() {
return bftExecutors;
}
public BftEventHandler getEventHandler() {
return eventHandler;
}
public BftFinalState getFinalState() {
return finalState;
}
public EventMultiplexer getEventMultiplexer() {
return eventMultiplexer;
}
public MessageFactory getMessageFactory() {
return messageFactory;
}
public ValidatorProvider getValidatorProvider() {
return validatorProvider;
}
}
public static final int EPOCH_LENGTH = 10_000;
public static final int BLOCK_TIMER_SEC = 3;
public static final int ROUND_TIMER_SEC = 12;
@ -329,7 +296,7 @@ public class TestContextBuilder {
new ValidatorPeer(
nodeParams,
new MessageFactory(nodeParams.getNodeKey()),
controllerAndState.getEventMultiplexer()),
controllerAndState.eventMultiplexer()),
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
@ -342,12 +309,12 @@ public class TestContextBuilder {
return new TestContext(
remotePeers,
blockChain,
controllerAndState.getBftExecutors(),
controllerAndState.getEventHandler(),
controllerAndState.getFinalState(),
controllerAndState.getEventMultiplexer(),
controllerAndState.getMessageFactory(),
controllerAndState.getValidatorProvider(),
controllerAndState.bftExecutors(),
controllerAndState.eventHandler(),
controllerAndState.finalState(),
controllerAndState.eventMultiplexer(),
controllerAndState.messageFactory(),
controllerAndState.validatorProvider(),
BFT_EXTRA_DATA_ENCODER);
}
@ -459,17 +426,33 @@ public class TestContextBuilder {
new QbftContext(validatorProvider, epochManager, blockInterface, Optional.empty()),
Optional.empty());
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build();
final GasPricePendingTransactionsSorter pendingTransactions =
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
clock,
metricsSystem,
blockChain::getChainHeadHeader);
poolConf, clock, metricsSystem, blockChain::getChainHeadHeader);
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
miningParams,
new TransactionPoolMetrics(metricsSystem),
poolConf);
transactionPool.setEnabled();
final Address localAddress = Util.publicKeyToAddress(nodeKey.getPublicKey());
final BftBlockCreatorFactory<?> blockCreatorFactory =
new QbftBlockCreatorFactory(
pendingTransactions, // changed from QbftBesuController
transactionPool, // changed from QbftBesuController
protocolContext,
protocolSchedule,
forksSchedule,

@ -26,7 +26,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.blockcreation.BlockCreator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import java.util.Collections;
@ -39,7 +39,7 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory<QbftConfigOp
/**
* Instantiates a new Qbft block creator factory.
*
* @param pendingTransactions the pending transactions
* @param transactionPool the pending transactions
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param forksSchedule the forks schedule
@ -48,7 +48,7 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory<QbftConfigOp
* @param bftExtraDataCodec the bft extra data codec
*/
public QbftBlockCreatorFactory(
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final ForksSchedule<QbftConfigOptions> forksSchedule,
@ -56,7 +56,7 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory<QbftConfigOp
final Address localAddress,
final BftExtraDataCodec bftExtraDataCodec) {
super(
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
forksSchedule,

@ -31,7 +31,7 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import java.util.Optional;
@ -59,7 +59,7 @@ public class QbftBlockCreatorFactoryTest {
qbftBlockCreatorFactory =
new QbftBlockCreatorFactory(
mock(PendingTransactions.class),
mock(TransactionPool.class),
mock(ProtocolContext.class),
mock(ProtocolSchedule.class),
forksSchedule,

@ -113,7 +113,7 @@ public class GraphQLDataFetchers {
return dataFetchingEnvironment -> {
final TransactionPool txPool =
dataFetchingEnvironment.getGraphQlContext().get(GraphQLContextType.TRANSACTION_POOL);
return Optional.of(new PendingStateAdapter(txPool.getPendingTransactions()));
return Optional.of(new PendingStateAdapter(txPool));
};
}

@ -20,7 +20,7 @@ import org.hyperledger.besu.ethereum.api.graphql.GraphQLContextType;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
@ -39,18 +39,18 @@ import org.apache.tuweni.units.bigints.UInt256;
@SuppressWarnings("unused") // reflected by GraphQL
public class PendingStateAdapter extends AdapterBase {
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
public PendingStateAdapter(final PendingTransactions pendingTransactions) {
this.pendingTransactions = pendingTransactions;
public PendingStateAdapter(final TransactionPool transactionPool) {
this.transactionPool = transactionPool;
}
public Integer getTransactionCount() {
return pendingTransactions.size();
return transactionPool.count();
}
public List<TransactionAdapter> getTransactions() {
return pendingTransactions.getPendingTransactions().stream()
return transactionPool.getPendingTransactions().stream()
.map(PendingTransaction::getTransaction)
.map(TransactionWithMetadata::new)
.map(TransactionAdapter::new)

@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.util.NonceProvider;
import java.util.OptionalLong;
@ -24,17 +24,17 @@ import java.util.OptionalLong;
public class LatestNonceProvider implements NonceProvider {
private final BlockchainQueries blockchainQueries;
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
public LatestNonceProvider(
final BlockchainQueries blockchainQueries, final PendingTransactions pendingTransactions) {
final BlockchainQueries blockchainQueries, final TransactionPool transactionPool) {
this.blockchainQueries = blockchainQueries;
this.pendingTransactions = pendingTransactions;
this.transactionPool = transactionPool;
}
@Override
public long getNonce(final Address address) {
final OptionalLong pendingNonce = pendingTransactions.getNextNonceForSender(address);
final OptionalLong pendingNonce = transactionPool.getNextNonceForSender(address);
return pendingNonce.orElseGet(
() -> blockchainQueries.getTransactionCount(address, blockchainQueries.headBlockNumber()));
}

@ -24,19 +24,19 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionCompleteResult;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionPendingResult;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.Optional;
public class EthGetTransactionByHash implements JsonRpcMethod {
private final BlockchainQueries blockchain;
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
public EthGetTransactionByHash(
final BlockchainQueries blockchain, final PendingTransactions pendingTransactions) {
final BlockchainQueries blockchain, final TransactionPool transactionPool) {
this.blockchain = blockchain;
this.pendingTransactions = pendingTransactions;
this.transactionPool = transactionPool;
}
@Override
@ -58,7 +58,7 @@ public class EthGetTransactionByHash implements JsonRpcMethod {
private Object getResult(final Hash hash) {
final Optional<Object> transactionPendingResult =
pendingTransactions.getTransactionByHash(hash).map(TransactionPendingResult::new);
transactionPool.getTransactionByHash(hash).map(TransactionPendingResult::new);
return transactionPendingResult.orElseGet(
() -> blockchain.transactionByHash(hash).map(TransactionCompleteResult::new).orElse(null));
}

@ -21,25 +21,25 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.function.Supplier;
import com.google.common.base.Suppliers;
public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMethod {
private final Supplier<PendingTransactions> pendingTransactions;
private final Supplier<TransactionPool> transactionPoolSupplier;
public EthGetTransactionCount(
final BlockchainQueries blockchain, final PendingTransactions pendingTransactions) {
this(Suppliers.ofInstance(blockchain), Suppliers.ofInstance(pendingTransactions));
final BlockchainQueries blockchain, final TransactionPool transactionPoolSupplier) {
this(Suppliers.ofInstance(blockchain), Suppliers.ofInstance(transactionPoolSupplier));
}
public EthGetTransactionCount(
final Supplier<BlockchainQueries> blockchain,
final Supplier<PendingTransactions> pendingTransactions) {
final Supplier<TransactionPool> transactionPoolSupplier) {
super(blockchain);
this.pendingTransactions = pendingTransactions;
this.transactionPoolSupplier = transactionPoolSupplier;
}
@Override
@ -56,7 +56,8 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet
@Override
protected Object pendingResult(final JsonRpcRequestContext request) {
final Address address = request.getRequiredParameter(0, Address.class);
final long pendingNonce = pendingTransactions.get().getNextNonceForSender(address).orElse(0);
final long pendingNonce =
transactionPoolSupplier.get().getNextNonceForSender(address).orElse(0);
final long latestNonce =
getBlockchainQueries()
.getTransactionCount(

@ -23,7 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionPen
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter.Filter;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.Collection;
import java.util.Collections;
@ -34,10 +34,10 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod {
final PendingTransactionFilter pendingTransactionFilter;
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
public TxPoolBesuPendingTransactions(final PendingTransactions pendingTransactions) {
this.pendingTransactions = pendingTransactions;
public TxPoolBesuPendingTransactions(final TransactionPool transactionPool) {
this.transactionPool = transactionPool;
this.pendingTransactionFilter = new PendingTransactionFilter();
}
@ -57,8 +57,7 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod {
.orElse(Collections.emptyList());
final Collection<Transaction> pendingTransactionsFiltered =
pendingTransactionFilter.reduce(
pendingTransactions.getPendingTransactions(), filters, limit);
pendingTransactionFilter.reduce(transactionPool.getPendingTransactions(), filters, limit);
return new JsonRpcSuccessResponse(
requestContext.getRequest().getId(),

@ -20,16 +20,16 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcRespon
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.PendingTransactionsStatisticsResult;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.Collection;
public class TxPoolBesuStatistics implements JsonRpcMethod {
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
public TxPoolBesuStatistics(final PendingTransactions pendingTransactions) {
this.pendingTransactions = pendingTransactions;
public TxPoolBesuStatistics(final TransactionPool transactionPool) {
this.transactionPool = transactionPool;
}
@Override
@ -44,11 +44,11 @@ public class TxPoolBesuStatistics implements JsonRpcMethod {
private PendingTransactionsStatisticsResult statistics() {
final Collection<PendingTransaction> pendingTransaction =
pendingTransactions.getPendingTransactions();
transactionPool.getPendingTransactions();
final long localCount =
pendingTransaction.stream().filter(PendingTransaction::isReceivedFromLocalSource).count();
final long remoteCount = pendingTransaction.size() - localCount;
return new PendingTransactionsStatisticsResult(
pendingTransactions.maxSize(), localCount, remoteCount);
transactionPool.maxSize(), localCount, remoteCount);
}
}

@ -19,14 +19,14 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.PendingTransactionsResult;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
public class TxPoolBesuTransactions implements JsonRpcMethod {
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
public TxPoolBesuTransactions(final PendingTransactions pendingTransactions) {
this.pendingTransactions = pendingTransactions;
public TxPoolBesuTransactions(final TransactionPool transactionPool) {
this.transactionPool = transactionPool;
}
@Override
@ -39,7 +39,7 @@ public class TxPoolBesuTransactions implements JsonRpcMethod {
final JsonRpcSuccessResponse jsonRpcSuccessResponse =
new JsonRpcSuccessResponse(
requestContext.getRequest().getId(),
new PendingTransactionsResult(pendingTransactions.getPendingTransactions()));
new PendingTransactionsResult(transactionPool.getPendingTransactions()));
return jsonRpcSuccessResponse;
}
}

@ -46,8 +46,7 @@ public class EeaJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
super(blockchainQueries, protocolSchedule, transactionPool, privacyParameters);
this.transactionPool = transactionPool;
this.privacyParameters = privacyParameters;
this.nonceProvider =
new LatestNonceProvider(blockchainQueries, transactionPool.getPendingTransactions());
this.nonceProvider = new LatestNonceProvider(blockchainQueries, transactionPool);
}
@Override

@ -138,10 +138,10 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
new EthNewBlockFilter(filterManager),
new EthNewPendingTransactionFilter(filterManager),
new EthNewFilter(filterManager),
new EthGetTransactionByHash(blockchainQueries, transactionPool.getPendingTransactions()),
new EthGetTransactionByHash(blockchainQueries, transactionPool),
new EthGetTransactionByBlockHashAndIndex(blockchainQueries),
new EthGetTransactionByBlockNumberAndIndex(blockchainQueries),
new EthGetTransactionCount(blockchainQueries, transactionPool.getPendingTransactions()),
new EthGetTransactionCount(blockchainQueries, transactionPool),
new EthGetTransactionReceipt(blockchainQueries),
new EthUninstallFilter(filterManager),
new EthGetFilterChanges(filterManager),

@ -39,8 +39,8 @@ public class TxPoolJsonRpcMethods extends ApiGroupJsonRpcMethods {
@Override
protected Map<String, JsonRpcMethod> create() {
return mapOf(
new TxPoolBesuTransactions(transactionPool.getPendingTransactions()),
new TxPoolBesuPendingTransactions(transactionPool.getPendingTransactions()),
new TxPoolBesuStatistics(transactionPool.getPendingTransactions()));
new TxPoolBesuTransactions(transactionPool),
new TxPoolBesuPendingTransactions(transactionPool),
new TxPoolBesuStatistics(transactionPool));
}
}

@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.ethereum.api.graphql;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
@ -27,7 +29,6 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.EthProtocol;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability;
@ -83,23 +84,20 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
public void setupTest() throws Exception {
final Synchronizer synchronizerMock = Mockito.mock(Synchronizer.class);
final SyncStatus status = new DefaultSyncStatus(1, 2, 3, Optional.of(4L), Optional.of(5L));
Mockito.when(synchronizerMock.getSyncStatus()).thenReturn(Optional.of(status));
when(synchronizerMock.getSyncStatus()).thenReturn(Optional.of(status));
final PoWMiningCoordinator miningCoordinatorMock = Mockito.mock(PoWMiningCoordinator.class);
Mockito.when(miningCoordinatorMock.getMinTransactionGasPrice()).thenReturn(Wei.of(16));
when(miningCoordinatorMock.getMinTransactionGasPrice()).thenReturn(Wei.of(16));
final TransactionPool transactionPoolMock = Mockito.mock(TransactionPool.class);
Mockito.when(transactionPoolMock.addTransactionViaApi(ArgumentMatchers.any(Transaction.class)))
when(transactionPoolMock.addTransactionViaApi(ArgumentMatchers.any(Transaction.class)))
.thenReturn(ValidationResult.valid());
// nonce too low tests uses a tx with nonce=16
Mockito.when(
transactionPoolMock.addTransactionViaApi(
ArgumentMatchers.argThat(tx -> tx.getNonce() == 16)))
when(transactionPoolMock.addTransactionViaApi(
ArgumentMatchers.argThat(tx -> tx.getNonce() == 16)))
.thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW));
final PendingTransactions pendingTransactionsMock = Mockito.mock(PendingTransactions.class);
Mockito.when(transactionPoolMock.getPendingTransactions()).thenReturn(pendingTransactionsMock);
Mockito.when(pendingTransactionsMock.getPendingTransactions())
Mockito.when(transactionPoolMock.getPendingTransactions())
.thenReturn(
Collections.singleton(
new PendingTransaction.Local(

@ -38,7 +38,6 @@ import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.EthProtocol;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.p2p.network.P2PNetwork;
@ -140,8 +139,6 @@ public abstract class AbstractJsonRpcHttpServiceTest {
// nonce too low tests uses a tx with nonce=16
when(transactionPoolMock.addTransactionViaApi(argThat(tx -> tx.getNonce() == 16)))
.thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW));
final PendingTransactions pendingTransactionsMock = mock(PendingTransactions.class);
when(transactionPoolMock.getPendingTransactions()).thenReturn(pendingTransactionsMock);
final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
final BlockchainQueries blockchainQueries =

@ -19,7 +19,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.OptionalLong;
@ -37,17 +37,17 @@ public class LatestNonceProviderTest {
@Mock private BlockchainQueries blockchainQueries;
private LatestNonceProvider nonceProvider;
@Mock private PendingTransactions pendingTransactions;
@Mock private TransactionPool transactionPool;
@Before
public void setUp() {
nonceProvider = new LatestNonceProvider(blockchainQueries, pendingTransactions);
nonceProvider = new LatestNonceProvider(blockchainQueries, transactionPool);
}
@Test
public void nextNonceUsesTxPool() {
final long highestNonceInPendingTransactions = 123;
when(pendingTransactions.getNextNonceForSender(senderAddress))
when(transactionPool.getNextNonceForSender(senderAddress))
.thenReturn(OptionalLong.of(highestNonceInPendingTransactions));
assertThat(nonceProvider.getNonce(senderAddress)).isEqualTo(highestNonceInPendingTransactions);
}
@ -56,7 +56,7 @@ public class LatestNonceProviderTest {
public void nextNonceIsTakenFromBlockchainIfNoPendingTransactionResponse() {
final long headBlockNumber = 8;
final long nonceInBlockchain = 56;
when(pendingTransactions.getNextNonceForSender(senderAddress)).thenReturn(OptionalLong.empty());
when(transactionPool.getNextNonceForSender(senderAddress)).thenReturn(OptionalLong.empty());
when(blockchainQueries.headBlockNumber()).thenReturn(headBlockNumber);
when(blockchainQueries.getTransactionCount(senderAddress, headBlockNumber))
.thenReturn(nonceInBlockchain);

@ -33,7 +33,7 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.plugin.data.Transaction;
import java.util.Optional;
@ -58,11 +58,11 @@ public class EthGetTransactionByHashTest {
private final String JSON_RPC_VERSION = "2.0";
private final String ETH_METHOD = "eth_getTransactionByHash";
@Mock private PendingTransactions pendingTransactions;
@Mock private TransactionPool transactionPool;
@Before
public void setUp() {
method = new EthGetTransactionByHash(blockchainQueries, pendingTransactions);
method = new EthGetTransactionByHash(blockchainQueries, transactionPool);
}
@Test
@ -87,7 +87,7 @@ public class EthGetTransactionByHashTest {
public void shouldReturnNullResultWhenTransactionDoesNotExist() {
final String transactionHash =
"0xf9ef5f0cf02685711cdf687b72d4754901729b942f4ea7f956e7fb206cae2f9e";
when(pendingTransactions.getTransactionByHash(eq(Hash.fromHexString(transactionHash))))
when(transactionPool.getTransactionByHash(eq(Hash.fromHexString(transactionHash))))
.thenReturn(Optional.empty());
when(blockchainQueries.transactionByHash(eq(Hash.fromHexString(transactionHash))))
.thenReturn(Optional.empty());
@ -110,7 +110,7 @@ public class EthGetTransactionByHashTest {
org.hyperledger.besu.ethereum.core.Transaction.readFrom(
Bytes.fromHexString(VALID_TRANSACTION));
when(pendingTransactions.getTransactionByHash(eq(transaction.getHash())))
when(transactionPool.getTransactionByHash(eq(transaction.getHash())))
.thenReturn(Optional.of(transaction));
verifyNoInteractions(blockchainQueries);
@ -135,9 +135,9 @@ public class EthGetTransactionByHashTest {
final TransactionWithMetadata transactionWithMetadata =
new TransactionWithMetadata(transaction, 1, Optional.empty(), Hash.ZERO, 0);
when(pendingTransactions.getTransactionByHash(eq(transaction.getHash())))
when(transactionPool.getTransactionByHash(eq(transaction.getHash())))
.thenReturn(Optional.empty());
verifyNoMoreInteractions(pendingTransactions);
verifyNoMoreInteractions(transactionPool);
when(blockchainQueries.transactionByHash(eq(transaction.getHash())))
.thenReturn(Optional.of(transactionWithMetadata));
@ -158,9 +158,9 @@ public class EthGetTransactionByHashTest {
@Test
public void validateResultSpec() {
PendingTransaction pendingTx = getPendingTransactions().stream().findFirst().get();
PendingTransaction pendingTx = getTransactionPool().stream().findFirst().get();
Hash hash = pendingTx.getHash();
when(this.pendingTransactions.getTransactionByHash(hash))
when(this.transactionPool.getTransactionByHash(hash))
.thenReturn(Optional.of(pendingTx.getTransaction()));
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
@ -188,7 +188,7 @@ public class EthGetTransactionByHashTest {
assertThat(result.getS()).isNotNull();
}
private Set<PendingTransaction> getPendingTransactions() {
private Set<PendingTransaction> getTransactionPool() {
final BlockDataGenerator gen = new BlockDataGenerator();
Transaction pendingTransaction = gen.transaction();

@ -27,7 +27,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.ChainHead;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.OptionalLong;
@ -42,19 +42,19 @@ public class EthGetTransactionCountTest {
private EthGetTransactionCount ethGetTransactionCount;
private final String pendingTransactionString = "0x00000000000000000000000000000000000000AA";
private final Object[] pendingParams = new Object[] {pendingTransactionString, "pending"};
private PendingTransactions pendingTransactions;
private TransactionPool transactionPool;
@BeforeEach
public void setup() {
pendingTransactions = mock(PendingTransactions.class);
ethGetTransactionCount = new EthGetTransactionCount(blockchainQueries, pendingTransactions);
transactionPool = mock(TransactionPool.class);
ethGetTransactionCount = new EthGetTransactionCount(blockchainQueries, transactionPool);
}
@Test
public void shouldUsePendingTransactionsWhenToldTo() {
final Address address = Address.fromHexString(pendingTransactionString);
when(pendingTransactions.getNextNonceForSender(address)).thenReturn(OptionalLong.of(12));
when(transactionPool.getNextNonceForSender(address)).thenReturn(OptionalLong.of(12));
mockGetTransactionCount(address, 7L);
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
@ -68,7 +68,7 @@ public class EthGetTransactionCountTest {
public void shouldUseLatestTransactionsWhenNoPendingTransactions() {
final Address address = Address.fromHexString(pendingTransactionString);
when(pendingTransactions.getNextNonceForSender(address)).thenReturn(OptionalLong.empty());
when(transactionPool.getNextNonceForSender(address)).thenReturn(OptionalLong.empty());
mockGetTransactionCount(address, 7L);
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
@ -83,7 +83,7 @@ public class EthGetTransactionCountTest {
final Address address = Address.fromHexString(pendingTransactionString);
mockGetTransactionCount(address, 8);
when(pendingTransactions.getNextNonceForSender(Address.fromHexString(pendingTransactionString)))
when(transactionPool.getNextNonceForSender(Address.fromHexString(pendingTransactionString)))
.thenReturn(OptionalLong.of(4));
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
@ -97,8 +97,7 @@ public class EthGetTransactionCountTest {
public void shouldReturnPendingWithHighNonce() {
final Address address = Address.fromHexString(pendingTransactionString);
when(pendingTransactions.getNextNonceForSender(address))
.thenReturn(OptionalLong.of(MAX_NONCE - 1));
when(transactionPool.getNextNonceForSender(address)).thenReturn(OptionalLong.of(MAX_NONCE - 1));
mockGetTransactionCount(address, 7L);
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
@ -112,8 +111,7 @@ public class EthGetTransactionCountTest {
public void shouldReturnLatestWithHighNonce() {
final Address address = Address.fromHexString(pendingTransactionString);
when(pendingTransactions.getNextNonceForSender(address))
.thenReturn(OptionalLong.of(MAX_NONCE - 2));
when(transactionPool.getNextNonceForSender(address)).thenReturn(OptionalLong.of(MAX_NONCE - 2));
mockGetTransactionCount(address, MAX_NONCE - 1);
final JsonRpcRequestContext request =
new JsonRpcRequestContext(

@ -26,7 +26,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionPendingResult;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.util.HashMap;
import java.util.Map;
@ -44,7 +44,7 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TxPoolBesuPendingTransactionsTest {
@Mock private PendingTransactions pendingTransactions;
@Mock private TransactionPool transactionPool;
private TxPoolBesuPendingTransactions method;
private final String JSON_RPC_VERSION = "2.0";
private final String TXPOOL_PENDING_TRANSACTIONS_METHOD = "txpool_besuPendingTransactions";
@ -52,9 +52,9 @@ public class TxPoolBesuPendingTransactionsTest {
@Before
public void setUp() {
listTrx = getPendingTransactions();
method = new TxPoolBesuPendingTransactions(pendingTransactions);
when(this.pendingTransactions.getPendingTransactions()).thenReturn(listTrx);
listTrx = getTransactionPool();
method = new TxPoolBesuPendingTransactions(transactionPool);
when(transactionPool.getPendingTransactions()).thenReturn(listTrx);
}
@Test
@ -72,7 +72,7 @@ public class TxPoolBesuPendingTransactionsTest {
final JsonRpcSuccessResponse actualResponse = (JsonRpcSuccessResponse) method.response(request);
final Set<TransactionPendingResult> result =
(Set<TransactionPendingResult>) actualResponse.getResult();
assertThat(result.size()).isEqualTo(getPendingTransactions().size());
assertThat(result.size()).isEqualTo(getTransactionPool().size());
}
@Test
@ -253,7 +253,7 @@ public class TxPoolBesuPendingTransactionsTest {
.hasMessageContaining("The `to` filter only supports the `eq` or `action` operator");
}
private Set<PendingTransaction> getPendingTransactions() {
private Set<PendingTransaction> getTransactionPool() {
final BlockDataGenerator gen = new BlockDataGenerator();
return gen.transactionsWithAllTypes(4).stream()

@ -23,7 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.PendingTransactionsStatisticsResult;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import com.google.common.collect.Sets;
import org.junit.Before;
@ -35,14 +35,14 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TxPoolBesuStatisticsTest {
@Mock private PendingTransactions pendingTransactions;
@Mock private TransactionPool transactionPool;
private TxPoolBesuStatistics method;
private final String JSON_RPC_VERSION = "2.0";
private final String TXPOOL_PENDING_TRANSACTIONS_METHOD = "txpool_besuStatistics";
@Before
public void setUp() {
method = new TxPoolBesuStatistics(pendingTransactions);
method = new TxPoolBesuStatistics(transactionPool);
}
@Test
@ -60,8 +60,8 @@ public class TxPoolBesuStatisticsTest {
final PendingTransaction local = createTransactionInfo(true);
final PendingTransaction secondLocal = createTransactionInfo(true);
final PendingTransaction remote = createTransactionInfo(false);
when(pendingTransactions.maxSize()).thenReturn(123L);
when(pendingTransactions.getPendingTransactions())
when(transactionPool.maxSize()).thenReturn(123L);
when(transactionPool.getPendingTransactions())
.thenReturn(Sets.newHashSet(local, secondLocal, remote));
final JsonRpcSuccessResponse actualResponse = (JsonRpcSuccessResponse) method.response(request);

@ -25,7 +25,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.PendingTransactionResult;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.PendingTransactionsResult;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import java.time.Instant;
@ -39,7 +39,7 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TxPoolBesuTransactionsTest {
@Mock private PendingTransactions pendingTransactions;
@Mock private TransactionPool transactionPool;
private TxPoolBesuTransactions method;
private final String JSON_RPC_VERSION = "2.0";
private final String TXPOOL_PENDING_TRANSACTIONS_METHOD = "txpool_besuTransactions";
@ -48,7 +48,7 @@ public class TxPoolBesuTransactionsTest {
@Before
public void setUp() {
method = new TxPoolBesuTransactions(pendingTransactions);
method = new TxPoolBesuTransactions(transactionPool);
}
@Test
@ -68,8 +68,7 @@ public class TxPoolBesuTransactionsTest {
when(pendingTransaction.getHash()).thenReturn(Hash.fromHexString(TRANSACTION_HASH));
when(pendingTransaction.isReceivedFromLocalSource()).thenReturn(true);
when(pendingTransaction.getAddedAt()).thenReturn(addedAt);
when(pendingTransactions.getPendingTransactions())
.thenReturn(Sets.newHashSet(pendingTransaction));
when(transactionPool.getPendingTransactions()).thenReturn(Sets.newHashSet(pendingTransaction));
final JsonRpcSuccessResponse actualResponse = (JsonRpcSuccessResponse) method.response(request);
final PendingTransactionsResult result = (PendingTransactionsResult) actualResponse.getResult();

@ -33,7 +33,7 @@ import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
import org.hyperledger.besu.ethereum.mainnet.DepositsValidator;
@ -79,7 +79,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
protected final Supplier<Optional<Long>> targetGasLimitSupplier;
private final ExtraDataCalculator extraDataCalculator;
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
protected final ProtocolContext protocolContext;
protected final ProtocolSchedule protocolSchedule;
protected final BlockHeaderFunctions blockHeaderFunctions;
@ -95,7 +95,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final Wei minTransactionGasPrice,
@ -106,7 +106,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
this.miningBeneficiaryCalculator = miningBeneficiaryCalculator;
this.targetGasLimitSupplier = targetGasLimitSupplier;
this.extraDataCalculator = extraDataCalculator;
this.pendingTransactions = pendingTransactions;
this.transactionPool = transactionPool;
this.protocolContext = protocolContext;
this.protocolSchedule = protocolSchedule;
this.minTransactionGasPrice = minTransactionGasPrice;
@ -317,7 +317,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
transactionProcessor,
protocolContext.getBlockchain(),
disposableWorldState,
pendingTransactions,
transactionPool,
processableBlockHeader,
transactionReceiptFactory,
minTransactionGasPrice,

@ -21,7 +21,7 @@ import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
import org.hyperledger.besu.ethereum.chain.PoWObserver;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.util.Subscribers;
@ -45,7 +45,7 @@ public abstract class AbstractMinerExecutor<M extends BlockMiner<? extends Abstr
private final ExecutorService executorService = Executors.newCachedThreadPool();
protected final ProtocolContext protocolContext;
protected final ProtocolSchedule protocolSchedule;
protected final PendingTransactions pendingTransactions;
protected final TransactionPool transactionPool;
protected final AbstractBlockScheduler blockScheduler;
protected volatile Bytes extraData;
@ -58,12 +58,12 @@ public abstract class AbstractMinerExecutor<M extends BlockMiner<? extends Abstr
protected AbstractMinerExecutor(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler) {
this.protocolContext = protocolContext;
this.protocolSchedule = protocolSchedule;
this.pendingTransactions = pendingTransactions;
this.transactionPool = transactionPool;
this.extraData = miningParams.getExtraData();
this.minTransactionGasPrice = miningParams.getMinTransactionGasPrice();
this.blockScheduler = blockScheduler;

@ -23,7 +23,7 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState;
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.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
@ -216,7 +216,7 @@ public class BlockTransactionSelector {
private final ProcessableBlockHeader processableBlockHeader;
private final Blockchain blockchain;
private final MutableWorldState worldState;
private final PendingTransactions pendingTransactions;
private final TransactionPool transactionPool;
private final AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory;
private final Address miningBeneficiary;
private final Wei dataGasPrice;
@ -232,7 +232,7 @@ public class BlockTransactionSelector {
final MainnetTransactionProcessor transactionProcessor,
final Blockchain blockchain,
final MutableWorldState worldState,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProcessableBlockHeader processableBlockHeader,
final AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory,
final Wei minTransactionGasPrice,
@ -247,7 +247,7 @@ public class BlockTransactionSelector {
this.transactionProcessor = transactionProcessor;
this.blockchain = blockchain;
this.worldState = worldState;
this.pendingTransactions = pendingTransactions;
this.transactionPool = transactionPool;
this.processableBlockHeader = processableBlockHeader;
this.transactionReceiptFactory = transactionReceiptFactory;
this.isCancelled = isCancelled;
@ -271,9 +271,9 @@ public class BlockTransactionSelector {
public TransactionSelectionResults buildTransactionListForBlock() {
LOG.atDebug()
.setMessage("Transaction pool stats {}")
.addArgument(pendingTransactions.logStats())
.addArgument(transactionPool::logStats)
.log();
pendingTransactions.selectTransactions(
transactionPool.selectTransactions(
pendingTransaction -> {
final var res = evaluateTransaction(pendingTransaction);
transactionSelectionResults.addSelectionResult(res);
@ -414,7 +414,7 @@ public class BlockTransactionSelector {
// 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()
&& !pendingTransactions.isLocalSender(transaction.getSender())) {
&& !transactionPool.isLocalSender(transaction.getSender())) {
// 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

@ -20,7 +20,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.EthHash;
import org.hyperledger.besu.ethereum.mainnet.PoWSolution;
import org.hyperledger.besu.ethereum.mainnet.PoWSolver;
@ -43,7 +43,7 @@ public class PoWBlockCreator extends AbstractBlockCreator {
final Address coinbase,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final PoWSolver nonceSolver,
@ -55,7 +55,7 @@ public class PoWBlockCreator extends AbstractBlockCreator {
__ -> coinbase,
targetGasLimitSupplier,
extraDataCalculator,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,

@ -20,7 +20,7 @@ import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
import org.hyperledger.besu.ethereum.chain.PoWObserver;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.EpochCalculator;
import org.hyperledger.besu.ethereum.mainnet.PoWSolver;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@ -43,13 +43,13 @@ public class PoWMinerExecutor extends AbstractMinerExecutor<PoWBlockMiner> {
public PoWMinerExecutor(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final MiningParameters miningParams,
final AbstractBlockScheduler blockScheduler,
final EpochCalculator epochCalculator,
final long powJobTimeToLive,
final int maxOmmerDepth) {
super(protocolContext, protocolSchedule, pendingTransactions, miningParams, blockScheduler);
super(protocolContext, protocolSchedule, transactionPool, miningParams, blockScheduler);
this.coinbase = miningParams.getCoinbase();
this.nonceGenerator = miningParams.getNonceGenerator().orElse(new RandomNonceGenerator());
this.epochCalculator = epochCalculator;
@ -92,7 +92,7 @@ public class PoWMinerExecutor extends AbstractMinerExecutor<PoWBlockMiner> {
coinbase.orElse(Address.ZERO),
() -> targetGasLimit.map(AtomicLong::longValue),
parent -> extraData,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
solver,

@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSpecs.DEFAULT_DEPOSIT_CONTRACT_ADDRESS;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@ -41,11 +42,17 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.Deposit;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
@ -282,19 +289,33 @@ abstract class AbstractBlockCreatorTest {
.build();
final MutableBlockchain blockchain = executionContextTestFixture.getBlockchain();
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(100).build();
final AbstractPendingTransactionsSorter sorter =
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(100).build(),
Clock.systemUTC(),
new NoOpMetricsSystem(),
blockchain::getChainHeadHeader);
poolConf, Clock.systemUTC(), new NoOpMetricsSystem(), blockchain::getChainHeadHeader);
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() -> sorter,
executionContextTestFixture.getProtocolSchedule(),
executionContextTestFixture.getProtocolContext(),
mock(TransactionBroadcaster.class),
ethContext,
mock(MiningParameters.class),
new TransactionPoolMetrics(new NoOpMetricsSystem()),
poolConf);
transactionPool.setEnabled();
return new TestBlockCreator(
Address.ZERO,
__ -> Address.ZERO,
() -> Optional.of(30_000_000L),
__ -> Bytes.fromHexString("deadbeef"),
sorter,
transactionPool,
executionContextTestFixture.getProtocolContext(),
executionContextTestFixture.getProtocolSchedule(),
Wei.of(1L),
@ -310,7 +331,7 @@ abstract class AbstractBlockCreatorTest {
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final AbstractPendingTransactionsSorter pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final Wei minTransactionGasPrice,
@ -322,7 +343,7 @@ abstract class AbstractBlockCreatorTest {
miningBeneficiaryCalculator,
targetGasLimitSupplier,
extraDataCalculator,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,

@ -18,7 +18,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
@ -28,28 +27,33 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.AddressHelpers;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
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.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyProtocolSchedule;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
@ -60,12 +64,12 @@ import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import org.hyperledger.besu.plugin.data.TransactionType;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
import org.hyperledger.besu.testutil.TestClock;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
import java.math.BigInteger;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@ -75,6 +79,7 @@ import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@ -82,23 +87,65 @@ import org.mockito.junit.MockitoJUnitRunner;
public abstract class AbstractBlockTransactionSelectorTest {
protected static final double MIN_OCCUPANCY_80_PERCENT = 0.8;
protected static final double MIN_OCCUPANCY_100_PERCENT = 1;
protected static final BigInteger CHAIN_ID = BigInteger.valueOf(42L);
protected static final KeyPair keyPair =
SignatureAlgorithmFactory.getInstance().generateKeyPair();
protected static final Address sender =
Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes()));
protected final MetricsSystem metricsSystem = new NoOpMetricsSystem();
protected final Blockchain blockchain = new ReferenceTestBlockchain();
protected PendingTransactions pendingTransactions;
protected GenesisConfigFile genesisConfigFile;
protected MutableBlockchain blockchain;
protected TransactionPool transactionPool;
protected MutableWorldState worldState;
protected ProtocolSchedule protocolSchedule;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
protected ProtocolContext protocolContext;
@Mock protected MainnetTransactionProcessor transactionProcessor;
@Mock protected MiningParameters miningParameters;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
protected EthContext ethContext;
@Before
public void setup() {
genesisConfigFile = getGenesisConfigFile();
protocolSchedule = createProtocolSchedule();
final Block genesisBlock =
GenesisState.fromConfig(genesisConfigFile, protocolSchedule).getBlock();
blockchain =
DefaultBlockchain.createMutable(
genesisBlock,
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()),
new NoOpMetricsSystem(),
0);
when(protocolContext.getBlockchain()).thenReturn(blockchain);
worldState = InMemoryKeyValueStorageProvider.createInMemoryWorldState();
pendingTransactions = createPendingTransactions();
final var worldStateUpdater = worldState.updater();
worldStateUpdater.createAccount(sender, 0, Wei.of(1_000_000_000L));
worldStateUpdater.commit();
when(protocolContext.getWorldStateArchive().getMutable(any(), anyBoolean()))
.thenReturn(Optional.of(worldState));
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
when(miningParameters.getMinTransactionGasPrice()).thenReturn(Wei.ONE);
transactionPool = createTransactionPool();
}
protected abstract PendingTransactions createPendingTransactions();
protected abstract GenesisConfigFile getGenesisConfigFile();
protected abstract ProtocolSchedule createProtocolSchedule();
protected abstract TransactionPool createTransactionPool();
private Boolean isCancelled() {
return false;
@ -129,7 +176,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
protocolSchedule.getByBlockHeader(blockHeader(0)).getTransactionProcessor();
// The block should fit 5 transactions only
final ProcessableBlockHeader blockHeader = createBlock(5000);
final ProcessableBlockHeader blockHeader = createBlock(500_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
@ -152,13 +199,13 @@ public abstract class AbstractBlockTransactionSelectorTest {
@Test
public void failedTransactionsAreIncludedInTheBlock() {
final Transaction transaction = createTransaction(1);
pendingTransactions.addRemoteTransaction(transaction, Optional.empty());
final Transaction transaction = createTransaction(1, Wei.of(7L), 100_000);
transactionPool.addRemoteTransactions(List.of(transaction));
ensureTransactionIsValid(transaction, 0, 5);
// The block should fit 3 transactions only
final ProcessableBlockHeader blockHeader = createBlock(5000);
final ProcessableBlockHeader blockHeader = createBlock(500_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
@ -177,25 +224,25 @@ public abstract class AbstractBlockTransactionSelectorTest {
assertThat(results.getTransactions().size()).isEqualTo(1);
Assertions.assertThat(results.getTransactions()).contains(transaction);
assertThat(results.getReceipts().size()).isEqualTo(1);
assertThat(results.getCumulativeGasUsed()).isEqualTo(95L);
assertThat(results.getCumulativeGasUsed()).isEqualTo(99995L);
}
@Test
public void invalidTransactionsTransactionProcessingAreSkippedButBlockStillFills() {
final List<Transaction> transactionsToInject = Lists.newArrayList();
for (int i = 0; i < 5; i++) {
final Transaction tx = createTransaction(i);
final Transaction tx = createTransaction(i, Wei.of(7), 100_000);
transactionsToInject.add(tx);
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
if (i == 1) {
ensureTransactionIsInvalid(tx, TransactionInvalidReason.NONCE_TOO_LOW);
ensureTransactionIsInvalid(tx, TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE);
} else {
ensureTransactionIsValid(tx);
}
}
transactionPool.addRemoteTransactions(transactionsToInject);
// The block should fit 3 transactions only
final ProcessableBlockHeader blockHeader = createBlock(5000);
// The block should fit 4 transactions only
final ProcessableBlockHeader blockHeader = createBlock(400_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
@ -214,21 +261,20 @@ public abstract class AbstractBlockTransactionSelectorTest {
assertThat(results.getTransactions().size()).isEqualTo(4);
assertThat(results.getTransactions().contains(transactionsToInject.get(1))).isFalse();
assertThat(results.getReceipts().size()).isEqualTo(4);
assertThat(results.getCumulativeGasUsed()).isEqualTo(400);
assertThat(results.getCumulativeGasUsed()).isEqualTo(400_000);
}
@Test
public void subsetOfPendingTransactionsIncludedWhenBlockGasLimitHit() {
final List<Transaction> transactionsToInject = Lists.newArrayList();
// Transactions are reported in reverse order.
for (int i = 0; i < 5; i++) {
final Transaction tx = createTransaction(i);
final Transaction tx = createTransaction(i, Wei.of(7), 100_000);
transactionsToInject.add(tx);
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
ensureTransactionIsValid(tx);
}
transactionPool.addRemoteTransactions(transactionsToInject);
final ProcessableBlockHeader blockHeader = createBlock(301);
final ProcessableBlockHeader blockHeader = createBlock(301_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
@ -248,81 +294,40 @@ public abstract class AbstractBlockTransactionSelectorTest {
assertThat(results.getTransactions().containsAll(transactionsToInject.subList(0, 3))).isTrue();
assertThat(results.getReceipts().size()).isEqualTo(3);
assertThat(results.getCumulativeGasUsed()).isEqualTo(300);
assertThat(results.getCumulativeGasUsed()).isEqualTo(300_000);
// Ensure receipts have the correct cumulative gas
Assertions.assertThat(results.getReceipts().get(0).getCumulativeGasUsed()).isEqualTo(100);
Assertions.assertThat(results.getReceipts().get(1).getCumulativeGasUsed()).isEqualTo(200);
Assertions.assertThat(results.getReceipts().get(2).getCumulativeGasUsed()).isEqualTo(300);
Assertions.assertThat(results.getReceipts().get(0).getCumulativeGasUsed()).isEqualTo(100_000);
Assertions.assertThat(results.getReceipts().get(1).getCumulativeGasUsed()).isEqualTo(200_000);
Assertions.assertThat(results.getReceipts().get(2).getCumulativeGasUsed()).isEqualTo(300_000);
}
@Test
public void useSingleGasSpaceForAllTransactions() {
final ProcessableBlockHeader blockHeader = createBlock(300);
final ProcessableBlockHeader blockHeader = createBlock(300_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BaseFeePendingTransactionsSorter pendingTransactions1559 =
new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(5).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
() -> {
final BlockHeader mockBlockHeader = mock(BlockHeader.class);
when(mockBlockHeader.getBaseFee()).thenReturn(Optional.of(Wei.ONE));
return mockBlockHeader;
});
final BlockTransactionSelector selector =
new BlockTransactionSelector(
createBlockSelector(
transactionProcessor,
blockchain,
worldState,
pendingTransactions1559,
blockHeader,
this::createReceipt,
Wei.of(6),
0.8,
this::isCancelled,
Wei.ZERO,
miningBeneficiary,
Wei.ZERO,
FeeMarket.london(0L),
new LondonGasCalculator(),
GasLimitCalculator.constant(),
Optional.empty());
MIN_OCCUPANCY_80_PERCENT);
// this should fill up all the block space
final Transaction fillingLegacyTx =
Transaction.builder()
.type(TransactionType.FRONTIER)
.gasLimit(300)
.gasPrice(Wei.of(10))
.nonce(1)
.payload(Bytes.EMPTY)
.to(Address.ID)
.value(Wei.ZERO)
.sender(Address.ID)
.chainId(BigInteger.ONE)
.signAndBuild(keyPair);
final Transaction fillingLegacyTx = createTransaction(0, Wei.of(10), 300_000);
ensureTransactionIsValid(fillingLegacyTx);
// so we shouldn't include this
final Transaction extraEIP1559Tx =
Transaction.builder()
.type(TransactionType.EIP1559)
.nonce(0)
.maxPriorityFeePerGas(Wei.of(10))
.maxFeePerGas(Wei.of(10))
.gasLimit(50)
.to(Address.ID)
.value(Wei.of(0))
.payload(Bytes.EMPTY)
.chainId(BigInteger.ONE)
.signAndBuild(keyPair);
final Transaction extraEIP1559Tx = createEIP1559Transaction(0, Wei.of(10), Wei.of(10), 50_000);
ensureTransactionIsValid(extraEIP1559Tx);
pendingTransactions1559.addRemoteTransaction(fillingLegacyTx, Optional.empty());
pendingTransactions1559.addRemoteTransaction(extraEIP1559Tx, Optional.empty());
transactionPool.addRemoteTransactions(List.of(fillingLegacyTx, extraEIP1559Tx));
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
@ -343,40 +348,32 @@ public abstract class AbstractBlockTransactionSelectorTest {
Wei.ZERO,
MIN_OCCUPANCY_80_PERCENT);
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
// Add 3 transactions to the Pending Transactions, 79% of block, 100% of block and 10% of block
// should end up selecting the first and third only.
// NOTE - PendingTransactions outputs these in nonce order
final List<Transaction> transactionsToInject = Lists.newArrayList();
transactionsToInject.add(
txTestFixture
.gasLimit((long) (blockHeader.getGasLimit() * 0.79))
.nonce(1)
.createTransaction(keyPair));
transactionsToInject.add(
txTestFixture.gasLimit(blockHeader.getGasLimit()).nonce(2).createTransaction(keyPair));
transactionsToInject.add(
txTestFixture
.gasLimit((long) (blockHeader.getGasLimit() * 0.1))
.nonce(3)
.createTransaction(keyPair));
final Transaction[] txs =
new Transaction[] {
createTransaction(1, Wei.of(10), (long) (blockHeader.getGasLimit() * 0.79)),
createTransaction(2, Wei.of(10), blockHeader.getGasLimit()),
createTransaction(3, Wei.of(10), (long) (blockHeader.getGasLimit() * 0.1))
};
for (final Transaction tx : transactionsToInject) {
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
for (final Transaction tx : txs) {
ensureTransactionIsValid(tx);
}
transactionPool.addRemoteTransactions(Arrays.stream(txs).toList());
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
assertThat(results.getTransactions().size()).isEqualTo(2);
Assertions.assertThat(results.getTransactions().get(0)).isEqualTo(transactionsToInject.get(0));
Assertions.assertThat(results.getTransactions().get(1)).isEqualTo(transactionsToInject.get(2));
Assertions.assertThat(results.getTransactions().get(0)).isEqualTo(txs[0]);
Assertions.assertThat(results.getTransactions().get(1)).isEqualTo(txs[2]);
}
@Test
public void transactionSelectionStopsWhenSufficientBlockOccupancyIsReached() {
final ProcessableBlockHeader blockHeader = createBlock(300);
final ProcessableBlockHeader blockHeader = createBlock(300_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector =
@ -388,35 +385,22 @@ public abstract class AbstractBlockTransactionSelectorTest {
Wei.ZERO,
MIN_OCCUPANCY_80_PERCENT);
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
// Add 4 transactions to the Pending Transactions 15% (ok), 79% (ok), 25% (too large), 10%
// (not included, it would fit, however previous transaction was too large and block was
// suitably populated).
// NOTE - PendingTransactions will output these in nonce order.
final Transaction[] txs =
new Transaction[] {
txTestFixture
.gasLimit((long) (blockHeader.getGasLimit() * 0.15))
.nonce(1)
.createTransaction(keyPair),
txTestFixture
.gasLimit((long) (blockHeader.getGasLimit() * 0.79))
.nonce(2)
.createTransaction(keyPair),
txTestFixture
.gasLimit((long) (blockHeader.getGasLimit() * 0.25))
.nonce(3)
.createTransaction(keyPair),
txTestFixture
.gasLimit((long) (blockHeader.getGasLimit() * 0.1))
.nonce(4)
.createTransaction(keyPair)
createTransaction(0, Wei.of(10), (long) (blockHeader.getGasLimit() * 0.15)),
createTransaction(1, Wei.of(10), (long) (blockHeader.getGasLimit() * 0.79)),
createTransaction(2, Wei.of(10), (long) (blockHeader.getGasLimit() * 0.25)),
createTransaction(3, Wei.of(10), (long) (blockHeader.getGasLimit() * 0.1))
};
for (Transaction tx : txs) {
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
ensureTransactionIsValid(tx);
}
transactionPool.addRemoteTransactions(Arrays.stream(txs).toList());
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
@ -458,18 +442,17 @@ public abstract class AbstractBlockTransactionSelectorTest {
final long gasLimit3 = minTxGasCost;
final long gasLimit4 = minTxGasCost;
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
final List<Transaction> transactionsToInject = Lists.newArrayList();
transactionsToInject.add(txTestFixture.gasLimit(gasLimit0).nonce(0).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit1).nonce(1).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit2).nonce(2).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit3).nonce(3).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit4).nonce(4).createTransaction(keyPair));
transactionsToInject.add(createTransaction(0, Wei.of(7), gasLimit0));
transactionsToInject.add(createTransaction(1, Wei.of(7), gasLimit1));
transactionsToInject.add(createTransaction(2, Wei.of(7), gasLimit2));
transactionsToInject.add(createTransaction(3, Wei.of(7), gasLimit3));
transactionsToInject.add(createTransaction(4, Wei.of(7), gasLimit4));
for (final Transaction tx : transactionsToInject) {
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
ensureTransactionIsValid(tx);
}
transactionPool.addRemoteTransactions(transactionsToInject);
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
@ -508,17 +491,16 @@ public abstract class AbstractBlockTransactionSelectorTest {
final long gasLimit2 = blockHeader.getGasLimit() - gasLimit0 - (minTxGasCost - 1);
final long gasLimit3 = minTxGasCost;
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
final List<Transaction> transactionsToInject = Lists.newArrayList();
transactionsToInject.add(txTestFixture.gasLimit(gasLimit0).nonce(0).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit1).nonce(1).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit2).nonce(2).createTransaction(keyPair));
transactionsToInject.add(txTestFixture.gasLimit(gasLimit3).nonce(3).createTransaction(keyPair));
transactionsToInject.add(createTransaction(0, Wei.of(10), gasLimit0));
transactionsToInject.add(createTransaction(1, Wei.of(10), gasLimit1));
transactionsToInject.add(createTransaction(2, Wei.of(10), gasLimit2));
transactionsToInject.add(createTransaction(3, Wei.of(10), gasLimit3));
for (final Transaction tx : transactionsToInject) {
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
ensureTransactionIsValid(tx);
}
transactionPool.addRemoteTransactions(transactionsToInject);
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
@ -530,7 +512,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
@Test
public void shouldDiscardTransactionsThatFailValidation() {
final ProcessableBlockHeader blockHeader = createBlock(300);
final ProcessableBlockHeader blockHeader = createBlock(300_000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector =
@ -542,62 +524,45 @@ public abstract class AbstractBlockTransactionSelectorTest {
Wei.ZERO,
MIN_OCCUPANCY_80_PERCENT);
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
final Transaction validTransaction =
txTestFixture.nonce(1).gasLimit(1).createTransaction(keyPair);
ensureTransactionIsValid(validTransaction, 2000, 10000);
final Transaction invalidTransaction =
txTestFixture.nonce(2).gasLimit(2).createTransaction(keyPair);
final Transaction validTransaction = createTransaction(0, Wei.of(10), 21_000);
ensureTransactionIsValid(validTransaction, 21_000, 0);
final Transaction invalidTransaction = createTransaction(3, Wei.of(10), 21_000);
ensureTransactionIsInvalid(
invalidTransaction, TransactionInvalidReason.EXCEEDS_BLOCK_GAS_LIMIT);
invalidTransaction, TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE);
pendingTransactions.addRemoteTransaction(validTransaction, Optional.empty());
pendingTransactions.addRemoteTransaction(invalidTransaction, Optional.empty());
transactionPool.addRemoteTransactions(List.of(validTransaction, invalidTransaction));
selector.buildTransactionListForBlock();
Assertions.assertThat(pendingTransactions.getTransactionByHash(validTransaction.getHash()))
Assertions.assertThat(transactionPool.getTransactionByHash(validTransaction.getHash()))
.isPresent();
Assertions.assertThat(pendingTransactions.getTransactionByHash(invalidTransaction.getHash()))
Assertions.assertThat(transactionPool.getTransactionByHash(invalidTransaction.getHash()))
.isNotPresent();
}
@Test
public void transactionSelectionPluginShouldWork() {
final ProcessableBlockHeader blockHeader = createBlock(300);
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
final Transaction selected =
txTestFixture
.nonce(1)
.gasLimit(1)
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
ensureTransactionIsValid(selected, 2000, 10000);
final Transaction notSelectedTransient =
txTestFixture
.nonce(1)
.gasLimit(1)
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
ensureTransactionIsValid(notSelectedTransient, 2000, 10000);
final Transaction notSelectedInvalid =
txTestFixture
.nonce(1)
.gasLimit(1)
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
ensureTransactionIsValid(notSelectedInvalid, 2000, 10000);
final ProcessableBlockHeader blockHeader = createBlock(300_000);
final Transaction selected = createTransaction(0, Wei.of(10), 21_000);
ensureTransactionIsValid(selected, 21_000, 0);
final Transaction notSelectedTransient = createTransaction(1, Wei.of(10), 21_000);
ensureTransactionIsValid(notSelectedTransient, 21_000, 0);
final Transaction notSelectedInvalid = createTransaction(2, Wei.of(10), 21_000);
ensureTransactionIsValid(notSelectedInvalid, 21_000, 0);
final TransactionSelectorFactory transactionSelectorFactory =
(TransactionSelectorFactory)
() ->
(tx, s, logs, cg) -> {
if (tx.equals(notSelectedTransient))
return TransactionSelectionResult.invalidTransient("transient");
if (tx.equals(notSelectedInvalid))
return TransactionSelectionResult.invalid("invalid");
return TransactionSelectionResult.SELECTED;
};
() ->
(tx, s, logs, cg) -> {
if (tx.equals(notSelectedTransient))
return TransactionSelectionResult.invalidTransient("transient");
if (tx.equals(notSelectedInvalid))
return TransactionSelectionResult.invalid("invalid");
return TransactionSelectionResult.SELECTED;
};
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector =
@ -610,35 +575,26 @@ public abstract class AbstractBlockTransactionSelectorTest {
MIN_OCCUPANCY_80_PERCENT,
transactionSelectorFactory);
pendingTransactions.addRemoteTransaction(selected, Optional.empty());
pendingTransactions.addRemoteTransaction(notSelectedTransient, Optional.empty());
pendingTransactions.addRemoteTransaction(notSelectedInvalid, Optional.empty());
transactionPool.addRemoteTransactions(
List.of(selected, notSelectedInvalid, notSelectedTransient));
final BlockTransactionSelector.TransactionSelectionResults transactionSelectionResults =
selector.buildTransactionListForBlock();
Assertions.assertThat(pendingTransactions.getTransactionByHash(notSelectedTransient.getHash()))
.isPresent();
Assertions.assertThat(pendingTransactions.getTransactionByHash(notSelectedInvalid.getHash()))
.isNotPresent();
// Assertions.assertThat(pendingTransactions.getTransactionByHash(selected.getHash()))
// .isNotPresent(); // TODO check with Fabio what should happen with selected txs
Assertions.assertThat(transactionSelectionResults.getTransactions()).contains(selected);
Assertions.assertThat(transactionSelectionResults.getTransactions())
.doesNotContain(notSelectedTransient);
Assertions.assertThat(transactionSelectionResults.getTransactions())
.doesNotContain(notSelectedInvalid);
assertThat(transactionPool.getTransactionByHash(notSelectedTransient.getHash())).isPresent();
assertThat(transactionPool.getTransactionByHash(notSelectedInvalid.getHash())).isNotPresent();
assertThat(transactionSelectionResults.getTransactions()).contains(selected);
assertThat(transactionSelectionResults.getTransactions()).doesNotContain(notSelectedTransient);
assertThat(transactionSelectionResults.getTransactions()).doesNotContain(notSelectedInvalid);
}
@Test
public void transactionWithIncorrectNonceRemainsInPoolAndNotSelected() {
final ProcessableBlockHeader blockHeader = createBlock(5000);
final ProcessableBlockHeader blockHeader = createBlock(5_000_000);
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
final Transaction futureTransaction =
txTestFixture.nonce(4).gasLimit(1).createTransaction(keyPair);
final Transaction futureTransaction = createTransaction(4, Wei.of(10), 100_000);
pendingTransactions.addRemoteTransaction(futureTransaction, Optional.empty());
transactionPool.addRemoteTransactions(List.of(futureTransaction));
ensureTransactionIsInvalid(futureTransaction, TransactionInvalidReason.NONCE_TOO_HIGH);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
@ -654,7 +610,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
Assertions.assertThat(pendingTransactions.getTransactionByHash(futureTransaction.getHash()))
Assertions.assertThat(transactionPool.getTransactionByHash(futureTransaction.getHash()))
.isPresent();
assertThat(results.getTransactions().size()).isEqualTo(0);
}
@ -671,7 +627,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
transactionProcessor,
blockchain,
worldState,
pendingTransactions,
transactionPool,
blockHeader,
this::createReceipt,
minGasPrice,
@ -700,7 +656,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
transactionProcessor,
blockchain,
worldState,
pendingTransactions,
transactionPool,
blockHeader,
this::createReceipt,
minGasPrice,
@ -716,24 +672,48 @@ public abstract class AbstractBlockTransactionSelectorTest {
return selector;
}
protected abstract GasCalculator getGasCalculator();
protected GasCalculator getGasCalculator() {
return protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()).getGasCalculator();
}
protected abstract FeeMarket getFeeMarket();
protected FeeMarket getFeeMarket() {
return protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()).getFeeMarket();
}
private Transaction createTransaction(final int transactionNumber) {
protected Transaction createTransaction(
final int nonce, final Wei gasPrice, final long gasLimit) {
return Transaction.builder()
.gasLimit(100)
.gasPrice(Wei.of(5))
.nonce(transactionNumber)
.gasLimit(gasLimit)
.gasPrice(gasPrice)
.nonce(nonce)
.payload(Bytes.EMPTY)
.to(Address.ID)
.value(Wei.of(transactionNumber))
.sender(Address.ID)
.chainId(BigInteger.ONE)
.value(Wei.of(nonce))
.sender(sender)
.chainId(CHAIN_ID)
.guessType()
.signAndBuild(keyPair);
}
protected Transaction createEIP1559Transaction(
final int nonce,
final Wei maxFeePerGas,
final Wei maxPriorityFeePerGas,
final long gasLimit) {
return Transaction.builder()
.type(TransactionType.EIP1559)
.gasLimit(gasLimit)
.maxFeePerGas(maxFeePerGas)
.maxPriorityFeePerGas(maxPriorityFeePerGas)
.nonce(nonce)
.payload(Bytes.EMPTY)
.to(Address.ID)
.value(Wei.of(nonce))
.sender(sender)
.chainId(CHAIN_ID)
.signAndBuild(keyPair);
}
// This is a duplicate of the MainnetProtocolSpec::frontierTransactionReceiptFactory
private TransactionReceipt createReceipt(
final TransactionType __,

@ -14,50 +14,80 @@
*/
package org.hyperledger.besu.ethereum.blockcreation;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.testutil.TestClock;
import java.time.ZoneId;
import java.util.Optional;
import java.util.function.Function;
public class LegacyFeeMarketBlockTransactionSelectorTest
extends AbstractBlockTransactionSelectorTest {
@Override
protected PendingTransactions createPendingTransactions() {
protected GenesisConfigFile getGenesisConfigFile() {
return GenesisConfigFile.genesisFileFromResources(
"/block-transaction-selector/gas-price-genesis.json");
}
return new GasPricePendingTransactionsSorter(
@Override
protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
CHAIN_ID,
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT)
.createProtocolSchedule();
}
@Override
protected TransactionPool createTransactionPool() {
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder()
.txPoolMaxSize(5)
.txPoolLimitByAccountPercentage(1)
.build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
LegacyFeeMarketBlockTransactionSelectorTest::mockBlockHeader);
}
.build();
private static BlockHeader mockBlockHeader() {
final BlockHeader blockHeader = mock(BlockHeader.class);
when(blockHeader.getBaseFee()).thenReturn(Optional.empty());
return blockHeader;
}
final PendingTransactions pendingTransactions =
new GasPricePendingTransactionsSorter(
poolConf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader);
@Override
protected FeeMarket getFeeMarket() {
return FeeMarket.legacy();
}
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
@Override
protected GasCalculator getGasCalculator() {
return new BerlinGasCalculator();
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
miningParameters,
new TransactionPoolMetrics(metricsSystem),
poolConf);
transactionPool.setEnabled();
return transactionPool;
}
}

@ -16,65 +16,86 @@ package org.hyperledger.besu.ethereum.blockcreation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.AddressHelpers;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
import org.hyperledger.besu.plugin.data.TransactionType;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.testutil.TestClock;
import java.math.BigInteger;
import java.time.ZoneId;
import java.util.Optional;
import java.util.List;
import java.util.function.Function;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Test;
public class LondonFeeMarketBlockTransactionSelectorTest
extends AbstractBlockTransactionSelectorTest {
@Override
protected PendingTransactions createPendingTransactions() {
return new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder()
.txPoolMaxSize(5)
.txPoolLimitByAccountPercentage(1)
.build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
LondonFeeMarketBlockTransactionSelectorTest::mockBlockHeader);
protected GenesisConfigFile getGenesisConfigFile() {
return GenesisConfigFile.genesisFileFromResources(
"/block-transaction-selector/london-genesis.json");
}
@Override
protected GasCalculator getGasCalculator() {
return new LondonGasCalculator();
}
private static BlockHeader mockBlockHeader() {
final BlockHeader blockHeader = mock(BlockHeader.class);
when(blockHeader.getBaseFee()).thenReturn(Optional.of(Wei.ONE));
return blockHeader;
protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
CHAIN_ID,
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
EvmConfiguration.DEFAULT)
.createProtocolSchedule();
}
@Override
protected FeeMarket getFeeMarket() {
return FeeMarket.london(0L);
protected TransactionPool createTransactionPool() {
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder()
.txPoolMaxSize(5)
.txPoolLimitByAccountPercentage(1)
.build();
final PendingTransactions pendingTransactions =
new BaseFeePendingTransactionsSorter(
poolConf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
blockchain::getChainHeadHeader);
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
miningParameters,
new TransactionPoolMetrics(metricsSystem),
poolConf);
transactionPool.setEnabled();
return transactionPool;
}
@Test
public void eip1559TransactionCurrentGasPriceLessThanMinimumIsSkippedAndKeptInThePool() {
final ProcessableBlockHeader blockHeader = createBlock(301, Wei.ONE);
final ProcessableBlockHeader blockHeader = createBlock(301_000, Wei.ONE);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector =
@ -86,21 +107,22 @@ public class LondonFeeMarketBlockTransactionSelectorTest
Wei.ZERO,
MIN_OCCUPANCY_80_PERCENT);
// tx is willing to pay max 6 wei for gas, but current network condition (baseFee == 1)
// tx is willing to pay max 7 wei for gas, but current network condition (baseFee == 1)
// result in it paying 2 wei, that is below the minimum accepted by the node, so it is skipped
final Transaction tx = createEIP1559Transaction(1, Wei.of(6L), Wei.ONE);
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
final Transaction tx = createEIP1559Transaction(1, Wei.of(7L), Wei.ONE, 100_000);
final var addResults = transactionPool.addRemoteTransactions(List.of(tx));
assertThat(addResults).extractingByKey(tx.getHash()).isEqualTo(ValidationResult.valid());
final BlockTransactionSelector.TransactionSelectionResults results =
selector.buildTransactionListForBlock();
assertThat(results.getTransactions().size()).isEqualTo(0);
assertThat(pendingTransactions.size()).isEqualTo(1);
assertThat(transactionPool.count()).isEqualTo(1);
}
@Test
public void eip1559TransactionCurrentGasPriceGreaterThanMinimumIsSelected() {
final ProcessableBlockHeader blockHeader = createBlock(301, Wei.of(5));
final ProcessableBlockHeader blockHeader = createBlock(301_000, Wei.of(5));
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector =
@ -112,10 +134,10 @@ public class LondonFeeMarketBlockTransactionSelectorTest
Wei.ZERO,
MIN_OCCUPANCY_80_PERCENT);
// tx is willing to pay max 6 wei for gas, and current network condition (baseFee == 5)
// tx is willing to pay max 7 wei for gas, and current network condition (baseFee == 5)
// result in it paying the max, that is >= the minimum accepted by the node, so it is selected
final Transaction tx = createEIP1559Transaction(1, Wei.of(6), Wei.ONE);
pendingTransactions.addRemoteTransaction(tx, Optional.empty());
final Transaction tx = createEIP1559Transaction(1, Wei.of(7), Wei.ONE, 100_000);
transactionPool.addRemoteTransactions(List.of(tx));
ensureTransactionIsValid(tx);
@ -123,12 +145,12 @@ public class LondonFeeMarketBlockTransactionSelectorTest
selector.buildTransactionListForBlock();
assertThat(results.getTransactions().size()).isEqualTo(1);
assertThat(pendingTransactions.size()).isEqualTo(1);
assertThat(transactionPool.count()).isEqualTo(1);
}
@Test
public void eip1559LocalTransactionCurrentGasPriceLessThanMinimumIsSelected() {
final ProcessableBlockHeader blockHeader = createBlock(301, Wei.ONE);
final ProcessableBlockHeader blockHeader = createBlock(301_000, Wei.ONE);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector =
@ -140,11 +162,12 @@ public class LondonFeeMarketBlockTransactionSelectorTest
Wei.ZERO,
MIN_OCCUPANCY_80_PERCENT);
// tx is willing to pay max 6 wei for gas, but current network condition (baseFee == 1)
// tx is willing to pay max 7 wei for gas, but current network condition (baseFee == 1)
// result in it paying 2 wei, that is below the minimum accepted by the node, but since it is
// a local sender it is accepted anyway
final Transaction tx = createEIP1559Transaction(1, Wei.of(6L), Wei.ONE);
pendingTransactions.addLocalTransaction(tx, Optional.empty());
final Transaction tx = createEIP1559Transaction(1, Wei.of(7L), Wei.ONE, 100_000);
final var addResult = transactionPool.addTransactionViaApi(tx);
assertThat(addResult.isValid()).isTrue();
ensureTransactionIsValid(tx);
@ -152,35 +175,19 @@ public class LondonFeeMarketBlockTransactionSelectorTest
selector.buildTransactionListForBlock();
assertThat(results.getTransactions().size()).isEqualTo(1);
assertThat(pendingTransactions.size()).isEqualTo(1);
assertThat(transactionPool.count()).isEqualTo(1);
}
@Test
public void transactionFromSameSenderWithMixedTypes() {
final ProcessableBlockHeader blockHeader = createBlock(5000);
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
final Transaction txFrontier1 =
txTestFixture
.type(TransactionType.FRONTIER)
.nonce(0)
.gasLimit(1)
.gasPrice(Wei.ONE)
.createTransaction(keyPair);
final Transaction txLondon1 = createEIP1559Transaction(1, Wei.ONE, Wei.ONE);
final Transaction txFrontier2 =
txTestFixture
.type(TransactionType.FRONTIER)
.nonce(2)
.gasLimit(1)
.gasPrice(Wei.ONE)
.createTransaction(keyPair);
final Transaction txLondon2 = createEIP1559Transaction(3, Wei.ONE, Wei.ONE);
pendingTransactions.addRemoteTransaction(txFrontier1, Optional.empty());
pendingTransactions.addRemoteTransaction(txLondon1, Optional.empty());
pendingTransactions.addRemoteTransaction(txFrontier2, Optional.empty());
pendingTransactions.addRemoteTransaction(txLondon2, Optional.empty());
final ProcessableBlockHeader blockHeader = createBlock(5_000_000);
final Transaction txFrontier1 = createTransaction(0, Wei.of(7L), 100_000);
final Transaction txLondon1 = createEIP1559Transaction(1, Wei.ONE, Wei.ONE, 100_000);
final Transaction txFrontier2 = createTransaction(2, Wei.of(7L), 100_000);
final Transaction txLondon2 = createEIP1559Transaction(3, Wei.ONE, Wei.ONE, 100_000);
transactionPool.addRemoteTransactions(List.of(txFrontier1, txLondon1, txFrontier2, txLondon2));
ensureTransactionIsValid(txFrontier1);
ensureTransactionIsValid(txLondon1);
@ -203,21 +210,4 @@ public class LondonFeeMarketBlockTransactionSelectorTest
assertThat(results.getTransactions())
.containsExactly(txFrontier1, txLondon1, txFrontier2, txLondon2);
}
private Transaction createEIP1559Transaction(
final int transactionNumber, final Wei maxFeePerGas, final Wei maxPriorityFeePerGas) {
return Transaction.builder()
.type(TransactionType.EIP1559)
.gasLimit(100)
.maxFeePerGas(maxFeePerGas)
.maxPriorityFeePerGas(maxPriorityFeePerGas)
.nonce(transactionNumber)
.payload(Bytes.EMPTY)
.to(Address.ID)
.value(Wei.of(transactionNumber))
.sender(Address.ID)
.chainId(BigInteger.ONE)
.guessType()
.signAndBuild(keyPair);
}
}

@ -15,6 +15,10 @@
package org.hyperledger.besu.ethereum.blockcreation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
@ -27,10 +31,16 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.EpochCalculator;
import org.hyperledger.besu.ethereum.mainnet.PoWHasher;
@ -94,19 +104,14 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
1000,
8);
final BaseFeePendingTransactionsSorter pendingTransactions =
new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.fixed(),
metricsSystem,
executionContextTestFixture.getProtocolContext().getBlockchain()::getChainHeadHeader);
final TransactionPool transactionPool = createTransactionPool(executionContextTestFixture);
final PoWBlockCreator blockCreator =
new PoWBlockCreator(
BLOCK_1_COINBASE,
Optional::empty,
parent -> BLOCK_1_EXTRA_DATA,
pendingTransactions,
transactionPool,
executionContextTestFixture.getProtocolContext(),
executionContextTestFixture.getProtocolSchedule(),
solver,
@ -155,19 +160,14 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
1000,
8);
final BaseFeePendingTransactionsSorter pendingTransactions =
new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.fixed(),
metricsSystem,
executionContextTestFixture.getProtocolContext().getBlockchain()::getChainHeadHeader);
final TransactionPool transactionPool = createTransactionPool(executionContextTestFixture);
final PoWBlockCreator blockCreator =
new PoWBlockCreator(
BLOCK_1_COINBASE,
Optional::empty,
parent -> BLOCK_1_EXTRA_DATA,
pendingTransactions,
transactionPool,
executionContextTestFixture.getProtocolContext(),
executionContextTestFixture.getProtocolSchedule(),
solver,
@ -207,19 +207,14 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
1000,
8);
final BaseFeePendingTransactionsSorter pendingTransactions =
new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.fixed(),
metricsSystem,
executionContextTestFixture.getProtocolContext().getBlockchain()::getChainHeadHeader);
final TransactionPool transactionPool = createTransactionPool(executionContextTestFixture);
final PoWBlockCreator blockCreator =
new PoWBlockCreator(
BLOCK_1_COINBASE,
() -> Optional.of(10_000_000L),
parent -> BLOCK_1_EXTRA_DATA,
pendingTransactions,
transactionPool,
executionContextTestFixture.getProtocolContext(),
executionContextTestFixture.getProtocolSchedule(),
solver,
@ -281,19 +276,14 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
1000,
8);
final BaseFeePendingTransactionsSorter pendingTransactions =
new BaseFeePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.fixed(),
metricsSystem,
executionContextTestFixture.getProtocolContext().getBlockchain()::getChainHeadHeader);
final TransactionPool transactionPool = createTransactionPool(executionContextTestFixture);
final PoWBlockCreator blockCreator =
new PoWBlockCreator(
BLOCK_1_COINBASE,
() -> Optional.of(10_000_000L),
parent -> BLOCK_1_EXTRA_DATA,
pendingTransactions,
transactionPool,
executionContextTestFixture.getProtocolContext(),
executionContextTestFixture.getProtocolSchedule(),
solver,
@ -326,4 +316,34 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
assertThat(mutableWorldState.get(BLOCK_1_COINBASE)).isNull();
}
private TransactionPool createTransactionPool(
final ExecutionContextTestFixture executionContextTestFixture) {
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build();
final BaseFeePendingTransactionsSorter pendingTransactions =
new BaseFeePendingTransactionsSorter(
poolConf,
TestClock.fixed(),
metricsSystem,
executionContextTestFixture.getProtocolContext().getBlockchain()::getChainHeadHeader);
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
executionContextTestFixture.getProtocolSchedule(),
executionContextTestFixture.getProtocolContext(),
mock(TransactionBroadcaster.class),
ethContext,
mock(MiningParameters.class),
new TransactionPoolMetrics(metricsSystem),
poolConf);
transactionPool.setEnabled();
return transactionPool;
}
}

@ -15,15 +15,24 @@
package org.hyperledger.besu.ethereum.blockcreation;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.EpochCalculator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.testutil.TestClock;
@ -42,18 +51,13 @@ public class PoWMinerExecutorTest {
final MiningParameters miningParameters =
new MiningParameters.Builder().coinbase(null).minTransactionGasPrice(Wei.of(1000)).build();
final GasPricePendingTransactionsSorter pendingTransactions =
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
PoWMinerExecutorTest::mockBlockHeader);
final TransactionPool transactionPool = createTransactionPool(miningParameters);
final PoWMinerExecutor executor =
new PoWMinerExecutor(
null,
null,
pendingTransactions,
transactionPool,
miningParameters,
new DefaultBlockScheduler(1, 10, TestClock.fixed()),
new EpochCalculator.DefaultEpochCalculator(),
@ -69,18 +73,13 @@ public class PoWMinerExecutorTest {
public void settingCoinbaseToNullThrowsException() {
final MiningParameters miningParameters = new MiningParameters.Builder().build();
final GasPricePendingTransactionsSorter pendingTransactions =
new GasPricePendingTransactionsSorter(
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(),
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
PoWMinerExecutorTest::mockBlockHeader);
final TransactionPool transactionPool = createTransactionPool(miningParameters);
final PoWMinerExecutor executor =
new PoWMinerExecutor(
null,
null,
pendingTransactions,
transactionPool,
miningParameters,
new DefaultBlockScheduler(1, 10, TestClock.fixed()),
new EpochCalculator.DefaultEpochCalculator(),
@ -97,4 +96,32 @@ public class PoWMinerExecutorTest {
when(blockHeader.getBaseFee()).thenReturn(Optional.empty());
return blockHeader;
}
private TransactionPool createTransactionPool(final MiningParameters miningParameters) {
final TransactionPoolConfiguration poolConf =
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build();
final GasPricePendingTransactionsSorter pendingTransactions =
new GasPricePendingTransactionsSorter(
poolConf,
TestClock.system(ZoneId.systemDefault()),
metricsSystem,
PoWMinerExecutorTest::mockBlockHeader);
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
final TransactionPool transactionPool =
new TransactionPool(
() -> pendingTransactions,
mock(ProtocolSchedule.class),
mock(ProtocolContext.class),
mock(TransactionBroadcaster.class),
ethContext,
miningParameters,
new TransactionPoolMetrics(new NoOpMetricsSystem()),
poolConf);
transactionPool.setEnabled();
return transactionPool;
}
}

@ -0,0 +1,21 @@
{
"config": {
"chainId": 42,
"homesteadBlock": 0,
"daoForkBlock": 0,
"eip150Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0
},
"nonce": "0x42",
"timestamp": "0x0",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x989680",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000"
}

@ -0,0 +1,23 @@
{
"config": {
"chainId": 42,
"homesteadBlock": 0,
"daoForkBlock": 0,
"eip150Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0,
"londonBlock": 0
},
"nonce": "0x42",
"timestamp": "0x0",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x989680",
"baseFeePerGas": "0x1",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000"
}

@ -16,6 +16,10 @@
package org.hyperledger.besu.ethereum.bonsai;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisAllocation;
import org.hyperledger.besu.config.GenesisConfigFile;
@ -37,13 +41,17 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolReplacementHandler;
@ -84,6 +92,7 @@ public abstract class AbstractIsolationTests {
protected BonsaiWorldStateProvider archive;
protected BonsaiWorldStateKeyValueStorage bonsaiWorldStateStorage;
protected ProtocolContext protocolContext;
protected EthContext ethContext;
final Function<String, KeyPair> asKeyPair =
key ->
SignatureAlgorithmFactory.getInstance()
@ -125,6 +134,7 @@ public abstract class AbstractIsolationTests {
.collect(Collectors.toList());
KeyPair sender1 = asKeyPair.apply(accounts.get(0).getPrivateKey().get());
TransactionPool transactionPool;
@Rule public final TemporaryFolder tempData = new TemporaryFolder();
@ -144,6 +154,19 @@ public abstract class AbstractIsolationTests {
var ws = archive.getMutable();
genesisState.writeStateTo(ws);
protocolContext = new ProtocolContext(blockchain, archive, null, Optional.empty());
ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
transactionPool =
new TransactionPool(
() -> sorter,
protocolSchedule,
protocolContext,
mock(TransactionBroadcaster.class),
ethContext,
mock(MiningParameters.class),
txPoolMetrics,
poolConfiguration);
transactionPool.setEnabled();
}
// storage provider which uses a temporary directory based rocksdb
@ -194,7 +217,7 @@ public abstract class AbstractIsolationTests {
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final Supplier<Optional<Long>> targetGasLimitSupplier,
final ExtraDataCalculator extraDataCalculator,
final PendingTransactions pendingTransactions,
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final Wei minTransactionGasPrice,
@ -205,7 +228,7 @@ public abstract class AbstractIsolationTests {
miningBeneficiaryCalculator,
targetGasLimitSupplier,
extraDataCalculator,
pendingTransactions,
transactionPool,
protocolContext,
protocolSchedule,
minTransactionGasPrice,
@ -218,13 +241,13 @@ public abstract class AbstractIsolationTests {
final BlockHeader parentHeader,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final PendingTransactions sorter) {
final TransactionPool transactionPool) {
return new TestBlockCreator(
Address.ZERO,
__ -> Address.ZERO,
() -> Optional.of(30_000_000L),
__ -> Bytes.fromHexString("deadbeef"),
sorter,
transactionPool,
protocolContext,
protocolSchedule,
Wei.of(1L),
@ -260,7 +283,7 @@ public abstract class AbstractIsolationTests {
protected Block forTransactions(
final List<Transaction> transactions, final BlockHeader forHeader) {
return TestBlockCreator.forHeader(forHeader, protocolContext, protocolSchedule, sorter)
return TestBlockCreator.forHeader(forHeader, protocolContext, protocolSchedule, transactionPool)
.createBlock(transactions, Collections.emptyList(), System.currentTimeMillis())
.getBlock();
}

@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.INTERNAL_ERROR;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.TRANSACTION_ALREADY_KNOWN;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
@ -56,6 +57,7 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.concurrent.CompletableFuture;
@ -198,20 +200,25 @@ public class TransactionPool implements BlockAddedObserver {
.sorted(Comparator.comparing(Transaction::getSender).thenComparing(Transaction::getNonce));
}
public void addRemoteTransactions(final Collection<Transaction> transactions) {
public Map<Hash, ValidationResult<TransactionInvalidReason>> addRemoteTransactions(
final Collection<Transaction> transactions) {
final long started = System.currentTimeMillis();
final int initialCount = transactions.size();
final List<Transaction> addedTransactions = new ArrayList<>(initialCount);
LOG.debug("Adding {} remote transactions", initialCount);
sortedBySenderAndNonce(transactions)
.forEach(
transaction -> {
final var result = addRemoteTransaction(transaction);
if (result.isValid()) {
addedTransactions.add(transaction);
}
});
final var validationResults =
sortedBySenderAndNonce(transactions)
.collect(
Collectors.toMap(
Transaction::getHash,
transaction -> {
final var result = addRemoteTransaction(transaction);
if (result.isValid()) {
addedTransactions.add(transaction);
}
return result;
}));
LOG_FOR_REPLAY
.atTrace()
@ -231,6 +238,7 @@ public class TransactionPool implements BlockAddedObserver {
if (!addedTransactions.isEmpty()) {
transactionBroadcaster.onTransactionsAdded(addedTransactions);
}
return validationResults;
}
private ValidationResult<TransactionInvalidReason> addRemoteTransaction(
@ -359,10 +367,6 @@ public class TransactionPool implements BlockAddedObserver {
.getTransactionValidator();
}
public PendingTransactions getPendingTransactions() {
return pendingTransactions;
}
private ValidationResultAndAccount validateLocalTransaction(final Transaction transaction) {
return validateTransaction(transaction, true);
}
@ -491,6 +495,44 @@ public class TransactionPool implements BlockAddedObserver {
return blockchain.getBlockHeader(blockchain.getChainHeadHash());
}
public boolean isLocalSender(final Address sender) {
return pendingTransactions.isLocalSender(sender);
}
public int count() {
return pendingTransactions.size();
}
public Collection<PendingTransaction> getPendingTransactions() {
return pendingTransactions.getPendingTransactions();
}
public OptionalLong getNextNonceForSender(final Address address) {
return pendingTransactions.getNextNonceForSender(address);
}
public long maxSize() {
return pendingTransactions.maxSize();
}
public void evictOldTransactions() {
pendingTransactions.evictOldTransactions();
}
public void selectTransactions(
final PendingTransactions.TransactionSelector transactionSelector) {
pendingTransactions.selectTransactions(transactionSelector);
}
public String logStats() {
return pendingTransactions.logStats();
}
@VisibleForTesting
Class<? extends PendingTransactions> pendingTransactionsImplementation() {
return pendingTransactions.getClass();
}
public interface TransactionBatchAddedListener {
void onTransactionsAdded(Collection<Transaction> transactions);

@ -37,7 +37,7 @@ public class TransactionPoolEvictionService {
TimeUnit.MINUTES.toMillis(1),
id -> {
if (transactionPool.isEnabled()) {
transactionPool.getPendingTransactions().evictOldTransactions();
transactionPool.evictOldTransactions();
}
}));
}

@ -17,6 +17,11 @@ package org.hyperledger.besu.ethereum.eth.manager.ethtaskutils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.spy;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SECPPublicKey;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
@ -52,6 +57,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@ -62,6 +68,19 @@ import org.junit.Test;
*/
public abstract class AbstractMessageTaskTest<T, R> {
protected static final int MAX_PEERS = 5;
protected static final KeyPair genesisAccountKeyPair =
new KeyPair(
SECPPrivateKey.create(
Bytes32.fromHexString(
"0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"),
"ECDSA"),
SECPPublicKey.create(
Bytes.fromHexString(
"0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3"),
"ECDSA"));
protected static final Address genesisAccountSender =
Address.extract(Hash.hash(genesisAccountKeyPair.getPublicKey().getEncodedBytes()));
protected static final long genesisAccountNonce = 32;
protected static Blockchain blockchain;
protected static ProtocolSchedule protocolSchedule;
protected static ProtocolContext protocolContext;
@ -119,6 +138,8 @@ public abstract class AbstractMessageTaskTest<T, R> {
syncState,
new MiningParameters.Builder().minTransactionGasPrice(Wei.ONE).build(),
TransactionPoolConfiguration.DEFAULT);
transactionPool.setEnabled();
ethProtocolManager =
EthProtocolManagerTestUtil.create(
blockchain,

@ -16,14 +16,12 @@ package org.hyperledger.besu.ethereum.eth.manager.task;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
import org.hyperledger.besu.ethereum.eth.manager.ethtaskutils.PeerMessageTaskTest;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem;
@ -40,18 +38,16 @@ public class GetPooledTransactionsFromPeerTaskTest extends PeerMessageTaskTest<L
@Override
protected List<Transaction> generateDataToBeRequested() {
final List<Transaction> requestedData = new ArrayList<>();
KeyPair keyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
final List<Transaction> requestedData = new ArrayList<>(3);
for (int i = 0; i < 3; i++) {
Transaction tx =
new TransactionTestFixture()
.nonce(i)
.nonce(genesisAccountNonce + i)
.gasPrice(Wei.ONE)
.gasLimit(100000)
.chainId(Optional.empty())
.createTransaction(keyPair);
assertThat(transactionPool.getPendingTransactions().addLocalTransaction(tx, Optional.empty()))
.isEqualTo(TransactionAddedResult.ADDED);
.createTransaction(genesisAccountKeyPair);
assertThat(transactionPool.addTransactionViaApi(tx).isValid()).isTrue();
requestedData.add(tx);
}
return requestedData;

@ -269,6 +269,6 @@ public class TestNode implements Closeable {
}
public int getPendingTransactionCount() {
return transactionPool.getPendingTransactions().size();
return transactionPool.count();
}
}

@ -51,7 +51,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import org.hyperledger.besu.testutil.TestClock;
@ -78,11 +77,8 @@ public class TransactionPoolFactoryTest {
@Mock EthContext ethContext;
@Mock EthMessages ethMessages;
@Mock EthScheduler ethScheduler;
@Mock PendingTransactions pendingTransactions;
@Mock PeerTransactionTracker peerTransactionTracker;
@Mock TransactionsMessageSender transactionsMessageSender;
@Mock NewPooledTransactionHashesMessageSender newPooledTransactionHashesMessageSender;
TransactionPool pool;
@ -99,13 +95,7 @@ public class TransactionPoolFactoryTest {
when(blockchain.getBlockHashByNumber(anyLong())).thenReturn(Optional.of(mock(Hash.class)));
when(context.getBlockchain()).thenReturn(blockchain);
final NodeMessagePermissioningProvider nmpp =
new NodeMessagePermissioningProvider() {
@Override
public boolean isMessagePermitted(final EnodeURL destinationEnode, final int code) {
return true;
}
};
final NodeMessagePermissioningProvider nmpp = (destinationEnode, code) -> true;
ethPeers =
new EthPeers(
"ETH",
@ -279,7 +269,8 @@ public class TransactionPoolFactoryTest {
final TransactionPool pool = createTransactionPool();
assertThat(pool.getPendingTransactions()).isInstanceOf(BaseFeePendingTransactionsSorter.class);
assertThat(pool.pendingTransactionsImplementation())
.isEqualTo(BaseFeePendingTransactionsSorter.class);
}
@Test
@ -289,7 +280,8 @@ public class TransactionPoolFactoryTest {
final TransactionPool pool = createTransactionPool();
assertThat(pool.getPendingTransactions()).isInstanceOf(GasPricePendingTransactionsSorter.class);
assertThat(pool.pendingTransactionsImplementation())
.isEqualTo(GasPricePendingTransactionsSorter.class);
}
private void setupScheduleWith(final StubGenesisConfigOptions config) {

@ -402,7 +402,7 @@ public class EthStatsService {
/** Sends the number of pending transactions in the pool */
private void sendPendingTransactionReport() {
final int pendingTransactionsNumber = transactionPool.getPendingTransactions().size();
final int pendingTransactionsNumber = transactionPool.count();
final PendingTransactionsReport pendingTransactionsReport =
ImmutablePendingTransactionsReport.builder()

@ -41,7 +41,6 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory;
@ -306,10 +305,6 @@ public class RetestethContext {
return transactionPool;
}
PendingTransactions getPendingTransactions() {
return transactionPool.getPendingTransactions();
}
public Address getCoinbase() {
return coinbase;
}

@ -80,7 +80,7 @@ public class RetestethService {
new EthGetBlockByHash(retestethContext::getBlockchainQueries, blockResult, true),
new EthGetCode(retestethContext::getBlockchainQueries),
new EthGetTransactionCount(
retestethContext::getBlockchainQueries, retestethContext::getPendingTransactions),
retestethContext::getBlockchainQueries, retestethContext::getTransactionPool),
new DebugStorageRangeAt(
retestethContext::getBlockchainQueries, retestethContext::getBlockReplay, true),
new TestModifyTimestamp(retestethContext),

@ -67,7 +67,7 @@ public class TestMineBlocks implements JsonRpcMethod {
context.getCoinbase(),
() -> Optional.of(blockchain.getChainHeadHeader().getGasLimit()),
header -> context.getExtraData(),
context.getTransactionPool().getPendingTransactions(),
context.getTransactionPool(),
protocolContext,
protocolSchedule,
context.getEthHashSolver(),

Loading…
Cancel
Save