### Question:
PeerDiscoveryController { public void start() { if (!started.compareAndSet(false, true)) { throw new IllegalStateException("The peer table had already been started"); } final List<DiscoveryPeer> initialDiscoveryPeers = bootstrapNodes.stream() .filter(peerPermissions::isAllowedInPeerTable) .collect(Collectors.toList()); initialDiscoveryPeers.forEach(peerTable::tryAdd); recursivePeerRefreshState = new RecursivePeerRefreshState( this::bond, this::findNodes, timerUtil, localPeer, peerTable, peerPermissions, PEER_REFRESH_ROUND_TIMEOUT_IN_SECONDS, 100); peerPermissions.subscribeUpdate(this::handlePermissionsUpdate); recursivePeerRefreshState.start(initialDiscoveryPeers, localPeer.getId()); final long refreshTimerId = timerUtil.setPeriodic( Math.min(REFRESH_CHECK_INTERVAL_MILLIS, tableRefreshIntervalMs), this::refreshTableIfRequired); tableRefreshTimerId = OptionalLong.of(refreshTimerId); cleanTableTimerId = OptionalLong.of( timerUtil.setPeriodic(cleanPeerTableIntervalMs, this::cleanPeerTableIfRequired)); } private  PeerDiscoveryController(
      final NodeKey nodeKey,
      final DiscoveryPeer localPeer,
      final PeerTable peerTable,
      final Collection<DiscoveryPeer> bootstrapNodes,
      final OutboundMessageHandler outboundMessageHandler,
      final TimerUtil timerUtil,
      final AsyncExecutor workerExecutor,
      final long tableRefreshIntervalMs,
      final long cleanPeerTableIntervalMs,
      final PeerRequirement peerRequirement,
      final PeerPermissions peerPermissions,
      final Subscribers<PeerBondedObserver> peerBondedObservers,
      final MetricsSystem metricsSystem); static Builder builder(); void start(); CompletableFuture<?> stop(); void dropPeer(final PeerId peer); void onMessage(final Packet packet, final DiscoveryPeer sender); Stream<DiscoveryPeer> streamDiscoveredPeers(); void setRetryDelayFunction(final RetryDelayFunction retryDelayFunction); void handleBondingRequest(final DiscoveryPeer peer);  }### Answer:
@Test public void shouldStopRetryingInteractionWhenLimitIsReached() { final List<NodeKey> nodeKeys = PeerDiscoveryTestHelper.generateNodeKeys(3); final List<DiscoveryPeer> peers = helper.createDiscoveryPeers(nodeKeys); final MockTimerUtil timer = new MockTimerUtil(); final OutboundMessageHandler outboundMessageHandler = mock(OutboundMessageHandler.class); controller = getControllerBuilder() .peers(peers) .timerUtil(timer) .outboundMessageHandler(outboundMessageHandler) .build(); final PingPacketData mockPing = PingPacketData.create(localPeer.getEndpoint(), peers.get(0).getEndpoint()); final Packet mockPacket = Packet.create(PacketType.PING, mockPing, nodeKeys.get(0)); mockPingPacketCreation(mockPacket); controller.start(); for (int i = 0; i < 10; i++) { timer.runTimerHandlers(); } for (final DiscoveryPeer peer : peers) { verify(outboundMessageHandler, times(6)).send(eq(peer), matchPacketOfType(PacketType.PING)); } }
@Test(expected = IllegalStateException.class) public void startTwice() { startPeerDiscoveryController(); controller.start(); }