show wallet sync progress on startup

This commit is contained in:
woodser 2023-12-01 11:59:36 -05:00
parent f5d82df477
commit 38bbfafcbb
4 changed files with 65 additions and 21 deletions

View file

@ -250,6 +250,10 @@ public final class XmrConnectionService {
return isConnectionLocal(getConnection()); return isConnectionLocal(getConnection());
} }
public boolean isConnectionTor() {
return useTorProxy(getConnection());
}
public long getRefreshPeriodMs() { public long getRefreshPeriodMs() {
return connectionList.getRefreshPeriod() > 0 ? connectionList.getRefreshPeriod() : getDefaultRefreshPeriodMs(); return connectionList.getRefreshPeriod() > 0 ? connectionList.getRefreshPeriod() : getDefaultRefreshPeriodMs();
} }
@ -318,14 +322,14 @@ public final class XmrConnectionService {
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 XmrLocalNode.REFRESH_PERIOD_LOCAL_MS; // TODO: announce faster refresh after done syncing else return XmrLocalNode.REFRESH_PERIOD_LOCAL_MS; // TODO: announce faster refresh after done syncing
} else if (useProxy(connection)) { } else if (useTorProxy(connection)) {
return REFRESH_PERIOD_ONION_MS; return REFRESH_PERIOD_ONION_MS;
} else { } else {
return REFRESH_PERIOD_HTTP_MS; return REFRESH_PERIOD_HTTP_MS;
} }
} }
private boolean useProxy(MoneroRpcConnection connection) { private boolean useTorProxy(MoneroRpcConnection connection) {
return connection.isOnion() || (preferences.getUseTorForXmr().isUseTorForXmr() && !HavenoUtils.isLocalHost(connection.getUri())); return connection.isOnion() || (preferences.getUseTorForXmr().isUseTorForXmr() && !HavenoUtils.isLocalHost(connection.getUri()));
} }
@ -435,7 +439,7 @@ public final class XmrConnectionService {
// set connection proxies // set connection proxies
log.info("TOR proxy URI: " + getProxyUri()); log.info("TOR proxy URI: " + getProxyUri());
for (MoneroRpcConnection connection : connectionManager.getConnections()) { for (MoneroRpcConnection connection : connectionManager.getConnections()) {
if (useProxy(connection)) connection.setProxyUri(getProxyUri()); if (useTorProxy(connection)) connection.setProxyUri(getProxyUri());
} }
// restore auto switch // restore auto switch
@ -456,7 +460,7 @@ public final class XmrConnectionService {
// set connection from startup argument if given // set connection from startup argument if given
connectionManager.setAutoSwitch(false); connectionManager.setAutoSwitch(false);
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 (useProxy(connection)) connection.setProxyUri(getProxyUri()); if (useTorProxy(connection)) connection.setProxyUri(getProxyUri());
connectionManager.setConnection(connection); connectionManager.setConnection(connection);
// start local node if used last and offline // start local node if used last and offline

View file

@ -125,15 +125,14 @@ public class WalletAppSetup {
Long bestWalletHeight = walletHeight == null ? null : (Long) walletHeight; Long bestWalletHeight = walletHeight == null ? null : (Long) walletHeight;
String walletHeightAsString = bestWalletHeight != null && bestWalletHeight > 0 ? String.valueOf(bestWalletHeight) : ""; String walletHeightAsString = bestWalletHeight != null && bestWalletHeight > 0 ? String.valueOf(bestWalletHeight) : "";
if (walletDownloadPercentageD == 1) { if (walletDownloadPercentageD == 1) {
String synchronizedWith = Res.get("mainView.footer.xmrInfo.synchronizedWalletWith", getXmrNetworkAsString(), walletHeightAsString); String synchronizedWith = Res.get("mainView.footer.xmrInfo.synchronizedWalletWith", getXmrWalletNetworkAsString(), walletHeightAsString);
String feeInfo = ""; // TODO: feeService.isFeeAvailable() returns true, disable String feeInfo = ""; // TODO: feeService.isFeeAvailable() returns true, disable
result = Res.get("mainView.footer.xmrInfo", synchronizedWith, feeInfo); result = Res.get("mainView.footer.xmrInfo", synchronizedWith, feeInfo);
getXmrSplashSyncIconId().set("image-connection-synced"); getXmrSplashSyncIconId().set("image-connection-synced");
downloadCompleteHandler.run(); downloadCompleteHandler.run();
} else if (walletDownloadPercentageD > 0) { } else if (walletDownloadPercentageD > 0) {
result = "Synchronizing wallet ..."; // TODO: support wallet progress updates and use below translation String synchronizingWith = Res.get("mainView.footer.xmrInfo.synchronizingWalletWith", getXmrWalletNetworkAsString(), walletHeightAsString, FormattingUtils.formatToRoundedPercentWithSymbol(walletDownloadPercentageD));
// String synchronizingWith = Res.get("mainView.footer.xmrInfo.synchronizingWalletWith", getXmrNetworkAsString(), walletHeightAsString, FormattingUtils.formatToRoundedPercentWithSymbol(walletDownloadPercentageD)); result = Res.get("mainView.footer.xmrInfo", synchronizingWith, "");
// result = Res.get("mainView.footer.xmrInfo", synchronizingWith, "");
getXmrSplashSyncIconId().set(""); // clear synced icon getXmrSplashSyncIconId().set(""); // clear synced icon
} else { } else {
@ -143,23 +142,23 @@ public class WalletAppSetup {
Long bestChainHeight = chainHeight == null ? null : (Long) chainHeight; Long bestChainHeight = chainHeight == null ? null : (Long) chainHeight;
String chainHeightAsString = bestChainHeight != null && bestChainHeight > 0 ? String.valueOf(bestChainHeight) : ""; String chainHeightAsString = bestChainHeight != null && bestChainHeight > 0 ? String.valueOf(bestChainHeight) : "";
if (chainDownloadPercentageD == 1) { if (chainDownloadPercentageD == 1) {
String synchronizedWith = Res.get("mainView.footer.xmrInfo.synchronizedDaemonWith", getXmrNetworkAsString(), chainHeightAsString); String synchronizedWith = Res.get("mainView.footer.xmrInfo.synchronizedDaemonWith", getXmrDaemonNetworkAsString(), chainHeightAsString);
String feeInfo = ""; // TODO: feeService.isFeeAvailable() returns true, disable String feeInfo = ""; // TODO: feeService.isFeeAvailable() returns true, disable
result = Res.get("mainView.footer.xmrInfo", synchronizedWith, feeInfo); result = Res.get("mainView.footer.xmrInfo", synchronizedWith, feeInfo);
getXmrSplashSyncIconId().set("image-connection-synced"); getXmrSplashSyncIconId().set("image-connection-synced");
} else if (chainDownloadPercentageD > 0.0) { } else if (chainDownloadPercentageD > 0.0) {
String synchronizingWith = Res.get("mainView.footer.xmrInfo.synchronizingDaemonWith", getXmrNetworkAsString(), chainHeightAsString, FormattingUtils.formatToRoundedPercentWithSymbol(chainDownloadPercentageD)); String synchronizingWith = Res.get("mainView.footer.xmrInfo.synchronizingDaemonWith", getXmrDaemonNetworkAsString(), chainHeightAsString, FormattingUtils.formatToRoundedPercentWithSymbol(chainDownloadPercentageD));
result = Res.get("mainView.footer.xmrInfo", synchronizingWith, ""); result = Res.get("mainView.footer.xmrInfo", synchronizingWith, "");
} else { } else {
result = Res.get("mainView.footer.xmrInfo", result = Res.get("mainView.footer.xmrInfo",
Res.get("mainView.footer.xmrInfo.connectingTo"), Res.get("mainView.footer.xmrInfo.connectingTo"),
getXmrNetworkAsString()); getXmrDaemonNetworkAsString());
} }
} }
} else { } else {
result = Res.get("mainView.footer.xmrInfo", result = Res.get("mainView.footer.xmrInfo",
Res.get("mainView.footer.xmrInfo.connectionFailed"), Res.get("mainView.footer.xmrInfo.connectionFailed"),
getXmrNetworkAsString()); getXmrDaemonNetworkAsString());
if (exception != null) { if (exception != null) {
if (exception instanceof TimeoutException) { if (exception instanceof TimeoutException) {
getWalletServiceErrorMsg().set(Res.get("mainView.walletServiceErrorMsg.timeout")); getWalletServiceErrorMsg().set(Res.get("mainView.walletServiceErrorMsg.timeout"));
@ -253,11 +252,22 @@ public class WalletAppSetup {
}); });
} }
private String getXmrNetworkAsString() { private String getXmrDaemonNetworkAsString() {
String postFix; String postFix;
if (config.ignoreLocalXmrNode) if (xmrConnectionService.isConnectionLocal())
postFix = " " + Res.get("mainView.footer.localhostMoneroNode"); postFix = " " + Res.get("mainView.footer.localhostMoneroNode");
else if (preferences.getUseTorForXmr().isUseTorForXmr()) else if (xmrConnectionService.isConnectionTor())
postFix = " " + Res.get("mainView.footer.usingTor");
else
postFix = "";
return Res.get(config.baseCurrencyNetwork.name()) + postFix;
}
private String getXmrWalletNetworkAsString() {
String postFix;
if (xmrConnectionService.isConnectionLocal())
postFix = " " + Res.get("mainView.footer.localhostMoneroNode");
else if (xmrWalletService.isProxyApplied())
postFix = " " + Res.get("mainView.footer.usingTor"); postFix = " " + Res.get("mainView.footer.usingTor");
else else
postFix = ""; postFix = "";

View file

@ -28,6 +28,7 @@ import monero.common.MoneroError;
import monero.common.MoneroRpcConnection; import monero.common.MoneroRpcConnection;
import monero.common.MoneroRpcError; import monero.common.MoneroRpcError;
import monero.common.MoneroUtils; import monero.common.MoneroUtils;
import monero.common.TaskLooper;
import monero.daemon.MoneroDaemonRpc; import monero.daemon.MoneroDaemonRpc;
import monero.daemon.model.MoneroFeeEstimate; import monero.daemon.model.MoneroFeeEstimate;
import monero.daemon.model.MoneroNetworkType; import monero.daemon.model.MoneroNetworkType;
@ -126,6 +127,7 @@ public class XmrWalletService {
private boolean isShutDownStarted = false; private boolean isShutDownStarted = false;
private ExecutorService syncWalletThreadPool = Executors.newFixedThreadPool(10); // TODO: adjust based on connection type private ExecutorService syncWalletThreadPool = Executors.newFixedThreadPool(10); // TODO: adjust based on connection type
private Long syncStartHeight = null; private Long syncStartHeight = null;
private TaskLooper syncLooper = null;
@Inject @Inject
XmrWalletService(Preferences preferences, XmrWalletService(Preferences preferences,
@ -247,6 +249,10 @@ public class XmrWalletService {
public XmrConnectionService getConnectionService() { public XmrConnectionService getConnectionService() {
return xmrConnectionService; return xmrConnectionService;
} }
public boolean isProxyApplied() {
return isProxyApplied(wasWalletSynced);
}
public boolean isProxyApplied(boolean wasWalletSynced) { public boolean isProxyApplied(boolean wasWalletSynced) {
return preferences.isProxyApplied(wasWalletSynced); return preferences.isProxyApplied(wasWalletSynced);
@ -728,11 +734,8 @@ public class XmrWalletService {
// sync main wallet // sync main wallet
log.info("Syncing main wallet"); log.info("Syncing main wallet");
updateSyncProgress();
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
wallet.sync(); // blocking syncWalletWithProgress(); // blocking
walletHeight.set(wallet.getHeight());
wasWalletSynced = true;
log.info("Done syncing main wallet in " + (System.currentTimeMillis() - time) + " ms"); log.info("Done syncing main wallet in " + (System.currentTimeMillis() - time) + " ms");
wallet.startSyncing(xmrConnectionService.getRefreshPeriodMs()); wallet.startSyncing(xmrConnectionService.getRefreshPeriodMs());
wallet.getTxs(new MoneroTxQuery().setIsLocked(true)); // TODO: main wallet's balance does update on startup with 0 conf PaymentReceivedMessage until pool txs fetched? wallet.getTxs(new MoneroTxQuery().setIsLocked(true)); // TODO: main wallet's balance does update on startup with 0 conf PaymentReceivedMessage until pool txs fetched?
@ -777,8 +780,33 @@ public class XmrWalletService {
} }
} }
private void syncWalletWithProgress() {
updateSyncProgress();
wallet.startSyncing();
CountDownLatch latch = new CountDownLatch(1);
syncLooper = new TaskLooper(() -> {
if (wallet.getHeight() < xmrConnectionService.getTargetHeight()) updateSyncProgress();
else {
wasWalletSynced = true;
updateSyncProgress();
syncLooper.stop();
latch.countDown();
}
});
syncLooper.start(1000);
HavenoUtils.awaitLatch(latch);
}
private void updateSyncProgress() { private void updateSyncProgress() {
walletHeight.set(wallet.getHeight()); walletHeight.set(wallet.getHeight());
// new wallet reports height 1 before synced
if (wallet.getHeight() == 1) {
downloadListener.progress(.0001, xmrConnectionService.getTargetHeight(), null); // >0% shows progress bar
return;
}
// set progress
long targetHeight = xmrConnectionService.getTargetHeight(); long targetHeight = xmrConnectionService.getTargetHeight();
long blocksLeft = targetHeight - walletHeight.get(); long blocksLeft = targetHeight - walletHeight.get();
if (syncStartHeight == null) syncStartHeight = walletHeight.get(); if (syncStartHeight == null) syncStartHeight = walletHeight.get();

View file

@ -536,8 +536,10 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
xmrSyncIcon.setVisible(true); xmrSyncIcon.setVisible(true);
xmrSyncIcon.setManaged(true); xmrSyncIcon.setManaged(true);
xmrSyncIndicator.setVisible(false); // show progress bar until we have checkmark id
xmrSyncIndicator.setManaged(false); boolean inProgress = "".equals(newValue);
xmrSyncIndicator.setVisible(inProgress);
xmrSyncIndicator.setManaged(inProgress);
}; };
model.getXmrSplashSyncIconId().addListener(xmrSyncIconIdListener); model.getXmrSplashSyncIconId().addListener(xmrSyncIconIdListener);