mirror of
https://github.com/boldsuck/haveno.git
synced 2024-12-22 20:19:21 +00:00
poll local node for faster switching
This commit is contained in:
parent
3d0b8c0b09
commit
27bf72d432
3 changed files with 43 additions and 23 deletions
|
@ -44,16 +44,13 @@ import java.util.stream.Collectors;
|
||||||
public final class CoreMoneroConnectionsService {
|
public final class CoreMoneroConnectionsService {
|
||||||
|
|
||||||
private static final int MIN_BROADCAST_CONNECTIONS = 0; // TODO: 0 for stagenet, 5+ for mainnet
|
private static final int MIN_BROADCAST_CONNECTIONS = 0; // TODO: 0 for stagenet, 5+ for mainnet
|
||||||
private static final long REFRESH_PERIOD_LOCAL_MS = 5000; // refresh period when connected to local node
|
|
||||||
private static final long REFRESH_PERIOD_HTTP_MS = 20000; // refresh period when connected to remote node over http
|
private static final long REFRESH_PERIOD_HTTP_MS = 20000; // refresh period when connected to remote node over http
|
||||||
private static final long REFRESH_PERIOD_ONION_MS = 30000; // refresh period when connected to remote node over tor
|
private static final long REFRESH_PERIOD_ONION_MS = 30000; // refresh period when connected to remote node over tor
|
||||||
private static final long MIN_ERROR_LOG_PERIOD_MS = 300000; // minimum period between logging errors fetching daemon info
|
private static final long MIN_ERROR_LOG_PERIOD_MS = 300000; // minimum period between logging errors fetching daemon info
|
||||||
private static Long lastErrorTimestamp;
|
private static Long lastErrorTimestamp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
private final Object listenersLock = new Object();
|
private final Object listenerLock = new Object();
|
||||||
private final Config config;
|
private final Config config;
|
||||||
private final CoreContext coreContext;
|
private final CoreContext coreContext;
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
|
@ -120,7 +117,7 @@ public final class CoreMoneroConnectionsService {
|
||||||
public void onShutDownStarted() {
|
public void onShutDownStarted() {
|
||||||
log.info("{}.onShutDownStarted()", getClass().getSimpleName());
|
log.info("{}.onShutDownStarted()", getClass().getSimpleName());
|
||||||
isShutDownStarted = true;
|
isShutDownStarted = true;
|
||||||
synchronized (this) {
|
synchronized (lock) {
|
||||||
// ensures request not in progress
|
// ensures request not in progress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +144,7 @@ public final class CoreMoneroConnectionsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConnectionListener(MoneroConnectionManagerListener listener) {
|
public void addConnectionListener(MoneroConnectionManagerListener listener) {
|
||||||
synchronized (listenersLock) {
|
synchronized (listenerLock) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,10 +316,10 @@ public final class CoreMoneroConnectionsService {
|
||||||
|
|
||||||
private long getDefaultRefreshPeriodMs() {
|
private long getDefaultRefreshPeriodMs() {
|
||||||
MoneroRpcConnection connection = getConnection();
|
MoneroRpcConnection connection = getConnection();
|
||||||
if (connection == null) return REFRESH_PERIOD_LOCAL_MS;
|
if (connection == null) return LocalMoneroNode.REFRESH_PERIOD_LOCAL_MS;
|
||||||
if (isConnectionLocal(connection)) {
|
if (isConnectionLocal(connection)) {
|
||||||
if (lastInfo != null && (lastInfo.isBusySyncing() || (lastInfo.getHeightWithoutBootstrap() != null && lastInfo.getHeightWithoutBootstrap() > 0 && lastInfo.getHeightWithoutBootstrap() < lastInfo.getHeight()))) return REFRESH_PERIOD_HTTP_MS; // refresh slower if syncing or bootstrapped
|
if (lastInfo != null && (lastInfo.isBusySyncing() || (lastInfo.getHeightWithoutBootstrap() != null && lastInfo.getHeightWithoutBootstrap() > 0 && lastInfo.getHeightWithoutBootstrap() < lastInfo.getHeight()))) return REFRESH_PERIOD_HTTP_MS; // refresh slower if syncing or bootstrapped
|
||||||
else return REFRESH_PERIOD_LOCAL_MS; // TODO: announce faster refresh after done syncing
|
else return LocalMoneroNode.REFRESH_PERIOD_LOCAL_MS; // TODO: announce faster refresh after done syncing
|
||||||
} else if (useProxy(connection)) {
|
} else if (useProxy(connection)) {
|
||||||
return REFRESH_PERIOD_ONION_MS;
|
return REFRESH_PERIOD_ONION_MS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -375,16 +372,23 @@ public final class CoreMoneroConnectionsService {
|
||||||
nodeService.addListener(new LocalMoneroNodeListener() {
|
nodeService.addListener(new LocalMoneroNodeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onNodeStarted(MoneroDaemonRpc daemon) {
|
public void onNodeStarted(MoneroDaemonRpc daemon) {
|
||||||
log.info(getClass() + ".onNodeStarted() called");
|
log.info("Local monero node started");
|
||||||
daemon.getRpcConnection().checkConnection(connectionManager.getTimeout());
|
|
||||||
setConnection(daemon.getRpcConnection());
|
|
||||||
checkConnection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNodeStopped() {
|
public void onNodeStopped() {
|
||||||
log.info(getClass() + ".onNodeStopped() called");
|
log.info("Local monero node stopped");
|
||||||
checkConnection();
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionChanged(MoneroRpcConnection connection) {
|
||||||
|
log.info("Local monerod connection changed: " + connection);
|
||||||
|
if (isShutDownStarted || !connectionManager.getAutoSwitch() || !accountService.isAccountOpen()) return;
|
||||||
|
if (nodeService.isConnected()) {
|
||||||
|
setConnection(connection.getUri()); // switch to local node if connected
|
||||||
|
} else if (getConnection() != null && getConnection().getUri().equals(connection.getUri())) {
|
||||||
|
setConnection(getBestAvailableConnection()); // switch to best available if disconnected from local node
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -514,7 +518,7 @@ public final class CoreMoneroConnectionsService {
|
||||||
updatePolling();
|
updatePolling();
|
||||||
|
|
||||||
// notify listeners in parallel
|
// notify listeners in parallel
|
||||||
synchronized (listenersLock) {
|
synchronized (listenerLock) {
|
||||||
for (MoneroConnectionManagerListener listener : listeners) {
|
for (MoneroConnectionManagerListener listener : listeners) {
|
||||||
new Thread(() -> listener.onConnectionChanged(currentConnection)).start();
|
new Thread(() -> listener.onConnectionChanged(currentConnection)).start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import haveno.core.trade.HavenoUtils;
|
||||||
import haveno.core.user.Preferences;
|
import haveno.core.user.Preferences;
|
||||||
import haveno.core.xmr.MoneroNodeSettings;
|
import haveno.core.xmr.MoneroNodeSettings;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import monero.common.MoneroConnectionManager;
|
||||||
import monero.common.MoneroUtils;
|
import monero.common.MoneroUtils;
|
||||||
import monero.daemon.MoneroDaemonRpc;
|
import monero.daemon.MoneroDaemonRpc;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -39,11 +40,16 @@ import java.util.List;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class LocalMoneroNode {
|
public class LocalMoneroNode {
|
||||||
|
|
||||||
|
// constants
|
||||||
|
public static final long REFRESH_PERIOD_LOCAL_MS = 5000; // refresh period for local node
|
||||||
public static final String MONEROD_DIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath();
|
public static final String MONEROD_DIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath();
|
||||||
public static final String MONEROD_NAME = Utilities.isWindows() ? "monerod.exe" : "monerod";
|
public static final String MONEROD_NAME = Utilities.isWindows() ? "monerod.exe" : "monerod";
|
||||||
public static final String MONEROD_PATH = MONEROD_DIR + File.separator + MONEROD_NAME;
|
public static final String MONEROD_PATH = MONEROD_DIR + File.separator + MONEROD_NAME;
|
||||||
private static final String MONEROD_DATADIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? MONEROD_DIR + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1" : null; // use default directory unless local
|
private static final String MONEROD_DATADIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? MONEROD_DIR + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1" : null; // use default directory unless local
|
||||||
|
|
||||||
|
// instance fields
|
||||||
|
private MoneroDaemonRpc daemon;
|
||||||
|
private MoneroConnectionManager connectionManager;
|
||||||
private final Config config;
|
private final Config config;
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
private final List<LocalMoneroNodeListener> listeners = new ArrayList<>();
|
private final List<LocalMoneroNodeListener> listeners = new ArrayList<>();
|
||||||
|
@ -57,8 +63,7 @@ public class LocalMoneroNode {
|
||||||
if (!Config.baseCurrencyNetwork().isMainnet()) MONEROD_ARGS.add("--" + Config.baseCurrencyNetwork().getNetwork().toLowerCase());
|
if (!Config.baseCurrencyNetwork().isMainnet()) MONEROD_ARGS.add("--" + Config.baseCurrencyNetwork().getNetwork().toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
// client to the local Monero node
|
// default rpc ports
|
||||||
private MoneroDaemonRpc daemon;
|
|
||||||
private static Integer rpcPort;
|
private static Integer rpcPort;
|
||||||
static {
|
static {
|
||||||
if (Config.baseCurrencyNetwork().isMainnet()) rpcPort = 18081;
|
if (Config.baseCurrencyNetwork().isMainnet()) rpcPort = 18081;
|
||||||
|
@ -72,6 +77,15 @@ public class LocalMoneroNode {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.daemon = new MoneroDaemonRpc("http://" + HavenoUtils.LOOPBACK_HOST + ":" + rpcPort);
|
this.daemon = new MoneroDaemonRpc("http://" + HavenoUtils.LOOPBACK_HOST + ":" + rpcPort);
|
||||||
|
|
||||||
|
// initialize connection manager to listen to local connection
|
||||||
|
this.connectionManager = new MoneroConnectionManager().setConnection(daemon.getRpcConnection());
|
||||||
|
this.connectionManager.setTimeout(REFRESH_PERIOD_LOCAL_MS);
|
||||||
|
this.connectionManager.checkConnection();
|
||||||
|
this.connectionManager.addListener((connection) -> {
|
||||||
|
for (var listener : listeners) listener.onConnectionChanged(connection); // notify of connection changes
|
||||||
|
});
|
||||||
|
this.connectionManager.startPolling(REFRESH_PERIOD_LOCAL_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,10 +120,6 @@ public class LocalMoneroNode {
|
||||||
return daemon;
|
return daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkConnection() {
|
|
||||||
return daemon.getRpcConnection().checkConnection(5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equalsUri(String uri) {
|
public boolean equalsUri(String uri) {
|
||||||
return HavenoUtils.isLocalHost(uri) && MoneroUtils.parseUri(uri).getPort() == rpcPort;
|
return HavenoUtils.isLocalHost(uri) && MoneroUtils.parseUri(uri).getPort() == rpcPort;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +129,7 @@ public class LocalMoneroNode {
|
||||||
*/
|
*/
|
||||||
public boolean isDetected() {
|
public boolean isDetected() {
|
||||||
checkConnection();
|
checkConnection();
|
||||||
return daemon.getRpcConnection().isOnline();
|
return Boolean.TRUE.equals(connectionManager.getConnection().isOnline());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,7 +137,11 @@ public class LocalMoneroNode {
|
||||||
*/
|
*/
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
checkConnection();
|
checkConnection();
|
||||||
return daemon.getRpcConnection().isConnected();
|
return Boolean.TRUE.equals(connectionManager.isConnected());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConnection() {
|
||||||
|
connectionManager.checkConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoneroNodeSettings getMoneroNodeSettings() {
|
public MoneroNodeSettings getMoneroNodeSettings() {
|
||||||
|
|
|
@ -16,9 +16,11 @@
|
||||||
*/
|
*/
|
||||||
package haveno.core.api;
|
package haveno.core.api;
|
||||||
|
|
||||||
|
import monero.common.MoneroRpcConnection;
|
||||||
import monero.daemon.MoneroDaemonRpc;
|
import monero.daemon.MoneroDaemonRpc;
|
||||||
|
|
||||||
public class LocalMoneroNodeListener {
|
public class LocalMoneroNodeListener {
|
||||||
public void onNodeStarted(MoneroDaemonRpc daemon) {}
|
public void onNodeStarted(MoneroDaemonRpc daemon) {}
|
||||||
public void onNodeStopped() {}
|
public void onNodeStopped() {}
|
||||||
|
public void onConnectionChanged(MoneroRpcConnection connection) {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue