From 6fc36d48dbec360ad6d0b622a579af46f6753361 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 17 Nov 2020 19:15:59 -0500 Subject: [PATCH 01/10] Reduce interval for persistence Seems the persistence at shutdown is too unsafe and we got bug reports where data was missing. https://github.com/bisq-network/bisq/issues/4806 Use millisec instead of sec for delay Rename delayInSec to delay --- .../common/persistence/PersistenceManager.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/bisq/common/persistence/PersistenceManager.java b/common/src/main/java/bisq/common/persistence/PersistenceManager.java index 2f3c74f3e47..214b6b8768b 100644 --- a/common/src/main/java/bisq/common/persistence/PersistenceManager.java +++ b/common/src/main/java/bisq/common/persistence/PersistenceManager.java @@ -143,25 +143,25 @@ private static void onWriteCompleted(ResultHandler completeHandler, public enum Source { // For data stores we received from the network and which could be rebuilt. We store only for avoiding too much network traffic. - NETWORK(1, TimeUnit.HOURS.toSeconds(1), false), + NETWORK(1, TimeUnit.MINUTES.toMillis(5), false), // For data stores which are created from private local data. This data could only be rebuilt from backup files. - PRIVATE(10, TimeUnit.SECONDS.toSeconds(30), true), + PRIVATE(10, 200, true), - // For data stores which are created from private local data. Loss of that data would not have any critical consequences. - PRIVATE_LOW_PRIO(4, TimeUnit.HOURS.toSeconds(2), false); + // For data stores which are created from private local data. Loss of that data would not have critical consequences. + PRIVATE_LOW_PRIO(4, TimeUnit.MINUTES.toMillis(1), false); @Getter private final int numMaxBackupFiles; @Getter - private final long delayInSec; + private final long delay; @Getter private final boolean flushAtShutDown; - Source(int numMaxBackupFiles, long delayInSec, boolean flushAtShutDown) { + Source(int numMaxBackupFiles, long delay, boolean flushAtShutDown) { this.numMaxBackupFiles = numMaxBackupFiles; - this.delayInSec = delayInSec; + this.delay = delay; this.flushAtShutDown = flushAtShutDown; } } @@ -352,7 +352,7 @@ public void requestPersistence() { timer = UserThread.runAfter(() -> { persistNow(null); UserThread.execute(() -> timer = null); - }, source.delayInSec, TimeUnit.SECONDS); + }, source.delay, TimeUnit.MILLISECONDS); } } @@ -454,7 +454,7 @@ public String toString() { ",\n dir=" + dir + ",\n storageFile=" + storageFile + ",\n persistable=" + persistable + - ",\n priority=" + source + + ",\n source=" + source + ",\n usedTempFilePath=" + usedTempFilePath + ",\n persistenceRequested=" + persistenceRequested + "\n}"; From fa0c28adf6933a86adabf0f8db52e5e2632276a8 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 17 Nov 2020 22:35:51 -0500 Subject: [PATCH 02/10] Add requestPersistence calls We relied on the shutdwon routine to be called reliably but it seems that is not the case as some bug reports show. So we call requestPersistence at every write access of the trade object --- core/src/main/java/bisq/core/app/WalletAppSetup.java | 1 + .../java/bisq/core/support/dispute/DisputeManager.java | 1 + .../support/dispute/mediation/MediationManager.java | 3 +++ .../core/support/dispute/refund/RefundManager.java | 1 + .../core/support/traderchat/TraderChatManager.java | 2 ++ core/src/main/java/bisq/core/trade/Trade.java | 7 +++---- core/src/main/java/bisq/core/trade/TradeManager.java | 9 +++++++-- .../java/bisq/core/trade/protocol/BuyerProtocol.java | 5 ++++- .../java/bisq/core/trade/protocol/SellerProtocol.java | 5 ++++- .../java/bisq/core/trade/protocol/TradeProtocol.java | 2 ++ .../ProcessPeerPublishedDelayedPayoutTxMessage.java | 2 ++ .../trade/protocol/tasks/SetupPayoutTxListener.java | 1 + .../java/bisq/core/trade/protocol/tasks/TradeTask.java | 6 ++++++ .../BuyerProcessDelayedPayoutTxSignatureRequest.java | 2 ++ ...BuyerProcessDepositTxAndDelayedPayoutTxMessage.java | 2 ++ .../buyer/BuyerProcessPayoutTxPublishedMessage.java | 2 ++ ...BuyerSendCounterCurrencyTransferStartedMessage.java | 9 +++++++++ .../tasks/buyer/BuyerSetupDepositTxListener.java | 2 ++ .../tasks/buyer/BuyerSetupPayoutTxListener.java | 2 ++ .../buyer_as_taker/BuyerAsTakerSignsDepositTx.java | 2 ++ .../tasks/maker/MakerCreateAndSignContract.java | 2 ++ .../maker/MakerSendsInputsForDepositTxResponse.java | 4 +++- .../trade/protocol/tasks/maker/MakerSetsLockTime.java | 2 ++ .../tasks/mediation/BroadcastMediatedPayoutTx.java | 1 + .../tasks/mediation/FinalizeMediatedPayoutTx.java | 2 ++ .../ProcessMediatedPayoutSignatureMessage.java | 2 ++ .../ProcessMediatedPayoutTxPublishedMessage.java | 3 +++ .../mediation/SendMediatedPayoutSignatureMessage.java | 4 ++++ .../SendMediatedPayoutTxPublishedMessage.java | 4 ++++ .../tasks/mediation/SetupMediatedPayoutTxListener.java | 1 + .../protocol/tasks/seller/SellerBroadcastPayoutTx.java | 1 + .../tasks/seller/SellerFinalizesDelayedPayoutTx.java | 2 ++ ...erProcessCounterCurrencyTransferStartedMessage.java | 2 ++ .../SellerProcessDelayedPayoutTxSignatureResponse.java | 2 ++ .../tasks/seller/SellerPublishesDepositTx.java | 2 ++ .../seller/SellerSendPayoutTxPublishedMessage.java | 4 ++++ .../SellerSendsDepositTxAndDelayedPayoutTxMessage.java | 10 ++++++++++ .../tasks/seller/SellerSignAndFinalizePayoutTx.java | 2 ++ .../SellerAsMakerCreatesUnsignedDepositTx.java | 2 ++ .../SellerAsMakerProcessDepositTxMessage.java | 2 ++ .../TakerProcessesInputsForDepositTxResponse.java | 2 ++ .../trade/protocol/tasks/taker/TakerPublishFeeTx.java | 3 +++ .../tasks/taker/TakerVerifyAndSignContract.java | 2 ++ .../pendingtrades/PendingTradesDataModel.java | 2 +- .../portfolio/pendingtrades/PendingTradesView.java | 1 + .../pendingtrades/steps/buyer/BuyerStep2View.java | 3 +++ 46 files changed, 123 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/bisq/core/app/WalletAppSetup.java b/core/src/main/java/bisq/core/app/WalletAppSetup.java index 61433278e10..5f0b4522560 100644 --- a/core/src/main/java/bisq/core/app/WalletAppSetup.java +++ b/core/src/main/java/bisq/core/app/WalletAppSetup.java @@ -247,6 +247,7 @@ void setRejectedTxErrorMessageHandler(Consumer 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)); diff --git a/core/src/main/java/bisq/core/support/dispute/DisputeManager.java b/core/src/main/java/bisq/core/support/dispute/DisputeManager.java index 45fc43f35e1..46a5c464b97 100644 --- a/core/src/main/java/bisq/core/support/dispute/DisputeManager.java +++ b/core/src/main/java/bisq/core/support/dispute/DisputeManager.java @@ -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. diff --git a/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java b/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java index e0a20e08da1..67042717e68 100644 --- a/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java +++ b/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java @@ -207,6 +207,7 @@ public void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) { tradeManager.requestPersistence(); trade.setDisputeState(Trade.DisputeState.MEDIATION_CLOSED); + tradeManager.requestPersistence(); } } else { Optional openOfferOptional = openOfferManager.getOpenOfferById(tradeId); @@ -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. @@ -265,5 +267,6 @@ public void onAcceptMediationResult(Trade trade, public void rejectMediationResult(Trade trade) { trade.setMediationResultState(MediationResultState.MEDIATION_RESULT_REJECTED); + tradeManager.requestPersistence(); } } diff --git a/core/src/main/java/bisq/core/support/dispute/refund/RefundManager.java b/core/src/main/java/bisq/core/support/dispute/refund/RefundManager.java index e7919346f3e..1cff45dbdcf 100644 --- a/core/src/main/java/bisq/core/support/dispute/refund/RefundManager.java +++ b/core/src/main/java/bisq/core/support/dispute/refund/RefundManager.java @@ -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 openOfferOptional = openOfferManager.getOpenOfferById(tradeId); diff --git a/core/src/main/java/bisq/core/support/traderchat/TraderChatManager.java b/core/src/main/java/bisq/core/support/traderchat/TraderChatManager.java index ef4a0157e00..bf7f353200d 100644 --- a/core/src/main/java/bisq/core/support/traderchat/TraderChatManager.java +++ b/core/src/main/java/bisq/core/support/traderchat/TraderChatManager.java @@ -164,5 +164,7 @@ public void addSystemMsg(Trade trade) { trade.getDate().getTime()); chatMessage.setSystemMessage(true); trade.getChatMessages().add(chatMessage); + + requestPersistence(); } } diff --git a/core/src/main/java/bisq/core/trade/Trade.java b/core/src/main/java/bisq/core/trade/Trade.java index a6f2d56ab99..ba503622629 100644 --- a/core/src/main/java/bisq/core/trade/Trade.java +++ b/core/src/main/java/bisq/core/trade/Trade.java @@ -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 @@ -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); } } diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index fa1af34b555..ed6cac4ea1c 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -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() { @@ -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(); + } } } }); diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java index ffff35a79bb..1fee12e22be 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java @@ -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(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java index dd138fc0f9b..c36b6c04178 100644 --- a/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java @@ -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(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java index 505eca1efd7..d72ac1c3771 100644 --- a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java @@ -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); } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/ProcessPeerPublishedDelayedPayoutTxMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/ProcessPeerPublishedDelayedPayoutTxMessage.java index a104b433b8e..aab0bb5a3b9 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/ProcessPeerPublishedDelayedPayoutTxMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/ProcessPeerPublishedDelayedPayoutTxMessage.java @@ -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); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/SetupPayoutTxListener.java b/core/src/main/java/bisq/core/trade/protocol/tasks/SetupPayoutTxListener.java index bc6502a4c8b..3c264335535 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/SetupPayoutTxListener.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/SetupPayoutTxListener.java @@ -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 { diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java b/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java index f7aeeaeaa9a..2f50603eff4 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java @@ -40,6 +40,8 @@ protected TradeTask(TaskRunner taskHandler, Trade trade) { @Override protected void failed() { trade.setErrorMessage(errorMessage); + processModel.getTradeManager().requestPersistence(); + super.failed(); } @@ -47,6 +49,8 @@ protected void failed() { protected void failed(String message) { appendToErrorMessage(message); trade.setErrorMessage(errorMessage); + processModel.getTradeManager().requestPersistence(); + super.failed(); } @@ -55,6 +59,8 @@ protected void failed(Throwable t) { t.printStackTrace(); appendExceptionToErrorMessage(t); trade.setErrorMessage(errorMessage); + processModel.getTradeManager().requestPersistence(); + super.failed(); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDelayedPayoutTxSignatureRequest.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDelayedPayoutTxSignatureRequest.java index 806b90b05ef..5bfc9157048 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDelayedPayoutTxSignatureRequest.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDelayedPayoutTxSignatureRequest.java @@ -54,6 +54,8 @@ protected void run() { trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress()); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDepositTxAndDelayedPayoutTxMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDepositTxAndDelayedPayoutTxMessage.java index dfecf3abde9..413000c1a2e 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDepositTxAndDelayedPayoutTxMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessDepositTxAndDelayedPayoutTxMessage.java @@ -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); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java index 45cd777a217..71c250b7b91 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java @@ -73,6 +73,8 @@ protected void run() { processModel.getAccountAgeWitnessService().publishOwnSignedWitness(signedWitness); } + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSendCounterCurrencyTransferStartedMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSendCounterCurrencyTransferStartedMessage.java index 5fd30322122..54a334c6d46 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSendCounterCurrencyTransferStartedMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSendCounterCurrencyTransferStartedMessage.java @@ -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 } @@ -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 @@ -118,6 +123,7 @@ protected void setStateFault() { if (!trade.isPayoutPublished()) { tryToSendAgainLater(); } + processModel.getTradeManager().requestPersistence(); } @Override @@ -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(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java index 32a4506efa4..f78156ef5e0 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java @@ -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(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java index 8f06c187bae..c58ce41ef16 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java @@ -45,5 +45,7 @@ protected void run() { @Override protected void setState() { trade.setStateIfValidTransitionTo(Trade.State.BUYER_SAW_PAYOUT_TX_IN_NETWORK); + + processModel.getTradeManager().requestPersistence(); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignsDepositTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignsDepositTx.java index 1ad8d8da534..24f988120da 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignsDepositTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignsDepositTx.java @@ -88,6 +88,8 @@ protected void run() { sellerMultiSigPubKey); processModel.setDepositTx(depositTx); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerCreateAndSignContract.java b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerCreateAndSignContract.java index ebc2ee2d9a0..4c9d05c4c3f 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerCreateAndSignContract.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerCreateAndSignContract.java @@ -95,6 +95,8 @@ protected void run() { processModel.setMyMultiSigPubKey(makerMultiSigPubKey); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSendsInputsForDepositTxResponse.java b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSendsInputsForDepositTxResponse.java index 8831d8eab00..34380f5bcf6 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSendsInputsForDepositTxResponse.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSendsInputsForDepositTxResponse.java @@ -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()); @@ -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(); } @@ -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); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSetsLockTime.java b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSetsLockTime.java index 3e55cee4813..fde4359becd 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSetsLockTime.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerSetsLockTime.java @@ -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); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/BroadcastMediatedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/BroadcastMediatedPayoutTx.java index 7d67edc7d52..7ebfa20ce53 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/BroadcastMediatedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/BroadcastMediatedPayoutTx.java @@ -45,5 +45,6 @@ protected void run() { @Override protected void setState() { trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED); + processModel.getTradeManager().requestPersistence(); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/FinalizeMediatedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/FinalizeMediatedPayoutTx.java index b9e43a84279..87a8bdf32e4 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/FinalizeMediatedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/FinalizeMediatedPayoutTx.java @@ -108,6 +108,8 @@ protected void run() { trade.setPayoutTx(transaction); + processModel.getTradeManager().requestPersistence(); + walletService.swapTradeEntryToAvailableEntry(tradeId, AddressEntry.Context.MULTI_SIG); complete(); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutSignatureMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutSignatureMessage.java index ea1a02a02a2..ba0aad72043 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutSignatureMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutSignatureMessage.java @@ -51,6 +51,8 @@ protected void run() { trade.setMediationResultState(MediationResultState.RECEIVED_SIG_MSG); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutTxPublishedMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutTxPublishedMessage.java index 226fefbb5af..8e5b08a068e 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutTxPublishedMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/ProcessMediatedPayoutTxPublishedMessage.java @@ -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); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutSignatureMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutSignatureMessage.java index e897027119b..22bc9f93b14 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutSignatureMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutSignatureMessage.java @@ -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, @@ -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(); } @@ -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(); } @@ -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); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutTxPublishedMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutTxPublishedMessage.java index 8cadcbeaece..c4c4287920c 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutTxPublishedMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SendMediatedPayoutTxPublishedMessage.java @@ -54,21 +54,25 @@ protected TradeMessage getMessage(String id) { @Override protected void setStateSent() { trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED_MSG_SENT); + processModel.getTradeManager().requestPersistence(); } @Override protected void setStateArrived() { trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED_MSG_ARRIVED); + processModel.getTradeManager().requestPersistence(); } @Override protected void setStateStoredInMailbox() { trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED_MSG_IN_MAILBOX); + processModel.getTradeManager().requestPersistence(); } @Override protected void setStateFault() { trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED_MSG_SEND_FAILED); + processModel.getTradeManager().requestPersistence(); } @Override diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SetupMediatedPayoutTxListener.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SetupMediatedPayoutTxListener.java index 8f0ee2b106b..dc0b60b314a 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SetupMediatedPayoutTxListener.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SetupMediatedPayoutTxListener.java @@ -49,5 +49,6 @@ protected void setState() { if (trade.getPayoutTx() != null) { processModel.getTradeManager().closeDisputedTrade(trade.getId(), Trade.DisputeState.MEDIATION_CLOSED); } + processModel.getTradeManager().requestPersistence(); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerBroadcastPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerBroadcastPayoutTx.java index 2ab775d80c1..d0a0f6c20d2 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerBroadcastPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerBroadcastPayoutTx.java @@ -44,5 +44,6 @@ protected void run() { @Override protected void setState() { trade.setState(Trade.State.SELLER_PUBLISHED_PAYOUT_TX); + processModel.getTradeManager().requestPersistence(); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerFinalizesDelayedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerFinalizesDelayedPayoutTx.java index 720c1a9f048..2683e526026 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerFinalizesDelayedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerFinalizesDelayedPayoutTx.java @@ -68,6 +68,8 @@ protected void run() { trade.applyDelayedPayoutTx(signedDelayedPayoutTx); log.info("DelayedPayoutTxBytes = {}", Utilities.bytesAsHexString(trade.getDelayedPayoutTxBytes())); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessCounterCurrencyTransferStartedMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessCounterCurrencyTransferStartedMessage.java index 5f8d6bc50ec..9cbba9b670b 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessCounterCurrencyTransferStartedMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessCounterCurrencyTransferStartedMessage.java @@ -61,6 +61,8 @@ protected void run() { trade.setState(Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessDelayedPayoutTxSignatureResponse.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessDelayedPayoutTxSignatureResponse.java index c47fd0be067..7d32c987617 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessDelayedPayoutTxSignatureResponse.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerProcessDelayedPayoutTxSignatureResponse.java @@ -47,6 +47,8 @@ protected void run() { // update to the latest peer address of our peer if the message is correct trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress()); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerPublishesDepositTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerPublishesDepositTx.java index 1cdc2e43583..1afae6dad39 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerPublishesDepositTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerPublishesDepositTx.java @@ -54,6 +54,8 @@ public void onSuccess(Transaction transaction) { processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(processModel.getOffer().getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + processModel.getTradeManager().requestPersistence(); + complete(); } else { log.warn("We got the onSuccess callback called after the timeout has been triggered a complete()."); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendPayoutTxPublishedMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendPayoutTxPublishedMessage.java index db73f1910a6..a7da42bece2 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendPayoutTxPublishedMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendPayoutTxPublishedMessage.java @@ -65,6 +65,7 @@ protected void setStateSent() { trade.setState(Trade.State.SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG); log.info("Sent PayoutTxPublishedMessage: tradeId={} at peer {} SignedWitness {}", trade.getId(), trade.getTradingPeerNodeAddress(), signedWitness); + processModel.getTradeManager().requestPersistence(); } @Override @@ -72,6 +73,7 @@ protected void setStateArrived() { trade.setState(Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG); log.info("PayoutTxPublishedMessage arrived: tradeId={} at peer {} SignedWitness {}", trade.getId(), trade.getTradingPeerNodeAddress(), signedWitness); + processModel.getTradeManager().requestPersistence(); } @Override @@ -79,6 +81,7 @@ protected void setStateStoredInMailbox() { trade.setState(Trade.State.SELLER_STORED_IN_MAILBOX_PAYOUT_TX_PUBLISHED_MSG); log.info("PayoutTxPublishedMessage storedInMailbox: tradeId={} at peer {} SignedWitness {}", trade.getId(), trade.getTradingPeerNodeAddress(), signedWitness); + processModel.getTradeManager().requestPersistence(); } @Override @@ -86,6 +89,7 @@ protected void setStateFault() { trade.setState(Trade.State.SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG); log.error("PayoutTxPublishedMessage failed: tradeId={} at peer {} SignedWitness {}", trade.getId(), trade.getTradingPeerNodeAddress(), signedWitness); + processModel.getTradeManager().requestPersistence(); } @Override diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendsDepositTxAndDelayedPayoutTxMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendsDepositTxAndDelayedPayoutTxMessage.java index e46a88fcdc1..18768093f7c 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendsDepositTxAndDelayedPayoutTxMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSendsDepositTxAndDelayedPayoutTxMessage.java @@ -76,11 +76,15 @@ protected TradeMessage getMessage(String tradeId) { @Override protected void setStateSent() { trade.setStateIfValidTransitionTo(Trade.State.SELLER_SENT_DEPOSIT_TX_PUBLISHED_MSG); + + processModel.getTradeManager().requestPersistence(); } @Override protected void setStateArrived() { trade.setStateIfValidTransitionTo(Trade.State.SELLER_SAW_ARRIVED_DEPOSIT_TX_PUBLISHED_MSG); + + processModel.getTradeManager().requestPersistence(); cleanup(); // Complete is called in base class } @@ -94,6 +98,8 @@ protected void onStoredInMailbox() { @Override protected void setStateStoredInMailbox() { trade.setStateIfValidTransitionTo(Trade.State.SELLER_STORED_IN_MAILBOX_DEPOSIT_TX_PUBLISHED_MSG); + + processModel.getTradeManager().requestPersistence(); // The DepositTxAndDelayedPayoutTxMessage is a mailbox message as earlier we use only the deposit tx which can // be also received from the network once published. // Now we send the delayed payout tx as well and with that this message is mandatory for continuing the protocol. @@ -119,6 +125,8 @@ protected void setStateFault() { if (!trade.isDepositConfirmed()) { tryToSendAgainLater(); } + + processModel.getTradeManager().requestPersistence(); } @Override @@ -173,6 +181,8 @@ private void onMessageStateChange(MessageState newValue) { if (newValue == MessageState.ACKNOWLEDGED) { // We treat a ACK like SELLER_SAW_ARRIVED_DEPOSIT_TX_PUBLISHED_MSG trade.setStateIfValidTransitionTo(Trade.State.SELLER_SAW_ARRIVED_DEPOSIT_TX_PUBLISHED_MSG); + + processModel.getTradeManager().requestPersistence(); cleanup(); complete(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java index eb5bd3aa99f..34f645896b2 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java @@ -100,6 +100,8 @@ protected void run() { trade.setPayoutTx(transaction); + processModel.getTradeManager().requestPersistence(); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.MULTI_SIG); complete(); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesUnsignedDepositTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesUnsignedDepositTx.java index 5caf031bfe2..121e75e922b 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesUnsignedDepositTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesUnsignedDepositTx.java @@ -103,6 +103,8 @@ protected void run() { processModel.setPreparedDepositTx(result.depositTransaction); processModel.setRawTransactionInputs(result.rawMakerInputs); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerProcessDepositTxMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerProcessDepositTxMessage.java index ea61b2fa506..16227588624 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerProcessDepositTxMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerProcessDepositTxMessage.java @@ -51,6 +51,8 @@ protected void run() { // but that cannot be changed due backward compatibility issues. It is a left over from the old trade protocol. trade.setTakerFeeTxId(processModel.getTakeOfferFeeTxId()); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerProcessesInputsForDepositTxResponse.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerProcessesInputsForDepositTxResponse.java index 1a84e311c4f..11218d6fef4 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerProcessesInputsForDepositTxResponse.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerProcessesInputsForDepositTxResponse.java @@ -83,6 +83,8 @@ protected void run() { // update to the latest peer address of our peer if the message is correct trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress()); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerPublishFeeTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerPublishFeeTx.java index a1c4914a49e..6324f74e000 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerPublishFeeTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerPublishFeeTx.java @@ -110,6 +110,9 @@ protected void onSuccess(@org.jetbrains.annotations.Nullable Transaction transac if (transaction != null) { trade.setTakerFeeTxId(transaction.getTxId().toString()); trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX); + + processModel.getTradeManager().requestPersistence(); + complete(); } } else { diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java index 15fef9aa327..afe14cba205 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java @@ -114,6 +114,8 @@ protected void run() { trade.setContractHash(contractHash); trade.setTakerContractSignature(signature); + + processModel.getTradeManager().requestPersistence(); try { checkNotNull(maker.getPubKeyRing(), "maker.getPubKeyRing() must nto be null"); Sig.verify(maker.getPubKeyRing().getSignaturePubKey(), diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java index bce37344b80..59f33ef27c9 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java @@ -555,6 +555,7 @@ private void doOpenDispute(boolean isSupportTicket, Transaction depositTx) { trade.setDisputeState(Trade.DisputeState.MEDIATION_REQUESTED); sendOpenDisputeMessage(disputeManager, resultHandler, dispute); + tradeManager.requestPersistence(); } else if (useRefundAgent) { resultHandler = () -> navigation.navigateTo(MainView.class, SupportView.class, RefundClientView.class); @@ -630,7 +631,6 @@ private void doOpenDispute(boolean isSupportTicket, Transaction depositTx) { sendOpenDisputeMessage(disputeManager, resultHandler, dispute); }, errorMessage -> new Popup().error(errorMessage).show()); - } else { log.warn("Invalid dispute state {}", disputeState.name()); } diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java index a72ab7ab770..0e5fc23a077 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesView.java @@ -471,6 +471,7 @@ private void openChat(Trade trade) { trade.stateProperty().removeListener(tradeStateListener); trade.disputeStateProperty().addListener(disputeStateListener); trade.mediationResultStateProperty().addListener(mediationResultStateListener); + traderChatManager.requestPersistence(); }); Scene scene = new Scene(pane); diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java index 5e1e6a7018a..7d4ef02925e 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java @@ -472,6 +472,8 @@ private void onPaymentStarted() { trade.setCounterCurrencyExtraData(txKey); trade.setCounterCurrencyTxId(txHash); + + model.dataModel.getTradeManager().requestPersistence(); showConfirmPaymentStartedPopup(); }) .closeButtonText(Res.get("shared.cancel")) @@ -519,6 +521,7 @@ private void confirmPaymentStarted() { //TODO seems this was a hack to enable repeated confirm??? if (trade.isFiatSent()) { trade.setState(Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN); + model.dataModel.getTradeManager().requestPersistence(); } model.dataModel.onPaymentStarted(() -> { From 9517f427b6d9dd2e1a2b019790fc0a7a4494a992 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Wed, 18 Nov 2020 12:12:59 -0500 Subject: [PATCH 03/10] Refactoring: Extract requestPersistence method --- .../bisq/core/trade/closed/ClosedTradableManager.java | 8 ++++++-- .../bisq/core/trade/failed/FailedTradesManager.java | 10 +++++++--- p2p/src/main/java/bisq/network/p2p/P2PService.java | 8 ++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/bisq/core/trade/closed/ClosedTradableManager.java b/core/src/main/java/bisq/core/trade/closed/ClosedTradableManager.java index 11fa2714147..01c36beb4d1 100644 --- a/core/src/main/java/bisq/core/trade/closed/ClosedTradableManager.java +++ b/core/src/main/java/bisq/core/trade/closed/ClosedTradableManager.java @@ -84,13 +84,13 @@ public void onAllServicesInitialized() { public void add(Tradable tradable) { if (closedTradables.add(tradable)) { - persistenceManager.requestPersistence(); + requestPersistence(); } } public void remove(Tradable tradable) { if (closedTradables.remove(tradable)) { - persistenceManager.requestPersistence(); + requestPersistence(); } } @@ -117,4 +117,8 @@ public Stream getTradesStreamWithFundsLockedIn() { return getClosedTrades().stream() .filter(Trade::isFundsLockedIn); } + + private void requestPersistence() { + persistenceManager.requestPersistence(); + } } diff --git a/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java b/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java index 69b2da21530..84746a2128c 100644 --- a/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java +++ b/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java @@ -95,13 +95,13 @@ public void onAllServicesInitialized() { public void add(Trade trade) { if (failedTrades.add(trade)) { - persistenceManager.requestPersistence(); + requestPersistence(); } } public void removeTrade(Trade trade) { if (failedTrades.remove(trade)) { - persistenceManager.requestPersistence(); + requestPersistence(); } } @@ -129,7 +129,7 @@ public void unFailTrade(Trade trade) { if (unFailTradeCallback.apply(trade)) { log.info("Unfailing trade {}", trade.getId()); if (failedTrades.remove(trade)) { - persistenceManager.requestPersistence(); + requestPersistence(); } } } @@ -151,4 +151,8 @@ public String checkUnFail(Trade trade) { } return blockingTrades.toString(); } + + private void requestPersistence() { + persistenceManager.requestPersistence(); + } } diff --git a/p2p/src/main/java/bisq/network/p2p/P2PService.java b/p2p/src/main/java/bisq/network/p2p/P2PService.java index 9b539cfae91..3cb04314dd3 100644 --- a/p2p/src/main/java/bisq/network/p2p/P2PService.java +++ b/p2p/src/main/java/bisq/network/p2p/P2PService.java @@ -536,7 +536,7 @@ private void processMailboxItem(MailboxItem mailboxItem) { mailboxItemsByUid.putIfAbsent(uid, new ArrayList<>()); mailboxItemsByUid.get(uid).add(mailboxItem); mailboxMessageList.add(mailboxItem); - persistenceManager.requestPersistence(); + requestPersistence(); NodeAddress sender = mailboxMessage.getSenderNodeAddress(); log.info("Received a {} mailbox message with uid {} and senderAddress {}", @@ -818,7 +818,7 @@ public void removeMailboxMsg(DecryptedMessageWithPubKey decryptedMessageWithPubK mailboxMessageList.remove(mailboxItem); }); mailboxItemsByUid.remove(uid); - persistenceManager.requestPersistence(); + requestPersistence(); } }); } else { @@ -827,6 +827,10 @@ public void removeMailboxMsg(DecryptedMessageWithPubKey decryptedMessageWithPubK } } + private void requestPersistence() { + persistenceManager.requestPersistence(); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Data storage From 255460e5d502146d420f716737bbaa4de1d84a55 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Wed, 18 Nov 2020 12:38:39 -0500 Subject: [PATCH 04/10] Add more requestPersistence for data changes in ProcessModel and TradingPeer --- .../core/support/dispute/mediation/MediationManager.java | 2 +- core/src/main/java/bisq/core/trade/TradeManager.java | 1 + .../java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java | 6 +++++- .../main/java/bisq/core/trade/protocol/FluentProtocol.java | 2 ++ .../main/java/bisq/core/trade/protocol/ProcessModel.java | 2 ++ .../bisq/core/trade/protocol/SellerAsTakerProtocol.java | 1 + .../core/trade/protocol/tasks/buyer/BuyerSignPayoutTx.java | 2 ++ .../protocol/tasks/buyer/BuyerSignsDelayedPayoutTx.java | 2 ++ .../BuyerAsMakerCreatesAndSignsDepositTx.java | 2 ++ .../buyer_as_taker/BuyerAsTakerCreatesDepositTxInputs.java | 2 ++ .../protocol/tasks/mediation/SignMediatedPayoutTx.java | 2 ++ .../protocol/tasks/seller/SellerCreatesDelayedPayoutTx.java | 2 ++ .../protocol/tasks/seller/SellerSignsDelayedPayoutTx.java | 2 ++ .../SellerAsTakerCreatesDepositTxInputs.java | 2 ++ .../core/trade/protocol/tasks/taker/CreateTakerFeeTx.java | 3 +++ .../tasks/taker/TakerSendInputsForDepositTxRequest.java | 3 +++ 16 files changed, 34 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java b/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java index 67042717e68..526c53c62a6 100644 --- a/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java +++ b/core/src/main/java/bisq/core/support/dispute/mediation/MediationManager.java @@ -204,9 +204,9 @@ public void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) { trade.getDisputeState() == Trade.DisputeState.MEDIATION_STARTED_BY_PEER) { trade.getProcessModel().setBuyerPayoutAmountFromMediation(disputeResult.getBuyerPayoutAmount().value); trade.getProcessModel().setSellerPayoutAmountFromMediation(disputeResult.getSellerPayoutAmount().value); - tradeManager.requestPersistence(); trade.setDisputeState(Trade.DisputeState.MEDIATION_CLOSED); + tradeManager.requestPersistence(); } } else { diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index ed6cac4ea1c..5bbd88c4cd5 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -433,6 +433,7 @@ public void onTakeOffer(Coin amount, ((TakerProtocol) tradeProtocol).onTakeOffer(); tradeResultHandler.handleResult(trade); + requestPersistence(); } }, errorMessageHandler); diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java index 41de427050c..2a29e2b562d 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java @@ -65,6 +65,7 @@ public BuyerAsTakerProtocol(BuyerAsTakerTrade trade) { Offer offer = checkNotNull(trade.getOffer()); processModel.getTradingPeer().setPubKeyRing(offer.getPubKeyRing()); + processModel.getTradeManager().requestPersistence(); } @@ -83,7 +84,10 @@ public void onTakeOffer() { BuyerAsTakerCreatesDepositTxInputs.class, TakerSendInputsForDepositTxRequest.class) .withTimeout(30)) - .run(() -> processModel.setTempTradingPeerNodeAddress(trade.getTradingPeerNodeAddress())) + .run(() -> { + processModel.setTempTradingPeerNodeAddress(trade.getTradingPeerNodeAddress()); + processModel.getTradeManager().requestPersistence(); + }) .executeTasks(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/FluentProtocol.java b/core/src/main/java/bisq/core/trade/protocol/FluentProtocol.java index bf054e99c4c..53815bfc075 100644 --- a/core/src/main/java/bisq/core/trade/protocol/FluentProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/FluentProtocol.java @@ -99,11 +99,13 @@ public FluentProtocol executeTasks() { NodeAddress peer = condition.getPeer(); if (peer != null) { tradeProtocol.processModel.setTempTradingPeerNodeAddress(peer); + tradeProtocol.processModel.getTradeManager().requestPersistence(); } TradeMessage message = condition.getMessage(); if (message != null) { tradeProtocol.processModel.setTradeMessage(message); + tradeProtocol.processModel.getTradeManager().requestPersistence(); } TradeTaskRunner taskRunner = setup.getTaskRunner(message, condition.getEvent()); diff --git a/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java b/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java index 017e640fddb..0aeac20f04e 100644 --- a/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java +++ b/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java @@ -294,6 +294,7 @@ void setPaymentStartedAckMessage(AckMessage ackMessage) { public void setPaymentStartedMessageState(MessageState paymentStartedMessageStateProperty) { this.paymentStartedMessageStateProperty.set(paymentStartedMessageStateProperty); + tradeManager.requestPersistence(); } void setDepositTxSentAckMessage(AckMessage ackMessage) { @@ -305,6 +306,7 @@ void setDepositTxSentAckMessage(AckMessage ackMessage) { public void setDepositTxMessageState(MessageState messageState) { this.depositTxMessageStateProperty.set(messageState); + tradeManager.requestPersistence(); } void witnessDebugLog(Trade trade) { diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java index afcd654d824..286a6141926 100644 --- a/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java @@ -59,6 +59,7 @@ public SellerAsTakerProtocol(SellerAsTakerTrade trade) { super(trade); Offer offer = checkNotNull(trade.getOffer()); processModel.getTradingPeer().setPubKeyRing(offer.getPubKeyRing()); + processModel.getTradeManager().requestPersistence(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignPayoutTx.java index 728ed405503..70dd1b8074a 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignPayoutTx.java @@ -81,6 +81,8 @@ protected void run() { sellerMultiSigPubKey); processModel.setPayoutTxSignature(payoutTxSignature); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignsDelayedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignsDelayedPayoutTx.java index 32748a319c3..cab7fc896ba 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignsDelayedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSignsDelayedPayoutTx.java @@ -69,6 +69,8 @@ protected void run() { sellerMultiSigPubKey); processModel.setDelayedPayoutTxSignature(delayedPayoutTxSignature); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerCreatesAndSignsDepositTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerCreatesAndSignsDepositTx.java index 29459b1c955..b62379c7ab8 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerCreatesAndSignsDepositTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerCreatesAndSignsDepositTx.java @@ -97,6 +97,8 @@ protected void run() { processModel.setPreparedDepositTx(result.depositTransaction); processModel.setRawTransactionInputs(result.rawMakerInputs); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerCreatesDepositTxInputs.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerCreatesDepositTxInputs.java index 0e911516436..0277ca7b76b 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerCreatesDepositTxInputs.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerCreatesDepositTxInputs.java @@ -53,6 +53,8 @@ protected void run() { processModel.setChangeOutputValue(result.changeOutputValue); processModel.setChangeOutputAddress(result.changeOutputAddress); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SignMediatedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SignMediatedPayoutTx.java index 3c145b981a9..6699d832003 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SignMediatedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/mediation/SignMediatedPayoutTx.java @@ -99,6 +99,8 @@ protected void run() { sellerMultiSigPubKey); processModel.setMediatedPayoutTxSignature(mediatedPayoutTxSignature); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerCreatesDelayedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerCreatesDelayedPayoutTx.java index aaf667c41d2..ae9048bec7b 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerCreatesDelayedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerCreatesDelayedPayoutTx.java @@ -56,6 +56,8 @@ protected void run() { processModel.setPreparedDelayedPayoutTx(preparedDelayedPayoutTx); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignsDelayedPayoutTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignsDelayedPayoutTx.java index 556e556b418..adabac92ebf 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignsDelayedPayoutTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller/SellerSignsDelayedPayoutTx.java @@ -70,6 +70,8 @@ protected void run() { processModel.setDelayedPayoutTxSignature(delayedPayoutTxSignature); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerCreatesDepositTxInputs.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerCreatesDepositTxInputs.java index 9240e9f8d18..7aa4118e6e9 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerCreatesDepositTxInputs.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerCreatesDepositTxInputs.java @@ -57,6 +57,8 @@ protected void run() { processModel.setChangeOutputValue(result.changeOutputValue); processModel.setChangeOutputAddress(result.changeOutputAddress); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java index e2dd1ed13b2..e6468020083 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java @@ -100,6 +100,9 @@ protected void run() { processModel.setTakeOfferFeeTx(transaction); walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING); + + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { if (t instanceof DaoDisabledException) { diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSendInputsForDepositTxRequest.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSendInputsForDepositTxRequest.java index 1170e18074d..89b201b4ad9 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSendInputsForDepositTxRequest.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSendInputsForDepositTxRequest.java @@ -129,6 +129,9 @@ protected void run() { log.info("Send {} with offerId {} and uid {} to peer {}", request.getClass().getSimpleName(), request.getTradeId(), request.getUid(), trade.getTradingPeerNodeAddress()); + + processModel.getTradeManager().requestPersistence(); + processModel.getP2PService().sendEncryptedDirectMessage( trade.getTradingPeerNodeAddress(), processModel.getTradingPeer().getPubKeyRing(), From 6fb36dcd41023381e9a372b5e0b1c789daa62257 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Wed, 18 Nov 2020 12:51:53 -0500 Subject: [PATCH 05/10] Add more requestPersistence calls --- .../buyer_as_taker/BuyerAsTakerSendsDepositTxMessage.java | 2 +- .../tasks/seller_as_maker/SellerAsMakerFinalizesDepositTx.java | 2 ++ .../SellerAsMakerSendsInputsForDepositTxResponse.java | 3 +++ .../tasks/seller_as_taker/SellerAsTakerSignsDepositTx.java | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSendsDepositTxMessage.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSendsDepositTxMessage.java index 08682bce8b4..b4d27bd6b1f 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSendsDepositTxMessage.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSendsDepositTxMessage.java @@ -72,7 +72,7 @@ public void onFault(String errorMessage) { } ); } else { - log.error("processModel.getDepositTx() = " + processModel.getDepositTx()); + log.error("processModel.getDepositTx() = {}", processModel.getDepositTx()); failed("DepositTx is null"); } } catch (Throwable t) { diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerFinalizesDepositTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerFinalizesDepositTx.java index 1a580b2fc7f..3902668f82e 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerFinalizesDepositTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerFinalizesDepositTx.java @@ -48,6 +48,8 @@ protected void run() { processModel.setDepositTx(myDepositTx); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { failed(t); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerSendsInputsForDepositTxResponse.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerSendsInputsForDepositTxResponse.java index c44adea75bd..9d0a3a83f35 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerSendsInputsForDepositTxResponse.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerSendsInputsForDepositTxResponse.java @@ -41,6 +41,9 @@ protected byte[] getPreparedDepositTx() { // before we have received his signature for the delayed payout tx. input.setScriptSig(new Script(new byte[]{})); }); + + processModel.getTradeManager().requestPersistence(); + return preparedDepositTx.bitcoinSerialize(); } } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignsDepositTx.java b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignsDepositTx.java index 16b4084eb9a..887cbcf7636 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignsDepositTx.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignsDepositTx.java @@ -83,6 +83,8 @@ protected void run() { // We set the deposit tx to trade once we have it published processModel.setDepositTx(depositTx); + processModel.getTradeManager().requestPersistence(); + complete(); } catch (Throwable t) { Contract contract = trade.getContract(); From 438a0d8217d9d86111f7017ba7f3194d69c6aa1c Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Wed, 18 Nov 2020 19:58:20 -0500 Subject: [PATCH 06/10] Remove requestPersistence in constructor as TradeManager is not set at that moment. --- .../main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java | 1 - .../java/bisq/core/trade/protocol/SellerAsTakerProtocol.java | 1 - 2 files changed, 2 deletions(-) diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java index 2a29e2b562d..514c5c12d5f 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java @@ -65,7 +65,6 @@ public BuyerAsTakerProtocol(BuyerAsTakerTrade trade) { Offer offer = checkNotNull(trade.getOffer()); processModel.getTradingPeer().setPubKeyRing(offer.getPubKeyRing()); - processModel.getTradeManager().requestPersistence(); } diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java index 286a6141926..afcd654d824 100644 --- a/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java @@ -59,7 +59,6 @@ public SellerAsTakerProtocol(SellerAsTakerTrade trade) { super(trade); Offer offer = checkNotNull(trade.getOffer()); processModel.getTradingPeer().setPubKeyRing(offer.getPubKeyRing()); - processModel.getTradeManager().requestPersistence(); } From 706ec5a2ed495e7317956f82c674d0efe255ee2d Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Thu, 19 Nov 2020 00:07:34 -0500 Subject: [PATCH 07/10] Add null checks for tradeManager We get called some setter methods from protobuf methods before tradeManager is set. --- .../main/java/bisq/core/trade/protocol/ProcessModel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java b/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java index 0aeac20f04e..ad0e10d671b 100644 --- a/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java +++ b/core/src/main/java/bisq/core/trade/protocol/ProcessModel.java @@ -294,7 +294,9 @@ void setPaymentStartedAckMessage(AckMessage ackMessage) { public void setPaymentStartedMessageState(MessageState paymentStartedMessageStateProperty) { this.paymentStartedMessageStateProperty.set(paymentStartedMessageStateProperty); - tradeManager.requestPersistence(); + if (tradeManager != null) { + tradeManager.requestPersistence(); + } } void setDepositTxSentAckMessage(AckMessage ackMessage) { @@ -306,7 +308,9 @@ void setDepositTxSentAckMessage(AckMessage ackMessage) { public void setDepositTxMessageState(MessageState messageState) { this.depositTxMessageStateProperty.set(messageState); - tradeManager.requestPersistence(); + if (tradeManager != null) { + tradeManager.requestPersistence(); + } } void witnessDebugLog(Trade trade) { From da9b42fb839f170374ef48c4e150d3793b81ff29 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Thu, 19 Nov 2020 00:34:40 -0500 Subject: [PATCH 08/10] Handle potential deposit confirmed state issues The deposit confirmed state is set after we applied the mailbox messages, which led to a task failure due wrong phase and the message was not applied. Further it can be that the wallet is still syncing and the deposit confirmed state is set in any time in the future. To fix the first problem we add a bit of delay so that the trade has been updated when we apply the mailbox messages. A better fix would be to change the order of the methods but that is a bit tricky to get right and I dont want to risk that for that release. The second problem would require a large change to trigger the mailbox processing based on wallet state. We prefer to be more tolerant with the expected phase instead so allow the mailbox message to be processed also in the DEPOSIT_PUBLISHED state. This has no risks as the payout tx would be invalid anyway if the buyer has cheated and sent the msg in not confirmed deposit tx state (only possible with code manipulation). A better fix would to add a listener for the wallet and process the mailbox msg once wallet is ready and trade state set, but I leave that for another PR. --- .../java/bisq/core/trade/protocol/SellerProtocol.java | 7 ++++++- .../java/bisq/core/trade/protocol/TradeProtocol.java | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java index c36b6c04178..00a6dbf25ea 100644 --- a/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java @@ -99,7 +99,12 @@ protected void handle(DelayedPayoutTxSignatureResponse message, NodeAddress peer /////////////////////////////////////////////////////////////////////////////////////////// protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress peer) { - expect(phase(Trade.Phase.DEPOSIT_CONFIRMED) + // We are more tolerant with expected phase and allow also DEPOSIT_PUBLISHED as it can be the case + // that the wallet is still syncing and so the DEPOSIT_CONFIRMED state to yet triggered when we received + // a mailbox message with CounterCurrencyTransferStartedMessage. + // TODO A better fix would be to add a listener for the wallet sync state and process + // the mailbox msg once wallet is ready and trade state set. + expect(anyPhase(Trade.Phase.DEPOSIT_CONFIRMED, Trade.Phase.DEPOSIT_PUBLISHED) .with(message) .from(peer) .preCondition(trade.getPayoutTx() == null, diff --git a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java index d72ac1c3771..6d236d83ca4 100644 --- a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java @@ -41,6 +41,8 @@ import java.security.PublicKey; +import java.util.concurrent.TimeUnit; + import lombok.extern.slf4j.Slf4j; import javax.annotation.Nullable; @@ -69,7 +71,13 @@ public TradeProtocol(Trade trade) { public void initialize(ProcessModelServiceProvider serviceProvider, TradeManager tradeManager, Offer offer) { processModel.applyTransient(serviceProvider, tradeManager, offer); - onInitialized(); + + // We delay a bit here as the trade gets updated from the wallet to update the trade + // state (deposit confirmed) and that happens after our method is called. + // TODO To fix that in a better way we would need to change the order of some routines + // from the TradeManager, but as we are close to a release I dont want to risk a bigger + // change and leave that for a later PR + UserThread.runAfter(this::onInitialized, 100, TimeUnit.MILLISECONDS); } protected void onInitialized() { From d6f4eed39e99f810d58e19d546e156aeba319a7c Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Thu, 19 Nov 2020 09:51:06 -0500 Subject: [PATCH 09/10] Add requestPersistence call at TradeTask.complete call. This is not really needed as we call it at each state change of the trade but gives more redundancy in case we missed one or once changes are applied and a dev forgets to call it. Multiple repeated calls do have close to zero costs. --- .../java/bisq/core/trade/protocol/tasks/TradeTask.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java b/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java index 2f50603eff4..332b571f747 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/TradeTask.java @@ -37,6 +37,13 @@ protected TradeTask(TaskRunner taskHandler, Trade trade) { processModel = trade.getProcessModel(); } + @Override + protected void complete() { + processModel.getTradeManager().requestPersistence(); + + super.complete(); + } + @Override protected void failed() { trade.setErrorMessage(errorMessage); From a4db09fe1deeefdbc22f707a1a51094028f9ebf7 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Thu, 19 Nov 2020 10:19:48 -0500 Subject: [PATCH 10/10] Move delay for applying mailbox messages inside onInitialized We need to set addDecryptedDirectMessageListener without delay as otherwise we could miss direct messages (detected with localhost testing, with tor its likely slower and would not have been triggered). --- .../core/trade/protocol/TradeProtocol.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java index 6d236d83ca4..56fa61edb03 100644 --- a/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java @@ -71,22 +71,24 @@ public TradeProtocol(Trade trade) { public void initialize(ProcessModelServiceProvider serviceProvider, TradeManager tradeManager, Offer offer) { processModel.applyTransient(serviceProvider, tradeManager, offer); - - // We delay a bit here as the trade gets updated from the wallet to update the trade - // state (deposit confirmed) and that happens after our method is called. - // TODO To fix that in a better way we would need to change the order of some routines - // from the TradeManager, but as we are close to a release I dont want to risk a bigger - // change and leave that for a later PR - UserThread.runAfter(this::onInitialized, 100, TimeUnit.MILLISECONDS); + onInitialized(); } protected void onInitialized() { if (!trade.isWithdrawn()) { processModel.getP2PService().addDecryptedDirectMessageListener(this); } - processModel.getP2PService().addDecryptedMailboxListener(this); - processModel.getP2PService().getMailBoxMessages() - .forEach(this::handleDecryptedMessageWithPubKey); + + // We delay a bit here as the trade gets updated from the wallet to update the trade + // state (deposit confirmed) and that happens after our method is called. + // TODO To fix that in a better way we would need to change the order of some routines + // from the TradeManager, but as we are close to a release I dont want to risk a bigger + // change and leave that for a later PR + UserThread.runAfter(() -> { + processModel.getP2PService().addDecryptedMailboxListener(this); + processModel.getP2PService().getMailBoxMessages() + .forEach(this::handleDecryptedMessageWithPubKey); + }, 100, TimeUnit.MILLISECONDS); } public void onWithdrawCompleted() {