diff --git a/core/src/main/java/haveno/core/trade/Trade.java b/core/src/main/java/haveno/core/trade/Trade.java index 1ee3cb8b83..f0b0ee2873 100644 --- a/core/src/main/java/haveno/core/trade/Trade.java +++ b/core/src/main/java/haveno/core/trade/Trade.java @@ -1812,19 +1812,6 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model { return; } - // unreserve taker's key images - if (this instanceof TakerTrade) { - ThreadUtils.submitToPool(() -> { - xmrWalletService.thawOutputs(getSelf().getReserveTxKeyImages()); - }); - } - - // unreserve maker's open offer - Optional openOffer = processModel.getOpenOfferManager().getOpenOffer(this.getId()); - if (this instanceof MakerTrade && openOffer.isPresent()) { - processModel.getOpenOfferManager().unreserveOpenOffer(openOffer.get()); - } - // remove if deposit not requested or is failed if (!isDepositRequested() || isDepositRequestFailed()) { removeTradeOnError(); @@ -1832,7 +1819,10 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model { } // done if wallet already deleted - if (!walletExists()) return; + if (!walletExists()) { + removeTradeOnError(); + return; + } // set error height if (processModel.getTradeProtocolErrorHeight() == 0) { @@ -1927,6 +1917,19 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model { forceCloseWallet(); if (isDepositRequested()) getWallet(); + // unreserve taker's key images + if (this instanceof TakerTrade) { + ThreadUtils.submitToPool(() -> { + xmrWalletService.thawOutputs(getSelf().getReserveTxKeyImages()); + }); + } + + // unreserve maker's open offer + Optional openOffer = processModel.getOpenOfferManager().getOpenOffer(this.getId()); + if (this instanceof MakerTrade && openOffer.isPresent()) { + processModel.getOpenOfferManager().unreserveOpenOffer(openOffer.get()); + } + // clear and shut down trade onShutDownStarted(); clearAndShutDown(); diff --git a/core/src/main/java/haveno/core/trade/TradeManager.java b/core/src/main/java/haveno/core/trade/TradeManager.java index 1a764a80cf..937edba786 100644 --- a/core/src/main/java/haveno/core/trade/TradeManager.java +++ b/core/src/main/java/haveno/core/trade/TradeManager.java @@ -445,7 +445,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi Set uninitializedTrades = new HashSet(); for (Trade trade : trades) { Runnable initTradeTask = getInitTradeTask(trade, trades, tradesToSkip, uninitializedTrades, uids); - if (trade.isDepositsPublished() && !trade.isPayoutUnlocked()) initTasksP1.add(initTradeTask); + if (trade.isDepositRequested() && !trade.isPayoutUnlocked()) initTasksP1.add(initTradeTask); else initTasksP2.add(initTradeTask); }; ThreadUtils.awaitTasks(initTasksP1, threadPoolSize); @@ -920,6 +920,10 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi // ensure trade is not already open Optional tradeOptional = getOpenTrade(offer.getId()); if (tradeOptional.isPresent()) throw new RuntimeException("Cannot create trade protocol because trade with ID " + offer.getId() + " is already open"); + + // ensure failed trade is not processing + tradeOptional = getFailedTrade(offer.getId()); + if (tradeOptional.isPresent() && tradeOptional.get().walletExists()) throw new RuntimeException("Cannot create trade protocol because trade with ID " + offer.getId() + " has failed but is not processed"); // create trade Trade trade; diff --git a/core/src/main/java/haveno/core/trade/protocol/TradeProtocol.java b/core/src/main/java/haveno/core/trade/protocol/TradeProtocol.java index fc9386bc3b..be4a3a7beb 100644 --- a/core/src/main/java/haveno/core/trade/protocol/TradeProtocol.java +++ b/core/src/main/java/haveno/core/trade/protocol/TradeProtocol.java @@ -536,6 +536,11 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D return; } + // log warning if trade not open + if (!processModel.getTradeManager().hasOpenTrade(trade)) { + log.warn("We received a PaymentSentMessage for {} {} but it is not an open trade. This can happen if the trade is pending processing as a failed trade.", trade.getClass().getSimpleName(), trade.getId()); + } + // validate signature try { HavenoUtils.verifyPaymentSentMessage(trade, message);