1616
1717import static org .assertj .core .api .Assertions .assertThat ;
1818import static org .hyperledger .besu .ethereum .eth .transactions .TransactionPoolConfiguration .Implementation .LAYERED ;
19+ import static org .hyperledger .besu .ethereum .eth .transactions .TransactionPoolConfiguration .Implementation .LEGACY ;
1920import static org .hyperledger .besu .ethereum .mainnet .MainnetProtocolSchedule .DEFAULT_CHAIN_ID ;
2021import static org .mockito .ArgumentMatchers .anyInt ;
2122import static org .mockito .ArgumentMatchers .anyLong ;
2728import static org .mockito .Mockito .when ;
2829
2930import org .hyperledger .besu .config .StubGenesisConfigOptions ;
31+ import org .hyperledger .besu .datatypes .Address ;
3032import org .hyperledger .besu .datatypes .Hash ;
3133import org .hyperledger .besu .ethereum .ProtocolContext ;
3234import 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