From bcfe6066447f006e6984c5960daef3847a7475c8 Mon Sep 17 00:00:00 2001 From: SlowBearDigger Date: Sun, 4 Jan 2026 17:06:54 -0500 Subject: [PATCH] Fix #1093: Resolve root connection issues with dynamic Tor RPC timeouts - Increase RPC timeout from 20s to 60s for Tor connections - Add dynamic error threshold (1 for Tor, 3 for clearnet) - Set connection timeout based on proxy usage in onConnectionChanged() Root cause: Monero daemon default timeout is 30 minutes, but Haveno was using 20s for all connections. Tor circuits often exceed 20s latency, causing premature timeouts and 'no connection to daemon' errors. Fix provides sufficient time for slow Tor circuits while maintaining responsiveness for clearnet connections. Tested on stagenet with remote node over Tor. Logs confirm stable connection where previous version failed with 'NoHttpResponseException' after ~1 minute. --- .../haveno/core/api/XmrConnectionService.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/haveno/core/api/XmrConnectionService.java b/core/src/main/java/haveno/core/api/XmrConnectionService.java index 30497020ea..00a4b8fbcf 100644 --- a/core/src/main/java/haveno/core/api/XmrConnectionService.java +++ b/core/src/main/java/haveno/core/api/XmrConnectionService.java @@ -78,6 +78,10 @@ public final class XmrConnectionService { private static final int MAX_CONSECUTIVE_ERRORS = 3; // max errors before switching connections private static int numConsecutiveErrors = 0; + private int getMaxConsecutiveErrors() { + return isProxyApplied(getConnection()) ? 1 : MAX_CONSECUTIVE_ERRORS; + } + public enum XmrConnectionFallbackType { LOCAL, CUSTOM, @@ -602,7 +606,8 @@ public final class XmrConnectionService { boolean isConnected = false; if (xmrLocalNode.isConnected()) { MoneroRpcConnection conn = connectionManager.getConnectionByUri(connection.getUri()); - conn.checkConnection(connectionManager.getTimeout()); + long timeout = isProxyApplied(conn) ? 60000 : connectionManager.getTimeout(); + conn.checkConnection(timeout); isConnected = Boolean.TRUE.equals(conn.isConnected()); } @@ -736,6 +741,13 @@ public final class XmrConnectionService { connectionList.removeConnection(currentConnection.getUri()); connectionList.addConnection(currentConnection); connectionList.setCurrentConnectionUri(currentConnection.getUri()); + + // set timeout based on connection type + long timeout = isProxyApplied(currentConnection) ? 60000 : REFRESH_PERIOD_HTTP_MS; + connectionManager.setTimeout(timeout); + if (currentConnection instanceof MoneroRpcConnection) { + currentConnection.setTimeout(timeout); + } } // set connection property on user thread @@ -819,7 +831,7 @@ public final class XmrConnectionService { // skip error handling up to max attempts numConsecutiveErrors++; - if (numConsecutiveErrors <= MAX_CONSECUTIVE_ERRORS) { + if (numConsecutiveErrors <= getMaxConsecutiveErrors()) { return; } else { numConsecutiveErrors = 0; // reset error count