@BeforeEach
  public void setupTest() {
    protocolContext.getBadBlockManager().reset();
    peersDoTimeout = new AtomicBoolean(false);
    peerCountToTimeout = new AtomicInteger(0);
    ethPeers =
        spy(
            new EthPeers(
                () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()),
                TestClock.fixed(),
                metricsSystem,
                EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE,
                Collections.emptyList(),
                Bytes.random(64),
                MAX_PEERS,
                MAX_PEERS,
                false,
                SyncMode.FAST,
                new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList())));

    final EthMessages ethMessages = new EthMessages();
    final EthScheduler ethScheduler =
        new DeterministicEthScheduler(
            () -> peerCountToTimeout.getAndDecrement() > 0 || peersDoTimeout.get());
    peerTaskExecutor = Mockito.mock(PeerTaskExecutor.class);
    ethContext = new EthContext(ethPeers, ethMessages, ethScheduler, peerTaskExecutor);
    final SyncState syncState = new SyncState(blockchain, ethContext.getEthPeers());
    transactionPool =
        TransactionPoolFactory.createTransactionPool(
            protocolSchedule,
            protocolContext,
            ethContext,
            TestClock.system(ZoneId.systemDefault()),
            metricsSystem,
            syncState,
            TransactionPoolConfiguration.DEFAULT,
            new BlobCache(),
            MiningConfiguration.newDefault(),
            false);
    transactionPool.setEnabled();

    ethProtocolManager =
        EthProtocolManagerTestBuilder.builder()
            .setProtocolSchedule(protocolSchedule)
            .setBlockchain(blockchain)
            .setEthScheduler(ethScheduler)
            .setTransactionPool(transactionPool)
            .setEthereumWireProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
            .setEthPeers(ethPeers)
            .setEthMessages(ethMessages)
            .setEthContext(ethContext)
            .build();
  }
@param <T> The type of data being requested from the network
@param <R> The type of data returned from the network
ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java