public void onDataRequest(Message message, final Connection connection) {
    Log.traceCall(message.toString() + " / connection=" + connection);

    checkArgument(timeoutTimer == null, "requestData must not be called twice.");
    timeoutTimer =
        UserThread.runAfter(
            () -> {
              log.info("timeoutTimer called");
              peerManager.shutDownConnection(connection);
              shutDown();
              listener.onFault("A timeout occurred");
            },
            10,
            TimeUnit.SECONDS);

    DataRequest dataRequest = (DataRequest) message;
    DataResponse dataResponse =
        new DataResponse(new HashSet<>(dataStorage.getMap().values()), dataRequest.getNonce());
    SettableFuture<Connection> future = networkNode.sendMessage(connection, dataResponse);
    Futures.addCallback(
        future,
        new FutureCallback<Connection>() {
          @Override
          public void onSuccess(Connection connection) {
            log.trace(
                "Send DataResponse to {} succeeded. dataResponse={}",
                connection.getPeersNodeAddressOptional(),
                dataResponse);
            shutDown();
            listener.onComplete();
          }

          @Override
          public void onFailure(@NotNull Throwable throwable) {
            String errorMessage =
                "Sending dataRequest to "
                    + connection
                    + " failed. That is expected if the peer is offline. dataRequest="
                    + dataRequest
                    + "."
                    + "Exception: "
                    + throwable.getMessage();
            log.info(errorMessage);

            peerManager.shutDownConnection(connection);
            shutDown();
            listener.onFault(errorMessage);
          }
        });
  }
  public void requestData(NodeAddress nodeAddress) {
    Log.traceCall("nodeAddress=" + nodeAddress);
    checkArgument(timeoutTimer == null, "requestData must not be called twice.");

    timeoutTimer =
        UserThread.runAfter(
            () -> {
              log.info("timeoutTimer called");
              peerManager.shutDownConnection(nodeAddress);
              shutDown();
              listener.onFault("A timeout occurred");
            },
            10,
            TimeUnit.SECONDS);

    Message dataRequest;
    if (networkNode.getNodeAddress() == null) dataRequest = new PreliminaryDataRequest(nonce);
    else dataRequest = new UpdateDataRequest(networkNode.getNodeAddress(), nonce);

    log.info("We send a {} to peer {}. ", dataRequest.getClass().getSimpleName(), nodeAddress);

    SettableFuture<Connection> future = networkNode.sendMessage(nodeAddress, dataRequest);
    Futures.addCallback(
        future,
        new FutureCallback<Connection>() {
          @Override
          public void onSuccess(@Nullable Connection connection) {
            log.trace("Send " + dataRequest + " to " + nodeAddress + " succeeded.");
          }

          @Override
          public void onFailure(@NotNull Throwable throwable) {
            String errorMessage =
                "Sending dataRequest to "
                    + nodeAddress
                    + " failed. That is expected if the peer is offline. dataRequest="
                    + dataRequest
                    + "."
                    + "Exception: "
                    + throwable.getMessage();
            log.info(errorMessage);

            peerManager.shutDownConnection(nodeAddress);
            shutDown();
            listener.onFault(errorMessage);
          }
        });
  }