mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-05-09 14:22:30 +00:00
prompt to fallback if last synced local node is offline on startup
This commit is contained in:
parent
a21971429c
commit
93369c4211
5 changed files with 36 additions and 50 deletions
core/src/main
java/haveno/core
resources/i18n
desktop/src/main/java/haveno/desktop/main
|
@ -24,6 +24,7 @@ import haveno.common.UserThread;
|
||||||
import haveno.common.app.DevEnv;
|
import haveno.common.app.DevEnv;
|
||||||
import haveno.common.config.BaseCurrencyNetwork;
|
import haveno.common.config.BaseCurrencyNetwork;
|
||||||
import haveno.common.config.Config;
|
import haveno.common.config.Config;
|
||||||
|
import haveno.core.locale.Res;
|
||||||
import haveno.core.trade.HavenoUtils;
|
import haveno.core.trade.HavenoUtils;
|
||||||
import haveno.core.user.Preferences;
|
import haveno.core.user.Preferences;
|
||||||
import haveno.core.xmr.model.EncryptedConnectionList;
|
import haveno.core.xmr.model.EncryptedConnectionList;
|
||||||
|
@ -43,7 +44,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import javafx.beans.property.BooleanProperty;
|
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
import javafx.beans.property.LongProperty;
|
import javafx.beans.property.LongProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
@ -51,7 +51,6 @@ import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||||
import javafx.beans.property.ReadOnlyIntegerProperty;
|
import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||||
import javafx.beans.property.ReadOnlyLongProperty;
|
import javafx.beans.property.ReadOnlyLongProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import javafx.beans.property.SimpleLongProperty;
|
import javafx.beans.property.SimpleLongProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
@ -91,7 +90,7 @@ public final class XmrConnectionService {
|
||||||
private final LongProperty chainHeight = new SimpleLongProperty(0);
|
private final LongProperty chainHeight = new SimpleLongProperty(0);
|
||||||
private final DownloadListener downloadListener = new DownloadListener();
|
private final DownloadListener downloadListener = new DownloadListener();
|
||||||
@Getter
|
@Getter
|
||||||
private final BooleanProperty connectionServiceFallbackHandlerActive = new SimpleBooleanProperty();
|
private final SimpleStringProperty connectionServiceFallbackHandler = new SimpleStringProperty();
|
||||||
@Getter
|
@Getter
|
||||||
private final StringProperty connectionServiceErrorMsg = new SimpleStringProperty();
|
private final StringProperty connectionServiceErrorMsg = new SimpleStringProperty();
|
||||||
private final LongProperty numUpdates = new SimpleLongProperty(0);
|
private final LongProperty numUpdates = new SimpleLongProperty(0);
|
||||||
|
@ -261,6 +260,7 @@ public final class XmrConnectionService {
|
||||||
|
|
||||||
private MoneroRpcConnection getBestConnection(Collection<MoneroRpcConnection> ignoredConnections) {
|
private MoneroRpcConnection getBestConnection(Collection<MoneroRpcConnection> ignoredConnections) {
|
||||||
accountService.checkAccountOpen();
|
accountService.checkAccountOpen();
|
||||||
|
if (!fallbackApplied && lastUsedLocalSyncingNode() && !xmrLocalNode.isDetected()) return null; // user needs to explicitly allow fallback after syncing local node
|
||||||
Set<MoneroRpcConnection> ignoredConnectionsSet = new HashSet<>(ignoredConnections);
|
Set<MoneroRpcConnection> ignoredConnectionsSet = new HashSet<>(ignoredConnections);
|
||||||
addLocalNodeIfIgnored(ignoredConnectionsSet);
|
addLocalNodeIfIgnored(ignoredConnectionsSet);
|
||||||
MoneroRpcConnection bestConnection = connectionManager.getBestAvailableConnection(ignoredConnectionsSet.toArray(new MoneroRpcConnection[0])); // checks connections
|
MoneroRpcConnection bestConnection = connectionManager.getBestAvailableConnection(ignoredConnectionsSet.toArray(new MoneroRpcConnection[0])); // checks connections
|
||||||
|
@ -604,9 +604,6 @@ public final class XmrConnectionService {
|
||||||
if (coreContext.isApiUser()) connectionManager.setAutoSwitch(connectionList.getAutoSwitch());
|
if (coreContext.isApiUser()) connectionManager.setAutoSwitch(connectionList.getAutoSwitch());
|
||||||
else connectionManager.setAutoSwitch(true); // auto switch is always enabled on desktop ui
|
else connectionManager.setAutoSwitch(true); // auto switch is always enabled on desktop ui
|
||||||
|
|
||||||
// start local node if applicable
|
|
||||||
maybeStartLocalNode();
|
|
||||||
|
|
||||||
// update connection
|
// update connection
|
||||||
if (connectionManager.getConnection() == null || connectionManager.getAutoSwitch()) {
|
if (connectionManager.getConnection() == null || connectionManager.getAutoSwitch()) {
|
||||||
MoneroRpcConnection bestConnection = getBestConnection();
|
MoneroRpcConnection bestConnection = getBestConnection();
|
||||||
|
@ -619,9 +616,6 @@ public final class XmrConnectionService {
|
||||||
MoneroRpcConnection connection = new MoneroRpcConnection(config.xmrNode, config.xmrNodeUsername, config.xmrNodePassword).setPriority(1);
|
MoneroRpcConnection connection = new MoneroRpcConnection(config.xmrNode, config.xmrNodeUsername, config.xmrNodePassword).setPriority(1);
|
||||||
if (isProxyApplied(connection)) connection.setProxyUri(getProxyUri());
|
if (isProxyApplied(connection)) connection.setProxyUri(getProxyUri());
|
||||||
connectionManager.setConnection(connection);
|
connectionManager.setConnection(connection);
|
||||||
|
|
||||||
// start local node if applicable
|
|
||||||
maybeStartLocalNode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register connection listener
|
// register connection listener
|
||||||
|
@ -634,20 +628,8 @@ public final class XmrConnectionService {
|
||||||
onConnectionChanged(connectionManager.getConnection());
|
onConnectionChanged(connectionManager.getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeStartLocalNode() {
|
private boolean lastUsedLocalSyncingNode() {
|
||||||
|
return connectionManager.getConnection() != null && xmrLocalNode.equalsUri(connectionManager.getConnection().getUri()) && !xmrLocalNode.isDetected() && !xmrLocalNode.shouldBeIgnored();
|
||||||
// skip if seed node
|
|
||||||
if (HavenoUtils.isSeedNode()) return;
|
|
||||||
|
|
||||||
// start local node if offline and used as last connection
|
|
||||||
if (connectionManager.getConnection() != null && xmrLocalNode.equalsUri(connectionManager.getConnection().getUri()) && !xmrLocalNode.isDetected() && !xmrLocalNode.shouldBeIgnored()) {
|
|
||||||
try {
|
|
||||||
log.info("Starting local node");
|
|
||||||
xmrLocalNode.start();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unable to start local monero node, error={}\n", e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onConnectionChanged(MoneroRpcConnection currentConnection) {
|
private void onConnectionChanged(MoneroRpcConnection currentConnection) {
|
||||||
|
@ -733,12 +715,17 @@ public final class XmrConnectionService {
|
||||||
if (isShutDownStarted) return;
|
if (isShutDownStarted) return;
|
||||||
|
|
||||||
// invoke fallback handling on startup error
|
// invoke fallback handling on startup error
|
||||||
boolean canFallback = isFixedConnection() || isCustomConnections();
|
boolean canFallback = isFixedConnection() || isCustomConnections() || lastUsedLocalSyncingNode();
|
||||||
if (lastInfo == null && canFallback) {
|
if (lastInfo == null && canFallback) {
|
||||||
if (!connectionServiceFallbackHandlerActive.get() && (lastFallbackInvocation == null || System.currentTimeMillis() - lastFallbackInvocation > FALLBACK_INVOCATION_PERIOD_MS)) {
|
if (connectionServiceFallbackHandler.get() == null || connectionServiceFallbackHandler.equals("") && (lastFallbackInvocation == null || System.currentTimeMillis() - lastFallbackInvocation > FALLBACK_INVOCATION_PERIOD_MS)) {
|
||||||
log.warn("Failed to fetch daemon info from custom connection on startup: " + e.getMessage());
|
|
||||||
lastFallbackInvocation = System.currentTimeMillis();
|
lastFallbackInvocation = System.currentTimeMillis();
|
||||||
connectionServiceFallbackHandlerActive.set(true);
|
if (lastUsedLocalSyncingNode()) {
|
||||||
|
log.warn("Failed to fetch daemon info from local connection on startup: " + e.getMessage());
|
||||||
|
connectionServiceFallbackHandler.set(Res.get("connectionFallback.localNode"));
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to fetch daemon info from custom connection on startup: " + e.getMessage());
|
||||||
|
connectionServiceFallbackHandler.set(Res.get("connectionFallback.customNode"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class HavenoSetup {
|
||||||
rejectedTxErrorMessageHandler;
|
rejectedTxErrorMessageHandler;
|
||||||
@Setter
|
@Setter
|
||||||
@Nullable
|
@Nullable
|
||||||
private Consumer<Boolean> displayMoneroConnectionFallbackHandler;
|
private Consumer<String> displayMoneroConnectionFallbackHandler;
|
||||||
@Setter
|
@Setter
|
||||||
@Nullable
|
@Nullable
|
||||||
private Consumer<Boolean> displayTorNetworkSettingsHandler;
|
private Consumer<Boolean> displayTorNetworkSettingsHandler;
|
||||||
|
@ -430,7 +430,7 @@ public class HavenoSetup {
|
||||||
getXmrWalletSyncProgress().addListener((observable, oldValue, newValue) -> resetStartupTimeout());
|
getXmrWalletSyncProgress().addListener((observable, oldValue, newValue) -> resetStartupTimeout());
|
||||||
|
|
||||||
// listen for fallback handling
|
// listen for fallback handling
|
||||||
getConnectionServiceFallbackHandlerActive().addListener((observable, oldValue, newValue) -> {
|
getConnectionServiceFallbackHandler().addListener((observable, oldValue, newValue) -> {
|
||||||
if (displayMoneroConnectionFallbackHandler == null) return;
|
if (displayMoneroConnectionFallbackHandler == null) return;
|
||||||
displayMoneroConnectionFallbackHandler.accept(newValue);
|
displayMoneroConnectionFallbackHandler.accept(newValue);
|
||||||
});
|
});
|
||||||
|
@ -734,8 +734,8 @@ public class HavenoSetup {
|
||||||
return xmrConnectionService.getConnectionServiceErrorMsg();
|
return xmrConnectionService.getConnectionServiceErrorMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty getConnectionServiceFallbackHandlerActive() {
|
public StringProperty getConnectionServiceFallbackHandler() {
|
||||||
return xmrConnectionService.getConnectionServiceFallbackHandlerActive();
|
return xmrConnectionService.getConnectionServiceFallbackHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty getTopErrorMsg() {
|
public StringProperty getTopErrorMsg() {
|
||||||
|
|
|
@ -2058,7 +2058,8 @@ closedTradesSummaryWindow.totalTradeFeeInXmr.value={0} ({1} of total trade amoun
|
||||||
walletPasswordWindow.headline=Enter password to unlock
|
walletPasswordWindow.headline=Enter password to unlock
|
||||||
|
|
||||||
connectionFallback.headline=Connection error
|
connectionFallback.headline=Connection error
|
||||||
connectionFallback.msg=Error connecting to your custom Monero node(s).\n\nDo you want to try the next best available Monero node?
|
connectionFallback.customNode=Error connecting to your custom Monero node(s).\n\nDo you want to use the next best available Monero node?
|
||||||
|
connectionFallback.localNode=Error connecting to your last used local node.\n\nDo you want to use the next best available Monero node?
|
||||||
|
|
||||||
torNetworkSettingWindow.header=Tor networks settings
|
torNetworkSettingWindow.header=Tor networks settings
|
||||||
torNetworkSettingWindow.noBridges=Don't use bridges
|
torNetworkSettingWindow.noBridges=Don't use bridges
|
||||||
|
|
|
@ -2057,7 +2057,7 @@ closedTradesSummaryWindow.totalTradeFeeInXmr.value={0} ({1} z celkového objemu
|
||||||
walletPasswordWindow.headline=Pro odemknutí zadejte heslo
|
walletPasswordWindow.headline=Pro odemknutí zadejte heslo
|
||||||
|
|
||||||
connectionFallback.headline=Chyba připojení
|
connectionFallback.headline=Chyba připojení
|
||||||
connectionFallback.msg=Chyba při připojování k vlastním uzlům Monero.\n\nChcete vyzkoušet další nejlepší dostupný uzel Monero?
|
connectionFallback.customNode=Chyba při připojování k vlastním uzlům Monero.\n\nChcete vyzkoušet další nejlepší dostupný uzel Monero?
|
||||||
|
|
||||||
torNetworkSettingWindow.header=Nastavení sítě Tor
|
torNetworkSettingWindow.header=Nastavení sítě Tor
|
||||||
torNetworkSettingWindow.noBridges=Nepoužívat most (bridge)
|
torNetworkSettingWindow.noBridges=Nepoužívat most (bridge)
|
||||||
|
|
|
@ -335,25 +335,23 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
|
||||||
tacWindow.onAction(acceptedHandler::run).show();
|
tacWindow.onAction(acceptedHandler::run).show();
|
||||||
}, 1));
|
}, 1));
|
||||||
|
|
||||||
havenoSetup.setDisplayMoneroConnectionFallbackHandler(show -> {
|
havenoSetup.setDisplayMoneroConnectionFallbackHandler(fallbackMsg -> {
|
||||||
if (moneroConnectionFallbackPopup == null) {
|
if (fallbackMsg != null && !fallbackMsg.isEmpty()) {
|
||||||
moneroConnectionFallbackPopup = new Popup()
|
moneroConnectionFallbackPopup = new Popup()
|
||||||
.headLine(Res.get("connectionFallback.headline"))
|
.headLine(Res.get("connectionFallback.headline"))
|
||||||
.warning(Res.get("connectionFallback.msg"))
|
.warning(fallbackMsg)
|
||||||
.closeButtonText(Res.get("shared.no"))
|
.closeButtonText(Res.get("shared.no"))
|
||||||
.actionButtonText(Res.get("shared.yes"))
|
.actionButtonText(Res.get("shared.yes"))
|
||||||
.onAction(() -> {
|
.onAction(() -> {
|
||||||
havenoSetup.getConnectionServiceFallbackHandlerActive().set(false);
|
havenoSetup.getConnectionServiceFallbackHandler().set("");
|
||||||
new Thread(() -> HavenoUtils.xmrConnectionService.fallbackToBestConnection()).start();
|
new Thread(() -> HavenoUtils.xmrConnectionService.fallbackToBestConnection()).start();
|
||||||
})
|
})
|
||||||
.onClose(() -> {
|
.onClose(() -> {
|
||||||
log.warn("User has declined to fallback to the next best available Monero node.");
|
log.warn("User has declined to fallback to the next best available Monero node.");
|
||||||
havenoSetup.getConnectionServiceFallbackHandlerActive().set(false);
|
havenoSetup.getConnectionServiceFallbackHandler().set("");
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (show) {
|
|
||||||
moneroConnectionFallbackPopup.show();
|
moneroConnectionFallbackPopup.show();
|
||||||
} else if (moneroConnectionFallbackPopup.isDisplayed()) {
|
} else if (moneroConnectionFallbackPopup != null && moneroConnectionFallbackPopup.isDisplayed()) {
|
||||||
moneroConnectionFallbackPopup.hide();
|
moneroConnectionFallbackPopup.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue