check that wallet is synced within tolerance

This commit is contained in:
woodser 2023-11-27 14:30:49 -05:00
parent 5fc7fef223
commit 9957aa6256
29 changed files with 66 additions and 62 deletions

View file

@ -260,17 +260,18 @@ public final class XmrConnectionService {
}
public boolean isSyncedWithinTolerance() {
if (daemon == null) return false;
Long targetHeight = lastInfo.getTargetHeight(); // the last time the node thought it was behind the network and was in active sync mode to catch up
if (targetHeight == 0) return true; // monero-daemon-rpc sync_info's target_height returns 0 when node is fully synced
long currentHeight = chainHeight.get();
if (targetHeight - currentHeight <= 3) { // synced if not more than 3 blocks behind target height
return true;
}
Long targetHeight = getTargetHeight();
if (targetHeight == null) return false;
if (targetHeight - chainHeight.get() <= 3) return true; // synced if within 3 blocks of target height
log.warn("Our chain height: {} is out of sync with peer nodes chain height: {}", chainHeight.get(), targetHeight);
return false;
}
public Long getTargetHeight() {
if (daemon == null || lastInfo == null) return null;
return lastInfo.getTargetHeight() == 0 ? chainHeight.get() : lastInfo.getTargetHeight(); // monerod sync_info's target_height returns 0 when node is fully synced
}
// ----------------------------- APP METHODS ------------------------------
public ReadOnlyIntegerProperty numPeersProperty() {

View file

@ -70,7 +70,7 @@ public class AppStartupState {
});
xmrWalletService.downloadPercentageProperty().addListener((observable, oldValue, newValue) -> {
if (xmrWalletService.isWalletSynced())
if (xmrWalletService.isDownloadComplete())
isWalletSynced.set(true);
});

View file

@ -47,7 +47,7 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
runInterceptHook();
// verify monero connection
model.getXmrWalletService().getConnectionsService().verifyConnection();
model.getXmrWalletService().getConnectionService().verifyConnection();
// create reserve tx
BigInteger makerFee = offer.getMakerFee();

View file

@ -338,7 +338,7 @@ public abstract class SupportManager {
p2PService.isBootstrapped() &&
xmrConnectionService.isDownloadComplete() &&
xmrConnectionService.hasSufficientPeersForBroadcast() &&
xmrWalletService.isWalletSynced();
xmrWalletService.isDownloadComplete();
}

View file

@ -252,18 +252,8 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
}
});
xmrConnectionService.downloadPercentageProperty().addListener((observable, oldValue, newValue) -> {
if (xmrConnectionService.isDownloadComplete())
tryApplyMessages();
});
xmrWalletService.downloadPercentageProperty().addListener((observable, oldValue, newValue) -> {
if (xmrWalletService.isWalletSynced())
tryApplyMessages();
});
xmrConnectionService.numPeersProperty().addListener((observable, oldValue, newValue) -> {
if (xmrConnectionService.hasSufficientPeersForBroadcast())
if (xmrWalletService.isSyncedWithinTolerance())
tryApplyMessages();
});

View file

@ -588,7 +588,7 @@ public abstract class Trade implements Tradable, Model {
});
// handle daemon changes with max parallelization
xmrWalletService.getConnectionsService().addConnectionListener(newConnection -> {
xmrWalletService.getConnectionService().addConnectionListener(newConnection -> {
HavenoUtils.submitTask(() -> onConnectionChanged(newConnection));
});
@ -643,7 +643,7 @@ public abstract class Trade implements Tradable, Model {
new Thread(() -> {
GenUtils.waitFor(1000);
if (isShutDownStarted) return;
if (Boolean.TRUE.equals(xmrWalletService.getConnectionsService().isConnected())) xmrWalletService.syncWallet(xmrWalletService.getWallet());
if (Boolean.TRUE.equals(xmrWalletService.getConnectionService().isConnected())) xmrWalletService.syncWallet(xmrWalletService.getWallet());
}).start();
// complete disputed trade
@ -758,7 +758,7 @@ public abstract class Trade implements Tradable, Model {
}
public void checkDaemonConnection() {
XmrConnectionService xmrConnectionService = xmrWalletService.getConnectionsService();
XmrConnectionService xmrConnectionService = xmrWalletService.getConnectionService();
xmrConnectionService.checkConnection();
xmrConnectionService.verifyConnection();
if (!getWallet().isConnectedToDaemon()) throw new RuntimeException("Trade wallet is not connected to a Monero node");
@ -783,7 +783,7 @@ public abstract class Trade implements Tradable, Model {
public void syncWalletNormallyForMs(long syncNormalDuration) {
syncNormalStartTime = System.currentTimeMillis();
setWalletRefreshPeriod(xmrWalletService.getConnectionsService().getRefreshPeriodMs());
setWalletRefreshPeriod(xmrWalletService.getConnectionService().getRefreshPeriodMs());
UserThread.runAfter(() -> {
if (!isShutDown && System.currentTimeMillis() >= syncNormalStartTime + syncNormalDuration) updateWalletRefreshPeriod();
}, syncNormalDuration);
@ -1684,7 +1684,7 @@ public abstract class Trade implements Tradable, Model {
*/
public long getReprocessDelayInSeconds(int reprocessCount) {
int retryCycles = 3; // reprocess on next refresh periods for first few attempts (app might auto switch to a good connection)
if (reprocessCount < retryCycles) return xmrWalletService.getConnectionsService().getRefreshPeriodMs() / 1000;
if (reprocessCount < retryCycles) return xmrWalletService.getConnectionService().getRefreshPeriodMs() / 1000;
long delay = 60;
for (int i = retryCycles; i < reprocessCount; i++) delay *= 2;
return Math.min(MAX_REPROCESS_DELAY_SECONDS, delay);
@ -1785,7 +1785,7 @@ public abstract class Trade implements Tradable, Model {
if (!wasWalletSynced) {
wasWalletSynced = true;
if (xmrWalletService.isProxyApplied(wasWalletSynced)) {
onConnectionChanged(xmrWalletService.getConnectionsService().getConnection());
onConnectionChanged(xmrWalletService.getConnectionService().getConnection());
}
}
@ -1843,7 +1843,7 @@ public abstract class Trade implements Tradable, Model {
try {
// log warning if wallet is too far behind daemon
MoneroDaemonInfo lastInfo = xmrWalletService.getConnectionsService().getLastInfo();
MoneroDaemonInfo lastInfo = xmrWalletService.getConnectionService().getLastInfo();
long walletHeight = wallet.getHeight();
if (wasWalletSynced && isDepositsPublished() && lastInfo != null && walletHeight < lastInfo.getHeight() - 3 && !Config.baseCurrencyNetwork().isTestnet()) {
log.warn("Wallet is more than 3 blocks behind monerod for {} {}, wallet height={}, monerod height={},", getClass().getSimpleName(), getShortId(), walletHeight, lastInfo.getHeight());
@ -1924,7 +1924,7 @@ public abstract class Trade implements Tradable, Model {
}
} catch (Exception e) {
if (!isShutDownStarted && wallet != null && isWalletConnected()) {
log.warn("Error polling trade wallet for {} {}: {}. Monerod={}", getClass().getSimpleName(), getId(), e.getMessage(), getXmrWalletService().getConnectionsService().getConnection());
log.warn("Error polling trade wallet for {} {}: {}. Monerod={}", getClass().getSimpleName(), getId(), e.getMessage(), getXmrWalletService().getConnectionService().getConnection());
}
}
}
@ -1932,7 +1932,7 @@ public abstract class Trade implements Tradable, Model {
private long getWalletRefreshPeriod() {
if (isIdling()) return IDLE_SYNC_PERIOD_MS;
return xmrWalletService.getConnectionsService().getRefreshPeriodMs();
return xmrWalletService.getConnectionService().getRefreshPeriodMs();
}
private void setStateDepositsPublished() {

View file

@ -1285,7 +1285,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
// listen for block confirmation to remove trade
long startTime = System.currentTimeMillis();
heightSubscription = EasyBind.subscribe(xmrWalletService.getConnectionsService().chainHeightProperty(), lastBlockHeight -> {
heightSubscription = EasyBind.subscribe(xmrWalletService.getConnectionService().chainHeightProperty(), lastBlockHeight -> {
if (isShutDown) return;
if (startHeight == null) startHeight = lastBlockHeight.longValue();
if (lastBlockHeight.longValue() >= startHeight + REMOVE_AFTER_NUM_CONFIRMATIONS) {

View file

@ -823,7 +823,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
}
void handleTaskRunnerFault(NodeAddress ackReceiver, @Nullable TradeMessage message, String source, String errorMessage) {
log.error("Task runner failed with error {}. Triggered from {}. Monerod={}" , errorMessage, source, trade.getXmrWalletService().getConnectionsService().getConnection());
log.error("Task runner failed with error {}. Triggered from {}. Monerod={}" , errorMessage, source, trade.getXmrWalletService().getConnectionService().getConnection());
if (message != null) {
sendAckMessage(ackReceiver, message, false, errorMessage);

View file

@ -215,10 +215,6 @@ public class XmrWalletService {
return accountService.getPassword() != null;
}
public boolean isWalletSynced() {
return downloadPercentageProperty().get() == 1d;
}
public ReadOnlyDoubleProperty downloadPercentageProperty() {
return downloadListener.percentageProperty();
}
@ -226,16 +222,28 @@ public class XmrWalletService {
private void doneDownload() {
downloadListener.doneDownload();
}
public boolean isDownloadComplete() {
return downloadPercentageProperty().get() == 1d;
}
public LongProperty walletHeightProperty() {
return walletHeight;
}
public boolean isSyncedWithinTolerance() {
if (!xmrConnectionService.isSyncedWithinTolerance()) return false;
Long targetHeight = xmrConnectionService.getTargetHeight();
if (targetHeight == null) return false;
if (targetHeight - walletHeight.get() <= 3) return true; // synced if within 3 blocks of target height
return false;
}
public MoneroDaemonRpc getDaemon() {
return xmrConnectionService.getDaemon();
}
public XmrConnectionService getConnectionsService() {
public XmrConnectionService getConnectionService() {
return xmrConnectionService;
}
@ -721,6 +729,7 @@ public class XmrWalletService {
log.info("Syncing main wallet");
long time = System.currentTimeMillis();
wallet.sync(); // blocking
walletHeight.set(wallet.getHeight());
wasWalletSynced = true;
log.info("Done syncing main wallet in " + (System.currentTimeMillis() - time) + " ms");
wallet.startSyncing(xmrConnectionService.getRefreshPeriodMs());