<p><b>@sqrrm</b> requested changes on this pull request.</p>

<p>Tested it and it works as expected, nice.</p>
<p>The errors logged by NioClientManager would be good to get rid of since most users won't be running with a local node so they would have big errors on startup. Not that familiar with logging, but if you have a way to do it I would say it's good.</p>
<p>I think the unchecked usages of <code>Optional</code> should be checked, perhaps use <code>orElse()</code>, didn't comment on all uses as there are quite a few.</p>
<p>NIT: Prefer no empty line between comment and method.</p><hr>

<p>In <a href="https://github.com/bisq-network/bisq/pull/3982#discussion_r380818535">core/src/main/java/bisq/core/app/BisqSetup.java</a>:</p>
<pre style='color:#555'>>              nextStep.run();
             return;
         }
 
-        localBitcoinNode.detectAndRun(nextStep);
+        // Results of the check don't have to be passed to nextStep,
+        // because they're cached in LocalBitcoinNode and dependent routines query it themselves.
+        localBitcoinNode.checkUsable();
+
+        // Here we only want to provide the user with a choice (in a popup) in case a local node is
+        // detected, but badly configured.
+        var detectedButMisconfigured = localBitcoinNode.isDetectedButMisconfigured().get();
</pre>
<p>Since <code>localBitcoinNode.isDetectedButMisconfigured()</code> is an optional it would be prudent to check that it's present here. Although it might be certain for now that it's never null the characteristics of an optional is that it should be able to handle the null state.</p>

<hr>

<p>In <a href="https://github.com/bisq-network/bisq/pull/3982#discussion_r380821333">core/src/main/java/bisq/core/app/BisqSetup.java</a>:</p>
<pre style='color:#555'>> @@ -862,7 +879,7 @@ private void maybeShowSecurityRecommendation() {
     }
 
     private void maybeShowLocalhostRunningInfo() {
-        maybeTriggerDisplayHandler("bitcoinLocalhostNode", displayLocalhostHandler, localBitcoinNode.isDetected());
+        maybeTriggerDisplayHandler("bitcoinLocalhostNode", displayLocalhostHandler, localBitcoinNode.isUsable().get());
</pre>
<p>Same here with the usage of <code>Optional</code> without checking <code>isPresent()</code>.</p>

<hr>

<p>In <a href="https://github.com/bisq-network/bisq/pull/3982#discussion_r380832636">core/src/main/java/bisq/core/btc/nodes/LocalBitcoinNode.java</a>:</p>
<pre style='color:#555'>>       */
-    public void detectAndRun(Runnable callback) {
-        try (Socket socket = new Socket()) {
-            socket.connect(new InetSocketAddress("127.0.0.1", port), CONNECTION_TIMEOUT);
+
+    private static Peer createLocalPeer(
+            int port
+    ) throws UnknownHostException {
+        // TODO: what's the effect of NetworkParameters on handshake?
+        // i.e. is it fine to just always use MainNetParams?
+        var networkParameters = new MainNetParams();
+
</pre>
<p>So much space in this method...</p>

<hr>

<p>In <a href="https://github.com/bisq-network/bisq/pull/3982#discussion_r380854122">core/src/main/java/bisq/core/btc/nodes/LocalBitcoinNode.java</a>:</p>
<pre style='color:#555'>> +        if (clientVersion >= whenBloomFiltersWereIntroduced
+                && clientVersion < whenBloomFiltersWereDisabledByDefault)
+            return true;
+        return (localServices & NODE_BLOOM) == NODE_BLOOM;
+    }
+
+    /**
+     * Initiates detection and configuration checks. The results are cached so that the public
+     * methods isUsable, isDetected, isWellConfigured don't trigger a recheck.
+     */
+
+    public boolean checkUsable() {
+        var optionalVersionMessage = attemptHandshakeForVersionMessage();
+        handleHandshakeAttempt(optionalVersionMessage);
+        // We know that the Optional/s will be populated by the end of the checks.
+        return isUsable().get();
</pre>
<p>Same with the checks for <code>Optional.isPresent()</code>.</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/bisq-network/bisq/pull/3982?email_source=notifications&email_token=AJFFTNXMEA7U56TJ65CRGOLRDQW75A5CNFSM4KWZVT6KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCV6S73A#pullrequestreview-360525804">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AJFFTNSBBATXHDDHL3L6C6DRDQW75ANCNFSM4KWZVT6A">unsubscribe</a>.<img src="https://github.com/notifications/beacon/AJFFTNVMLV4WY6FG3H7JEODRDQW75A5CNFSM4KWZVT6KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCV6S73A.gif" height="1" width="1" alt="" /></p>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/bisq-network/bisq/pull/3982?email_source=notifications\u0026email_token=AJFFTNXMEA7U56TJ65CRGOLRDQW75A5CNFSM4KWZVT6KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCV6S73A#pullrequestreview-360525804",
"url": "https://github.com/bisq-network/bisq/pull/3982?email_source=notifications\u0026email_token=AJFFTNXMEA7U56TJ65CRGOLRDQW75A5CNFSM4KWZVT6KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCV6S73A#pullrequestreview-360525804",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>