do not start local node when credentialed local node running

rename isMoneroNodeRunning() to isMoneroNodeOnline()
This commit is contained in:
woodser 2022-07-15 13:31:57 -04:00
parent e06fb1a3af
commit 14ada60c25
7 changed files with 74 additions and 61 deletions

View File

@ -247,8 +247,8 @@ public class CoreApi {
// Monero node
///////////////////////////////////////////////////////////////////////////////////////////
public boolean isMoneroNodeRunning() {
return coreMoneroNodeService.isMoneroNodeRunning();
public boolean isMoneroNodeOnline() {
return coreMoneroNodeService.isOnline();
}
public MoneroNodeSettings getMoneroNodeSettings() {

View File

@ -5,6 +5,7 @@ import bisq.common.config.Config;
import bisq.core.btc.model.EncryptedConnectionList;
import bisq.core.btc.setup.DownloadListener;
import bisq.core.btc.setup.WalletsSetup;
import bisq.core.trade.TradeUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -237,7 +238,7 @@ public final class CoreMoneroConnectionsService {
public long getDefaultRefreshPeriodMs() {
if (daemon == null) return REFRESH_PERIOD_LOCAL_MS;
else {
boolean isLocal = CoreMoneroNodeService.isLocalHost(daemon.getRpcConnection().getUri());
boolean isLocal = TradeUtils.isLocalHost(daemon.getRpcConnection().getUri());
if (isLocal) {
updateDaemonInfo();
if (lastInfo != null && (lastInfo.isBusySyncing() || (lastInfo.getHeightWithoutBootstrap() != null && lastInfo.getHeightWithoutBootstrap() > 0 && lastInfo.getHeightWithoutBootstrap() < lastInfo.getHeight()))) return REFRESH_PERIOD_REMOTE_MS; // refresh slower if syncing or bootstrapped
@ -321,6 +322,11 @@ public final class CoreMoneroConnectionsService {
var currentConnectionUri = connectionList.getCurrentConnectionUri();
if (currentConnectionUri.isPresent()) connectionManager.setConnection(currentConnectionUri.get());
// set monero connection from startup arguments
if (!isInitialized && !"".equals(config.xmrNode)) {
connectionManager.setConnection(new MoneroRpcConnection(config.xmrNode, config.xmrNodeUsername, config.xmrNodePassword).setPriority(1));
}
// restore configuration
connectionManager.setAutoSwitch(connectionList.getAutoSwitch());
long refreshPeriod = connectionList.getRefreshPeriod();
@ -331,11 +337,6 @@ public final class CoreMoneroConnectionsService {
// run once
if (!isInitialized) {
// set monero connection from startup arguments
if (!"".equals(config.xmrNode)) {
connectionManager.setConnection(new MoneroRpcConnection(config.xmrNode, config.xmrNodeUsername, config.xmrNodePassword).setPriority(1));
}
// register connection change listener
connectionManager.addListener(this::onConnectionChanged);
@ -358,10 +359,10 @@ public final class CoreMoneroConnectionsService {
isInitialized = true;
}
// start local node if offline and last connection is local
// if offline and last connection is local, start local node if offline
currentConnectionUri.ifPresent(uri -> {
try {
if (CoreMoneroNodeService.isLocalHost(uri) && !nodeService.isMoneroNodeRunning()) {
if (!connectionManager.isConnected() && TradeUtils.isLocalHost(uri) && !nodeService.isOnline()) {
nodeService.startMoneroNode();
}
} catch (Exception e) {
@ -369,8 +370,10 @@ public final class CoreMoneroConnectionsService {
}
});
// connect to local node if available
if (nodeService.isMoneroNodeRunning() && (!connectionManager.isConnected() || connectionManager.getAutoSwitch())) {
// prefer to connect to local node unless prevented by configuration
if (("".equals(config.xmrNode) || TradeUtils.isLocalHost(config.xmrNode)) &&
(!connectionManager.isConnected() || connectionManager.getAutoSwitch()) &&
nodeService.isConnected()) {
MoneroRpcConnection connection = connectionManager.getConnectionByUri(nodeService.getDaemon().getRpcConnection().getUri());
if (connection != null) {
connection.checkConnection(connectionManager.getTimeout());

View File

@ -16,6 +16,7 @@
*/
package bisq.core.api;
import bisq.core.trade.TradeUtils;
import bisq.core.user.Preferences;
import bisq.core.xmr.MoneroNodeSettings;
import bisq.common.config.BaseCurrencyNetwork;
@ -24,8 +25,6 @@ import bisq.common.config.Config;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.net.URI;
import java.io.File;
import java.io.IOException;
@ -34,7 +33,6 @@ import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import monero.common.MoneroError;
import monero.daemon.MoneroDaemonRpc;
/**
@ -44,8 +42,6 @@ import monero.daemon.MoneroDaemonRpc;
@Singleton
public class CoreMoneroNodeService {
private static final String LOOPBACK_HOST = "127.0.0.1"; // local loopback address to host Monero node
private static final String LOCALHOST = "localhost";
private static final String MONERO_NETWORK_TYPE = Config.baseCurrencyNetwork().getNetwork().toLowerCase();
private static final String MONEROD_PATH = System.getProperty("user.dir") + File.separator + ".localnet" + File.separator + "monerod";
private static final String MONEROD_DATADIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1" : null;
@ -72,19 +68,7 @@ public class CoreMoneroNodeService {
else if (Config.baseCurrencyNetwork().isTestnet()) rpcPort = 28081;
else if (Config.baseCurrencyNetwork().isStagenet()) rpcPort = 38081;
else throw new RuntimeException("Base network is not local testnet, stagenet, or mainnet");
this.daemon = new MoneroDaemonRpc("http://" + LOOPBACK_HOST + ":" + rpcPort);
}
/**
* Returns whether the given URI is on local host. // TODO: move to utils
*/
public static boolean isLocalHost(String uri) {
try {
String host = new URI(uri).getHost();
return host.equals(CoreMoneroNodeService.LOOPBACK_HOST) || host.equals(CoreMoneroNodeService.LOCALHOST);
} catch (Exception e) {
throw new RuntimeException(e);
}
this.daemon = new MoneroDaemonRpc("http://" + TradeUtils.LOOPBACK_HOST + ":" + rpcPort);
}
public void addListener(MoneroNodeServiceListener listener) {
@ -96,23 +80,30 @@ public class CoreMoneroNodeService {
}
/**
* Returns the client of the local monero node.
* Return the client of the local Monero node.
*/
public MoneroDaemonRpc getDaemon() {
return daemon;
}
/**
* Returns whether a local monero node is running.
*/
public boolean isMoneroNodeRunning() {
//return daemon.isConnected(); // TODO: daemonRpc.isConnected() should use getVersion() instead of getHeight() which throws when unsynced
try {
daemon.getVersion();
return true;
} catch (MoneroError e) {
return false;
private boolean checkConnection() {
return daemon.getRpcConnection().checkConnection(5000);
}
/**
* Check if local Monero node is online.
*/
public boolean isOnline() {
checkConnection();
return daemon.getRpcConnection().isOnline();
}
/**
* Check if connected to local Monero node.
*/
public boolean isConnected() {
checkConnection();
return daemon.getRpcConnection().isConnected();
}
public MoneroNodeSettings getMoneroNodeSettings() {
@ -120,7 +111,7 @@ public class CoreMoneroNodeService {
}
/**
* Starts a local monero node from settings.
* Start a local Monero node from settings.
*/
public void startMoneroNode() throws IOException {
var settings = preferences.getMoneroNodeSettings();
@ -128,11 +119,11 @@ public class CoreMoneroNodeService {
}
/**
* Starts a local monero node. Throws MoneroError if the node cannot be started.
* Persists the settings to preferences if the node started successfully.
* Start local Monero node. Throws MoneroError if the node cannot be started.
* Persist the settings to preferences if the node started successfully.
*/
public void startMoneroNode(MoneroNodeSettings settings) throws IOException {
if (isMoneroNodeRunning()) throw new IllegalStateException("Local Monero node already running");
if (isOnline()) throw new IllegalStateException("Local Monero node already online");
log.info("Starting local Monero node: " + settings);
@ -160,11 +151,11 @@ public class CoreMoneroNodeService {
}
/**
* Stops the current local monero node if we own its process.
* Stop the current local Monero node if we own its process.
* Does not remove the last MoneroNodeSettings.
*/
public void stopMoneroNode() {
if (!isMoneroNodeRunning()) throw new IllegalStateException("Local Monero node is not running");
if (!isOnline()) throw new IllegalStateException("Local Monero node is not running");
if (daemon.getProcess() == null || !daemon.getProcess().isAlive()) throw new IllegalStateException("Cannot stop local Monero node because we don't own its process"); // TODO (woodser): remove isAlive() check after monero-java 0.5.4 which nullifies internal process
daemon.stopProcess();
for (var listener : listeners) listener.onNodeStopped();

View File

@ -451,7 +451,7 @@ public class XmrWalletService {
try {
log.info("Creating wallet " + config.getPath());
walletRpc.createWallet(config);
log.info("Syncing wallet " + config.getPath());
log.info("Syncing wallet " + config.getPath() + " in background");
walletRpc.startSyncing(connectionsService.getDefaultRefreshPeriodMs());
return walletRpc;
} catch (Exception e) {
@ -473,10 +473,13 @@ public class XmrWalletService {
walletRpc.openWallet(config);
// start syncing wallet in background
log.info("Syncing wallet " + config.getPath() + " in background");
walletRpc.startSyncing(connectionsService.getDefaultRefreshPeriodMs());
// sync wallet (blocks)
walletRpc.sync();
log.info("Syncing wallet " + config.getPath());
walletRpc.sync(); // TODO: does this initiate 2 syncs back-to-back?
log.info("Done syncing wallet " + config.getPath());
return walletRpc;
} catch (Exception e) {
e.printStackTrace();

View File

@ -27,6 +27,7 @@ import bisq.core.offer.OfferPayload;
import bisq.core.support.dispute.arbitration.arbitrator.Arbitrator;
import bisq.core.trade.messages.InitTradeRequest;
import bisq.core.util.JsonUtil;
import java.net.URI;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
@ -35,6 +36,9 @@ import java.util.concurrent.CountDownLatch;
*/
public class TradeUtils {
public static final String LOOPBACK_HOST = "127.0.0.1"; // local loopback address to host Monero node
public static final String LOCALHOST = "localhost";
/**
* Get address to collect trade fees.
*
@ -55,6 +59,18 @@ public class TradeUtils {
}
}
/**
* Check if the given URI is on local host.
*/
public static boolean isLocalHost(String uri) {
try {
String host = new URI(uri).getHost();
return host.equals(LOOPBACK_HOST) || host.equals(LOCALHOST);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Check if the arbitrator signature for an offer is valid.
*

View File

@ -21,8 +21,8 @@ import bisq.core.xmr.MoneroNodeSettings;
import bisq.proto.grpc.GetMoneroNodeSettingsReply;
import bisq.proto.grpc.GetMoneroNodeSettingsRequest;
import bisq.proto.grpc.IsMoneroNodeRunningReply;
import bisq.proto.grpc.IsMoneroNodeRunningRequest;
import bisq.proto.grpc.IsMoneroNodeOnlineReply;
import bisq.proto.grpc.IsMoneroNodeOnlineRequest;
import bisq.proto.grpc.MoneroNodeGrpc.MoneroNodeImplBase;
import bisq.proto.grpc.StartMoneroNodeReply;
import bisq.proto.grpc.StartMoneroNodeRequest;
@ -42,7 +42,7 @@ import lombok.extern.slf4j.Slf4j;
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static bisq.proto.grpc.MoneroNodeGrpc.getStartMoneroNodeMethod;
import static bisq.proto.grpc.MoneroNodeGrpc.getStopMoneroNodeMethod;
import static bisq.proto.grpc.MoneroNodeGrpc.getIsMoneroNodeRunningMethod;
import static bisq.proto.grpc.MoneroNodeGrpc.getIsMoneroNodeOnlineMethod;
import static bisq.proto.grpc.MoneroNodeGrpc.getGetMoneroNodeSettingsMethod;
import static java.util.concurrent.TimeUnit.SECONDS;
@ -63,11 +63,11 @@ public class GrpcMoneroNodeService extends MoneroNodeImplBase {
}
@Override
public void isMoneroNodeRunning(IsMoneroNodeRunningRequest request,
StreamObserver<IsMoneroNodeRunningReply> responseObserver) {
public void isMoneroNodeOnline(IsMoneroNodeOnlineRequest request,
StreamObserver<IsMoneroNodeOnlineReply> responseObserver) {
try {
var reply = IsMoneroNodeRunningReply.newBuilder()
.setIsRunning(coreApi.isMoneroNodeRunning())
var reply = IsMoneroNodeOnlineReply.newBuilder()
.setIsRunning(coreApi.isMoneroNodeOnline())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
@ -146,7 +146,7 @@ public class GrpcMoneroNodeService extends MoneroNodeImplBase {
.or(() -> Optional.of(CallRateMeteringInterceptor.valueOf(
new HashMap<>() {{
int allowedCallsPerTimeWindow = 10;
put(getIsMoneroNodeRunningMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getIsMoneroNodeOnlineMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getGetMoneroNodeSettingsMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getStartMoneroNodeMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getStopMoneroNodeMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));

View File

@ -387,7 +387,7 @@ message SetAutoSwitchReply {}
///////////////////////////////////////////////////////////////////////////////////////////
service MoneroNode {
rpc IsMoneroNodeRunning (IsMoneroNodeRunningRequest) returns (IsMoneroNodeRunningReply) {
rpc IsMoneroNodeOnline (IsMoneroNodeOnlineRequest) returns (IsMoneroNodeOnlineReply) {
}
rpc GetMoneroNodeSettings (GetMoneroNodeSettingsRequest) returns (GetMoneroNodeSettingsReply) {
}
@ -397,10 +397,10 @@ service MoneroNode {
}
}
message IsMoneroNodeRunningRequest {
message IsMoneroNodeOnlineRequest {
}
message IsMoneroNodeRunningReply {
message IsMoneroNodeOnlineReply {
bool is_running = 1;
}