Warn at shutdown if Dispute message is pending.

This commit is contained in:
jmacxx 2022-10-11 17:54:07 -05:00
parent f7f78a1624
commit b35e316cdc
No known key found for this signature in database
GPG Key ID: 155297BABFE94A1B
3 changed files with 59 additions and 1 deletions

View File

@ -95,6 +95,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
private final Config config;
private final PriceFeedService priceFeedService;
protected final DaoFacade daoFacade;
protected String pendingOutgoingMessage;
@Getter
protected final ObservableList<TradeDataValidation.ValidationException> validationExceptions =
@ -132,6 +133,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
this.disputeListService = disputeListService;
this.config = config;
this.priceFeedService = priceFeedService;
clearPendingMessage();
}
@ -502,6 +504,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
openNewDisputeMessage.getUid(),
chatMessage.getUid());
recordPendingMessage(openNewDisputeMessage.getClass().getSimpleName());
mailboxMessageService.sendEncryptedMailboxMessage(agentNodeAddress,
dispute.getAgentPubKeyRing(),
openNewDisputeMessage,
@ -514,6 +517,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
openNewDisputeMessage.getTradeId(), openNewDisputeMessage.getUid(),
chatMessage.getUid());
clearPendingMessage();
// We use the chatMessage wrapped inside the openNewDisputeMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setArrived(true);
@ -529,6 +533,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
openNewDisputeMessage.getTradeId(), openNewDisputeMessage.getUid(),
chatMessage.getUid());
clearPendingMessage();
// We use the chatMessage wrapped inside the openNewDisputeMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setStoredInMailbox(true);
@ -544,6 +549,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
openNewDisputeMessage.getTradeId(), openNewDisputeMessage.getUid(),
chatMessage.getUid(), errorMessage);
clearPendingMessage();
// We use the chatMessage wrapped inside the openNewDisputeMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setSendMessageError(errorMessage);
@ -650,6 +656,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
chatMessage.getUid());
recordPendingMessage(peerOpenedDisputeMessage.getClass().getSimpleName());
mailboxMessageService.sendEncryptedMailboxMessage(peersNodeAddress,
peersPubKeyRing,
peerOpenedDisputeMessage,
@ -662,6 +669,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
chatMessage.getUid());
clearPendingMessage();
// We use the chatMessage wrapped inside the peerOpenedDisputeMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setArrived(true);
@ -676,6 +684,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
chatMessage.getUid());
clearPendingMessage();
// We use the chatMessage wrapped inside the peerOpenedDisputeMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setStoredInMailbox(true);
@ -690,6 +699,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
chatMessage.getUid(), errorMessage);
clearPendingMessage();
// We use the chatMessage wrapped inside the peerOpenedDisputeMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setSendMessageError(errorMessage);
@ -732,6 +742,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
log.info("Send {} to peer {}. tradeId={}, disputeResultMessage.uid={}, chatMessage.uid={}",
disputeResultMessage.getClass().getSimpleName(), peersNodeAddress, disputeResultMessage.getTradeId(),
disputeResultMessage.getUid(), chatMessage.getUid());
recordPendingMessage(disputeResultMessage.getClass().getSimpleName());
mailboxMessageService.sendEncryptedMailboxMessage(peersNodeAddress,
dispute.getTraderPubKeyRing(),
disputeResultMessage,
@ -744,6 +755,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
disputeResultMessage.getTradeId(), disputeResultMessage.getUid(),
chatMessage.getUid());
clearPendingMessage();
// We use the chatMessage wrapped inside the disputeResultMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setArrived(true);
@ -758,6 +770,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
disputeResultMessage.getTradeId(), disputeResultMessage.getUid(),
chatMessage.getUid());
clearPendingMessage();
// We use the chatMessage wrapped inside the disputeResultMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setStoredInMailbox(true);
@ -772,6 +785,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
disputeResultMessage.getTradeId(), disputeResultMessage.getUid(),
chatMessage.getUid(), errorMessage);
clearPendingMessage();
// We use the chatMessage wrapped inside the disputeResultMessage for
// the state, as that is displayed to the user and we only persist that msg
chatMessage.setSendMessageError(errorMessage);
@ -991,4 +1005,19 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
return null;
}
}
public boolean hasPendingMessageAtShutdown() {
if (pendingOutgoingMessage.length() > 0) {
log.warn("{} has an outgoing message pending: {}", this.getClass().getSimpleName(), pendingOutgoingMessage);
return true;
}
return false;
}
private void recordPendingMessage(String className) {
pendingOutgoingMessage = className;
}
private void clearPendingMessage() {
pendingOutgoingMessage = "";
}
}

View File

@ -3127,6 +3127,9 @@ popup.info.shutDownWithOpenOffers=Bisq is being shut down, but there are open of
(i.e., make sure it doesn't go into standby mode...monitor standby is not a problem).
popup.info.shutDownWithTradeInit={0}\n\
This trade has not finished initializing; shutting down now will probably make it corrupted. Please wait a minute and try again.
popup.info.shutDownWithDisputeInit=Bisq is being shut down, but there is a Dispute system message still pending.\n\
Please wait a minute before shutting down.\n\
For further help please contact the Bisq support channel at the Bisq Matrix Space.
popup.info.qubesOSSetupInfo=It appears you are running Bisq on Qubes OS. \n\n\
Please make sure your Bisq qube is setup according to our Setup Guide at [HYPERLINK:https://bisq.wiki/Running_Bisq_on_Qubes].
popup.info.p2pStatusIndicator.red={0}\n\n\

View File

@ -40,6 +40,8 @@ import bisq.core.dao.governance.voteresult.MissingDataRequestService;
import bisq.core.locale.Res;
import bisq.core.offer.OpenOffer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.support.dispute.mediation.MediationManager;
import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.trade.TradeManager;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.core.user.Cookie;
@ -369,7 +371,11 @@ public class BisqApp extends Application implements UncaughtExceptionHandler {
if (shutdownStage1) {
shutDownByUserCheckOffers().thenAccept(shutdownStage2 -> {
if (shutdownStage2) {
stop();
shutDownByUserCheckDisputes().thenAccept(shutdownStage3 -> {
if (shutdownStage3) {
stop();
}
});
}
});
}
@ -377,6 +383,7 @@ public class BisqApp extends Application implements UncaughtExceptionHandler {
}
private CompletableFuture<Boolean> shutDownByUserCheckTrades() {
log.info("Checking trades at shutdown");
final CompletableFuture<Boolean> asyncStatus = new CompletableFuture<>();
Instant fiveMinutesAgo = Instant.ofEpochSecond(Instant.now().getEpochSecond() - TimeUnit.MINUTES.toSeconds(5));
String tradeIdsWithOperationsPending = "";
@ -404,6 +411,7 @@ public class BisqApp extends Application implements UncaughtExceptionHandler {
}
private CompletableFuture<Boolean> shutDownByUserCheckOffers() {
log.info("Checking offers at shutdown");
final CompletableFuture<Boolean> asyncStatus = new CompletableFuture<>();
boolean hasOpenOffers = false;
for (OpenOffer openOffer : injector.getInstance(OpenOfferManager.class).getObservableList()) {
@ -434,6 +442,24 @@ public class BisqApp extends Application implements UncaughtExceptionHandler {
return asyncStatus;
}
private CompletableFuture<Boolean> shutDownByUserCheckDisputes() {
log.info("Checking disputes at shutdown");
final CompletableFuture<Boolean> asyncStatus = new CompletableFuture<>();
if (injector.getInstance(MediationManager.class).hasPendingMessageAtShutdown() ||
injector.getInstance(RefundManager.class).hasPendingMessageAtShutdown()) {
// We show a popup to inform user that some messages are still being sent.
new Popup().warning(Res.get("popup.info.shutDownWithDisputeInit"))
.actionButtonText(Res.get("shared.okWait"))
.onAction(() -> asyncStatus.complete(false))
.closeButtonText(Res.get("shared.closeAnywayDanger"))
.onClose(() -> asyncStatus.complete(true))
.show();
} else {
asyncStatus.complete(true);
}
return asyncStatus;
}
// Used for debugging trade process
private void showDebugWindow(Scene scene, Injector injector) {
ViewLoader viewLoader = injector.getInstance(ViewLoader.class);