mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-09 22:07:59 -05:00
Do not leak references to PendingTransactions (#5693)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
This commit is contained in:
@@ -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);
|
||||
ensureTransactionIsInvalid(
|
||||
invalidTransaction, TransactionInvalidReason.EXCEEDS_BLOCK_GAS_LIMIT);
|
||||
final Transaction validTransaction = createTransaction(0, Wei.of(10), 21_000);
|
||||
|
||||
pendingTransactions.addRemoteTransaction(validTransaction, Optional.empty());
|
||||
pendingTransactions.addRemoteTransaction(invalidTransaction, Optional.empty());
|
||||
ensureTransactionIsValid(validTransaction, 21_000, 0);
|
||||
final Transaction invalidTransaction = createTransaction(3, Wei.of(10), 21_000);
|
||||
ensureTransactionIsInvalid(
|
||||
invalidTransaction, TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE);
|
||||
|
||||
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 ProcessableBlockHeader blockHeader = createBlock(300_000);
|
||||
|
||||
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
|
||||
final Transaction selected =
|
||||
txTestFixture
|
||||
.nonce(1)
|
||||
.gasLimit(1)
|
||||
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||||
ensureTransactionIsValid(selected, 2000, 10000);
|
||||
final Transaction selected = createTransaction(0, Wei.of(10), 21_000);
|
||||
ensureTransactionIsValid(selected, 21_000, 0);
|
||||
|
||||
final Transaction notSelectedTransient =
|
||||
txTestFixture
|
||||
.nonce(1)
|
||||
.gasLimit(1)
|
||||
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||||
ensureTransactionIsValid(notSelectedTransient, 2000, 10000);
|
||||
final Transaction notSelectedTransient = createTransaction(1, Wei.of(10), 21_000);
|
||||
ensureTransactionIsValid(notSelectedTransient, 21_000, 0);
|
||||
|
||||
final Transaction notSelectedInvalid =
|
||||
txTestFixture
|
||||
.nonce(1)
|
||||
.gasLimit(1)
|
||||
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||||
ensureTransactionIsValid(notSelectedInvalid, 2000, 10000);
|
||||
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(
|
||||
protected GenesisConfigFile getGenesisConfigFile() {
|
||||
return GenesisConfigFile.genesisFileFromResources(
|
||||
"/block-transaction-selector/london-genesis.json");
|
||||
}
|
||||
|
||||
@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,
|
||||
LondonFeeMarketBlockTransactionSelectorTest::mockBlockHeader);
|
||||
}
|
||||
.build();
|
||||
final PendingTransactions pendingTransactions =
|
||||
new BaseFeePendingTransactionsSorter(
|
||||
poolConf,
|
||||
TestClock.system(ZoneId.systemDefault()),
|
||||
metricsSystem,
|
||||
blockchain::getChainHeadHeader);
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FeeMarket getFeeMarket() {
|
||||
return FeeMarket.london(0L);
|
||||
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 ProcessableBlockHeader blockHeader = createBlock(5_000_000);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
pendingTransactions.addRemoteTransaction(txFrontier1, Optional.empty());
|
||||
pendingTransactions.addRemoteTransaction(txLondon1, Optional.empty());
|
||||
pendingTransactions.addRemoteTransaction(txFrontier2, Optional.empty());
|
||||
pendingTransactions.addRemoteTransaction(txLondon2, Optional.empty());
|
||||
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(),
|
||||
|
||||
Reference in New Issue
Block a user