Skip to content

Commit 184a5e3

Browse files
fab-10macfarla
authored andcommitted
Correctly initialize the txpool as disabled on creation (besu-eth#6890)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com> Signed-off-by: amsmota <antonio.mota@citi.com>
1 parent 5e831b8 commit 184a5e3

File tree

3 files changed

+60
-48
lines changed

3 files changed

+60
-48
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
- Fix Shanghai/QBFT block import bug when syncing new nodes [#6765](https://github.com/hyperledger/besu/pull/6765)
4646
- Fix to avoid broadcasting full blob txs, instead of only the tx announcement, to a subset of nodes [#6835](https://github.com/hyperledger/besu/pull/6835)
4747
- Snap client fixes discovered during snap server testing [#6847](https://github.com/hyperledger/besu/pull/6847)
48+
- Correctly initialize the txpool as disabled on creation [#6890](https://github.com/hyperledger/besu/pull/6890)
4849

4950
### Download Links
5051

ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public class TransactionPool implements BlockAddedObserver {
8989
private static final Logger LOG = LoggerFactory.getLogger(TransactionPool.class);
9090
private static final Logger LOG_FOR_REPLAY = LoggerFactory.getLogger("LOG_FOR_REPLAY");
9191
private final Supplier<PendingTransactions> pendingTransactionsSupplier;
92-
private volatile PendingTransactions pendingTransactions;
92+
private volatile PendingTransactions pendingTransactions = new DisabledPendingTransactions();
9393
private final ProtocolSchedule protocolSchedule;
9494
private final ProtocolContext protocolContext;
9595
private final EthContext ethContext;

ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static org.assertj.core.api.Assertions.assertThat;
1818
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.LAYERED;
19+
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.LEGACY;
1920
import static org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule.DEFAULT_CHAIN_ID;
2021
import static org.mockito.ArgumentMatchers.anyInt;
2122
import static org.mockito.ArgumentMatchers.anyLong;
@@ -27,6 +28,7 @@
2728
import static org.mockito.Mockito.when;
2829

2930
import org.hyperledger.besu.config.StubGenesisConfigOptions;
31+
import org.hyperledger.besu.datatypes.Address;
3032
import org.hyperledger.besu.datatypes.Hash;
3133
import org.hyperledger.besu.ethereum.ProtocolContext;
3234
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
@@ -262,33 +264,38 @@ public void incomingTransactionMessageHandlersRegisteredIfNoInitialSync() {
262264
"transaction messages handler should be enabled"));
263265
}
264266

267+
@Test
268+
public void txPoolStartsDisabledWhenInitialSyncPhaseIsRequired() {
269+
// when using any of the initial syncs (SNAP, FAST, ...), txpool starts disabled
270+
// and is enabled only after it is in sync
271+
setupInitialSyncPhase(true);
272+
assertThat(pool.isEnabled()).isFalse();
273+
}
274+
275+
@Test
276+
public void callingGetNextNonceForSenderOnDisabledTxPoolWorks() {
277+
setupInitialSyncPhase(true);
278+
279+
assertThat(pool.getNextNonceForSender(Address.fromHexString("0x123abc"))).isEmpty();
280+
}
281+
282+
@Test
283+
public void txPoolStartsEnabledWhenFullSyncConfigured() {
284+
// when using FULL sync, txpool starts enabled, because it could be
285+
// that it is the first node on a new network and so, it is in sync with genesis
286+
// and must accept txs. Otherwise, asap it find a sync target that is ahead, the txpool
287+
// will be disabled, until in sync.
288+
setupInitialSyncPhase(false);
289+
assertThat(pool.isEnabled()).isTrue();
290+
}
291+
265292
private void setupInitialSyncPhase(final boolean hasInitialSyncPhase) {
266293
syncState = new SyncState(blockchain, ethPeers, hasInitialSyncPhase, Optional.empty());
267294
setupInitialSyncPhase(syncState);
268295
}
269296

270297
private void setupInitialSyncPhase(final SyncState syncState) {
271-
pool =
272-
TransactionPoolFactory.createTransactionPool(
273-
schedule,
274-
context,
275-
ethContext,
276-
TestClock.fixed(),
277-
new TransactionPoolMetrics(new NoOpMetricsSystem()),
278-
syncState,
279-
ImmutableTransactionPoolConfiguration.builder()
280-
.txPoolMaxSize(1)
281-
.pendingTxRetentionPeriod(1)
282-
.unstable(
283-
ImmutableTransactionPoolConfiguration.Unstable.builder()
284-
.txMessageKeepAliveSeconds(1)
285-
.build())
286-
.build(),
287-
peerTransactionTracker,
288-
transactionsMessageSender,
289-
newPooledTransactionHashesMessageSender,
290-
new BlobCache(),
291-
MiningParameters.newDefault());
298+
pool = createTransactionPool(LAYERED, syncState);
292299

293300
ethProtocolManager =
294301
new EthProtocolManager(
@@ -312,8 +319,7 @@ private void setupInitialSyncPhase(final SyncState syncState) {
312319
createLegacyTransactionPool_shouldUseBaseFeePendingTransactionsSorter_whenLondonEnabled() {
313320
setupScheduleWith(new StubGenesisConfigOptions().londonBlock(0));
314321

315-
final TransactionPool pool =
316-
createTransactionPool(TransactionPoolConfiguration.Implementation.LEGACY);
322+
final TransactionPool pool = createAndEnableTransactionPool(LEGACY, syncState);
317323

318324
assertThat(pool.pendingTransactionsImplementation())
319325
.isEqualTo(BaseFeePendingTransactionsSorter.class);
@@ -324,8 +330,7 @@ private void setupInitialSyncPhase(final SyncState syncState) {
324330
createLegacyTransactionPool_shouldUseGasPricePendingTransactionsSorter_whenLondonNotEnabled() {
325331
setupScheduleWith(new StubGenesisConfigOptions().berlinBlock(0));
326332

327-
final TransactionPool pool =
328-
createTransactionPool(TransactionPoolConfiguration.Implementation.LEGACY);
333+
final TransactionPool pool = createAndEnableTransactionPool(LEGACY, syncState);
329334

330335
assertThat(pool.pendingTransactionsImplementation())
331336
.isEqualTo(GasPricePendingTransactionsSorter.class);
@@ -336,7 +341,7 @@ private void setupInitialSyncPhase(final SyncState syncState) {
336341
createLayeredTransactionPool_shouldUseBaseFeePendingTransactionsSorter_whenLondonEnabled() {
337342
setupScheduleWith(new StubGenesisConfigOptions().londonBlock(0));
338343

339-
final TransactionPool pool = createTransactionPool(LAYERED);
344+
final TransactionPool pool = createAndEnableTransactionPool(LAYERED, syncState);
340345

341346
assertThat(pool.pendingTransactionsImplementation())
342347
.isEqualTo(LayeredPendingTransactions.class);
@@ -349,7 +354,7 @@ private void setupInitialSyncPhase(final SyncState syncState) {
349354
createLayeredTransactionPool_shouldUseGasPricePendingTransactionsSorter_whenLondonNotEnabled() {
350355
setupScheduleWith(new StubGenesisConfigOptions().berlinBlock(0));
351356

352-
final TransactionPool pool = createTransactionPool(LAYERED);
357+
final TransactionPool pool = createAndEnableTransactionPool(LAYERED, syncState);
353358

354359
assertThat(pool.pendingTransactionsImplementation())
355360
.isEqualTo(LayeredPendingTransactions.class);
@@ -378,27 +383,33 @@ private void setupScheduleWith(final StubGenesisConfigOptions config) {
378383
}
379384

380385
private TransactionPool createTransactionPool(
381-
final TransactionPoolConfiguration.Implementation implementation) {
382-
final TransactionPool txPool =
383-
TransactionPoolFactory.createTransactionPool(
384-
schedule,
385-
protocolContext,
386-
ethContext,
387-
TestClock.fixed(),
388-
new NoOpMetricsSystem(),
389-
syncState,
390-
ImmutableTransactionPoolConfiguration.builder()
391-
.txPoolImplementation(implementation)
392-
.txPoolMaxSize(1)
393-
.pendingTxRetentionPeriod(1)
394-
.unstable(
395-
ImmutableTransactionPoolConfiguration.Unstable.builder()
396-
.txMessageKeepAliveSeconds(1)
397-
.build())
398-
.build(),
399-
new BlobCache(),
400-
MiningParameters.newDefault());
386+
final TransactionPoolConfiguration.Implementation implementation, final SyncState syncState) {
387+
return TransactionPoolFactory.createTransactionPool(
388+
schedule,
389+
context,
390+
ethContext,
391+
TestClock.fixed(),
392+
new TransactionPoolMetrics(new NoOpMetricsSystem()),
393+
syncState,
394+
ImmutableTransactionPoolConfiguration.builder()
395+
.txPoolImplementation(implementation)
396+
.txPoolMaxSize(1)
397+
.pendingTxRetentionPeriod(1)
398+
.unstable(
399+
ImmutableTransactionPoolConfiguration.Unstable.builder()
400+
.txMessageKeepAliveSeconds(1)
401+
.build())
402+
.build(),
403+
peerTransactionTracker,
404+
transactionsMessageSender,
405+
newPooledTransactionHashesMessageSender,
406+
new BlobCache(),
407+
MiningParameters.newDefault());
408+
}
401409

410+
private TransactionPool createAndEnableTransactionPool(
411+
final TransactionPoolConfiguration.Implementation implementation, final SyncState syncState) {
412+
final TransactionPool txPool = createTransactionPool(implementation, syncState);
402413
txPool.setEnabled();
403414
return txPool;
404415
}

0 commit comments

Comments
 (0)