Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with missing persistence for trade state #4816

Merged
1 change: 1 addition & 0 deletions core/src/main/java/bisq/core/app/WalletAppSetup.java
Expand Up @@ -247,6 +247,7 @@ void setRejectedTxErrorMessageHandler(Consumer<String> rejectedTxErrorMessageHan
String finalDetails = details;
UserThread.runAfter(() -> {
trade.setErrorMessage(newValue.getMessage());
tradeManager.requestPersistence();
if (rejectedTxErrorMessageHandler != null) {
rejectedTxErrorMessageHandler.accept(Res.get("popup.warning.trade.txRejected",
finalDetails, trade.getShortId(), txId));
Expand Down
Expand Up @@ -395,6 +395,7 @@ protected void onPeerOpenedDisputeMessage(PeerOpenedDisputeMessage peerOpenedDis
if (!storedDisputeOptional.isPresent()) {
disputeList.add(dispute);
trade.setDisputeState(getDisputeStateStartedByPeer());
tradeManager.requestPersistence();
errorMessage = null;
} else {
// valid case if both have opened a dispute and agent was not online.
Expand Down
Expand Up @@ -207,6 +207,7 @@ public void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
tradeManager.requestPersistence();

trade.setDisputeState(Trade.DisputeState.MEDIATION_CLOSED);
tradeManager.requestPersistence();
}
} else {
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOfferById(tradeId);
Expand Down Expand Up @@ -243,6 +244,7 @@ public void onAcceptMediationResult(Trade trade,
DisputeProtocol tradeProtocol = (DisputeProtocol) tradeManager.getTradeProtocol(trade);

trade.setMediationResultState(MediationResultState.MEDIATION_RESULT_ACCEPTED);
tradeManager.requestPersistence();

// If we have not got yet the peers signature we sign and send to the peer our signature.
// Otherwise we sign and complete with the peers signature the payout tx.
Expand All @@ -265,5 +267,6 @@ public void onAcceptMediationResult(Trade trade,

public void rejectMediationResult(Trade trade) {
trade.setMediationResultState(MediationResultState.MEDIATION_RESULT_REJECTED);
tradeManager.requestPersistence();
}
}
Expand Up @@ -205,6 +205,7 @@ public void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
if (trade.getDisputeState() == Trade.DisputeState.REFUND_REQUESTED ||
trade.getDisputeState() == Trade.DisputeState.REFUND_REQUEST_STARTED_BY_PEER) {
trade.setDisputeState(Trade.DisputeState.REFUND_REQUEST_CLOSED);
tradeManager.requestPersistence();
}
} else {
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOfferById(tradeId);
Expand Down
Expand Up @@ -164,5 +164,7 @@ public void addSystemMsg(Trade trade) {
trade.getDate().getTime());
chatMessage.setSystemMessage(true);
trade.getChatMessages().add(chatMessage);

requestPersistence();
}
}
7 changes: 3 additions & 4 deletions core/src/main/java/bisq/core/trade/Trade.java
Expand Up @@ -700,10 +700,6 @@ public void addAndPersistChatMessage(ChatMessage chatMessage) {
}
}

public void appendErrorMessage(String msg) {
errorMessage = errorMessage == null ? msg : errorMessage + "\n" + msg;
}

public boolean mediationResultAppliedPenaltyToSeller() {
// If mediated payout is same or more then normal payout we enable otherwise a penalty was applied
// by mediators and we keep the confirm disabled to avoid that the seller can complete the trade
Expand Down Expand Up @@ -1099,6 +1095,9 @@ public void onFailure(@NotNull Throwable t) {
private void setConfirmedState() {
// we only apply the state if we are not already further in the process
if (!isDepositConfirmed()) {
// As setState is called here from the trade itself we cannot trigger a requestPersistence call.
// But as we get setupConfidenceListener called at startup anyway there is no issue if it would not be
// persisted in case the shutdown routine did not persist the trade.
setState(State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN);
}
}
Expand Down
9 changes: 7 additions & 2 deletions core/src/main/java/bisq/core/trade/TradeManager.java
Expand Up @@ -342,11 +342,13 @@ private void initPersistedTrades() {
private void initPersistedTrade(Trade trade) {
initTradeAndProtocol(trade, getTradeProtocol(trade));
trade.updateDepositTxFromWallet();
requestPersistence();
}

private void initTradeAndProtocol(Trade trade, TradeProtocol tradeProtocol) {
tradeProtocol.initialize(processModelServiceProvider, this, trade.getOffer());
trade.initialize(processModelServiceProvider);
requestPersistence();
}

public void requestPersistence() {
Expand Down Expand Up @@ -544,10 +546,13 @@ private void updateTradePeriodState() {
Date halfTradePeriodDate = trade.getHalfTradePeriodDate();
if (maxTradePeriodDate != null && halfTradePeriodDate != null) {
Date now = new Date();
if (now.after(maxTradePeriodDate))
if (now.after(maxTradePeriodDate)) {
trade.setTradePeriodState(Trade.TradePeriodState.TRADE_PERIOD_OVER);
else if (now.after(halfTradePeriodDate))
requestPersistence();
} else if (now.after(halfTradePeriodDate)) {
trade.setTradePeriodState(Trade.TradePeriodState.SECOND_HALF);
requestPersistence();
}
}
}
});
Expand Down
Expand Up @@ -147,7 +147,10 @@ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler er
errorMessageHandler.handleErrorMessage(errorMessage);
handleTaskRunnerFault(event, errorMessage);
})))
.run(() -> trade.setState(Trade.State.BUYER_CONFIRMED_IN_UI_FIAT_PAYMENT_INITIATED))
.run(() -> {
trade.setState(Trade.State.BUYER_CONFIRMED_IN_UI_FIAT_PAYMENT_INITIATED);
processModel.getTradeManager().requestPersistence();
})
.executeTasks();
}

Expand Down
Expand Up @@ -141,7 +141,10 @@ public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler e
errorMessageHandler.handleErrorMessage(errorMessage);
handleTaskRunnerFault(event, errorMessage);
})))
.run(() -> trade.setState(Trade.State.SELLER_CONFIRMED_IN_UI_FIAT_PAYMENT_RECEIPT))
.run(() -> {
trade.setState(Trade.State.SELLER_CONFIRMED_IN_UI_FIAT_PAYMENT_RECEIPT);
processModel.getTradeManager().requestPersistence();
})
.executeTasks();
}

Expand Down
Expand Up @@ -297,6 +297,8 @@ protected void startTimeout(long timeoutSec) {
log.error("Timeout reached. TradeID={}, state={}, timeoutSec={}",
trade.getId(), trade.stateProperty().get(), timeoutSec);
trade.setErrorMessage("Timeout reached. Protocol did not complete in " + timeoutSec + " sec.");

processModel.getTradeManager().requestPersistence();
cleanup();
}, timeoutSec);
}
Expand Down
Expand Up @@ -52,6 +52,8 @@ protected void run() {
Transaction delayedPayoutTx = checkNotNull(trade.getDelayedPayoutTx());
WalletService.maybeAddSelfTxToWallet(delayedPayoutTx, processModel.getBtcWalletService().getWallet());

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -91,6 +91,7 @@ private void applyConfidence(TransactionConfidence confidence) {
if (trade.getPayoutTx() == null) {
Transaction walletTx = processModel.getTradeWalletService().getWalletTx(confidence.getTransactionHash());
trade.setPayoutTx(walletTx);
processModel.getTradeManager().requestPersistence();
BtcWalletService.printTx("payoutTx received from network", walletTx);
setState();
} else {
Expand Down
Expand Up @@ -40,13 +40,17 @@ protected TradeTask(TaskRunner<Trade> taskHandler, Trade trade) {
@Override
protected void failed() {
trade.setErrorMessage(errorMessage);
processModel.getTradeManager().requestPersistence();

super.failed();
}

@Override
protected void failed(String message) {
appendToErrorMessage(message);
trade.setErrorMessage(errorMessage);
processModel.getTradeManager().requestPersistence();

super.failed();
}

Expand All @@ -55,6 +59,8 @@ protected void failed(Throwable t) {
t.printStackTrace();
appendExceptionToErrorMessage(t);
trade.setErrorMessage(errorMessage);
processModel.getTradeManager().requestPersistence();

super.failed();
}
}
Expand Up @@ -54,6 +54,8 @@ protected void run() {

trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -73,6 +73,8 @@ protected void run() {
processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(),
AddressEntry.Context.RESERVED_FOR_TRADE);

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -73,6 +73,8 @@ protected void run() {
processModel.getAccountAgeWitnessService().publishOwnSignedWitness(signedWitness);
}

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -83,11 +83,15 @@ protected TradeMessage getMessage(String tradeId) {
@Override
protected void setStateSent() {
trade.setStateIfValidTransitionTo(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);

processModel.getTradeManager().requestPersistence();
}

@Override
protected void setStateArrived() {
trade.setStateIfValidTransitionTo(Trade.State.BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG);

processModel.getTradeManager().requestPersistence();
cleanup();
// Complete is called in base class
}
Expand All @@ -104,6 +108,7 @@ protected void setStateStoredInMailbox() {
if (!trade.isPayoutPublished()) {
tryToSendAgainLater();
}
processModel.getTradeManager().requestPersistence();
}

// We override the default behaviour for onFault and do not call appendToErrorMessage and failed
Expand All @@ -118,6 +123,7 @@ protected void setStateFault() {
if (!trade.isPayoutPublished()) {
tryToSendAgainLater();
}
processModel.getTradeManager().requestPersistence();
}

@Override
Expand Down Expand Up @@ -173,6 +179,9 @@ private void onMessageStateChange(MessageState newValue) {
if (newValue == MessageState.ACKNOWLEDGED) {
// We treat a ACK like BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG
trade.setStateIfValidTransitionTo(Trade.State.BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG);

processModel.getTradeManager().requestPersistence();

cleanup();
complete();
}
Expand Down
Expand Up @@ -100,6 +100,8 @@ private void applyConfidence(TransactionConfidence confidence) {
// We don't want to trigger the tradeStateSubscription when setting the state, so we unsubscribe before
unSubscribeAndRemoveListener();
trade.setState(Trade.State.BUYER_SAW_DEPOSIT_TX_IN_NETWORK);

processModel.getTradeManager().requestPersistence();
} else {
unSubscribeAndRemoveListener();
}
Expand Down
Expand Up @@ -45,5 +45,7 @@ protected void run() {
@Override
protected void setState() {
trade.setStateIfValidTransitionTo(Trade.State.BUYER_SAW_PAYOUT_TX_IN_NETWORK);

processModel.getTradeManager().requestPersistence();
}
}
Expand Up @@ -88,6 +88,8 @@ protected void run() {
sellerMultiSigPubKey);
processModel.setDepositTx(depositTx);

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -95,6 +95,8 @@ protected void run() {

processModel.setMyMultiSigPubKey(makerMultiSigPubKey);

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -89,7 +89,7 @@ protected void run() {
trade.getLockTime());

trade.setState(Trade.State.MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST);

processModel.getTradeManager().requestPersistence();
NodeAddress peersNodeAddress = trade.getTradingPeerNodeAddress();
log.info("Send {} to peer {}. tradeId={}, uid={}",
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
Expand All @@ -103,6 +103,7 @@ public void onArrived() {
log.info("{} arrived at peer {}. tradeId={}, uid={}",
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
trade.setState(Trade.State.MAKER_SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST);
processModel.getTradeManager().requestPersistence();
complete();
}

Expand All @@ -112,6 +113,7 @@ public void onFault(String errorMessage) {
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid(), errorMessage);
trade.setState(Trade.State.MAKER_SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST);
appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
processModel.getTradeManager().requestPersistence();
failed(errorMessage);
}
}
Expand Down
Expand Up @@ -47,6 +47,8 @@ protected void run() {
log.info("lockTime={}, delay={}", lockTime, delay);
trade.setLockTime(lockTime);

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -45,5 +45,6 @@ protected void run() {
@Override
protected void setState() {
trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED);
processModel.getTradeManager().requestPersistence();
}
}
Expand Up @@ -108,6 +108,8 @@ protected void run() {

trade.setPayoutTx(transaction);

processModel.getTradeManager().requestPersistence();

walletService.swapTradeEntryToAvailableEntry(tradeId, AddressEntry.Context.MULTI_SIG);

complete();
Expand Down
Expand Up @@ -51,6 +51,8 @@ protected void run() {

trade.setMediationResultState(MediationResultState.RECEIVED_SIG_MSG);

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -74,6 +74,9 @@ protected void run() {
} else {
log.info("We got the payout tx already set from BuyerSetupPayoutTxListener and do nothing here. trade ID={}", trade.getId());
}

processModel.getTradeManager().requestPersistence();

complete();
} catch (Throwable t) {
failed(t);
Expand Down
Expand Up @@ -60,6 +60,7 @@ protected void run() {
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());

trade.setMediationResultState(MediationResultState.SIG_MSG_SENT);
processModel.getTradeManager().requestPersistence();
p2PService.sendEncryptedMailboxMessage(peersNodeAddress,
peersPubKeyRing,
message,
Expand All @@ -70,6 +71,7 @@ public void onArrived() {
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());

trade.setMediationResultState(MediationResultState.SIG_MSG_ARRIVED);
processModel.getTradeManager().requestPersistence();
complete();
}

Expand All @@ -79,6 +81,7 @@ public void onStoredInMailbox() {
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());

trade.setMediationResultState(MediationResultState.SIG_MSG_IN_MAILBOX);
processModel.getTradeManager().requestPersistence();
complete();
}

Expand All @@ -88,6 +91,7 @@ public void onFault(String errorMessage) {
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid(), errorMessage);
trade.setMediationResultState(MediationResultState.SIG_MSG_SEND_FAILED);
appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
processModel.getTradeManager().requestPersistence();
failed(errorMessage);
}
}
Expand Down