From 956cb65a6ced56eebb4226c038dc6985006d172a Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 7 Apr 2020 13:15:25 -0500 Subject: [PATCH 1/3] Add BuyerVerifiesDonationAddress task Buyer was not verifying if the donation address is either the default DAO param address or the recent one changed by DAO voting. We do not support past DAO param addresses to avoid that past addresses receive funds. --- .../trade/protocol/BuyerAsMakerProtocol.java | 2 + .../trade/protocol/BuyerAsTakerProtocol.java | 2 + .../buyer/BuyerVerifiesDonationAddress.java | 80 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java index 3234d6d109a..7bb9f25cd19 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java @@ -38,6 +38,7 @@ import bisq.core.trade.protocol.tasks.buyer.BuyerSignPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDelayedPayoutTx; +import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDonationAddress; import bisq.core.trade.protocol.tasks.buyer_as_maker.BuyerAsMakerCreatesAndSignsDepositTx; import bisq.core.trade.protocol.tasks.buyer_as_maker.BuyerAsMakerSendsInputsForDepositTxResponse; import bisq.core.trade.protocol.tasks.maker.MakerCreateAndSignContract; @@ -154,6 +155,7 @@ private void handle(DelayedPayoutTxSignatureRequest tradeMessage, NodeAddress pe errorMessage -> handleTaskRunnerFault(tradeMessage, errorMessage)); taskRunner.addTasks( BuyerProcessDelayedPayoutTxSignatureRequest.class, + BuyerVerifiesDonationAddress.class, BuyerSignsDelayedPayoutTx.class, BuyerSendsDelayedPayoutTxSignatureResponse.class ); 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 fd7d3292d2e..c9e41e669ae 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java @@ -40,6 +40,7 @@ import bisq.core.trade.protocol.tasks.buyer.BuyerSignPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDelayedPayoutTx; +import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDonationAddress; import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerCreatesDepositTxInputs; import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSendsDepositTxMessage; import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSignsDepositTx; @@ -177,6 +178,7 @@ private void handle(DelayedPayoutTxSignatureRequest tradeMessage, NodeAddress se errorMessage -> handleTaskRunnerFault(tradeMessage, errorMessage)); taskRunner.addTasks( BuyerProcessDelayedPayoutTxSignatureRequest.class, + BuyerVerifiesDonationAddress.class, BuyerSignsDelayedPayoutTx.class, BuyerSendsDelayedPayoutTxSignatureResponse.class ); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java new file mode 100644 index 00000000000..c9c19ae3d59 --- /dev/null +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java @@ -0,0 +1,80 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.trade.protocol.tasks.buyer; + +import bisq.core.dao.governance.param.Param; +import bisq.core.trade.Trade; +import bisq.core.trade.protocol.tasks.TradeTask; + +import bisq.common.taskrunner.TaskRunner; + +import org.bitcoinj.core.Address; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionOutput; + +import lombok.extern.slf4j.Slf4j; + +import static com.google.common.base.Preconditions.checkNotNull; + +@Slf4j +public class BuyerVerifiesDonationAddress extends TradeTask { + @SuppressWarnings({"unused"}) + public BuyerVerifiesDonationAddress(TaskRunner taskHandler, Trade trade) { + super(taskHandler, trade); + } + + @Override + protected void run() { + try { + runInterceptHook(); + + Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx(), "preparedDelayedPayoutTx must not be null"); + + // Get most recent donation address. + // We do not support past DAO param addresses to avoid that those receive funds (no bond set up anymore). + // Users who have not synced the DAO cannot trade. + String recentDonationAddressString = processModel.getDaoFacade().getParamValue(Param.RECIPIENT_BTC_ADDRESS); + + // In case the seller has deactivated the DAO the default address will be used. + String defaultDonationAddressString = Param.RECIPIENT_BTC_ADDRESS.getDefaultValue(); + + TransactionOutput output = preparedDelayedPayoutTx.getOutput(0); + NetworkParameters params = processModel.getBtcWalletService().getParams(); + Address address = output.getAddressFromP2PKHScript(params); + if (address == null) { + // The donation address can be as well be a multisig address. + address = output.getAddressFromP2SH(params); + checkNotNull(address, "address must not be null"); + } + + String addressAsString = address.toString(); + if (recentDonationAddressString.equals(addressAsString) || + defaultDonationAddressString.equals(addressAsString)) { + complete(); + } else { + failed("Sellers donation address not recognized." + + "\nAddress used by BTC seller: " + addressAsString + + "\nRecent donation address:" + recentDonationAddressString + + "\nDefault donation address: " + defaultDonationAddressString); + } + } catch (Throwable t) { + failed(t); + } + } +} From 792808b746d69948ba6e1570f926d99c9a639da6 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 7 Apr 2020 18:16:25 -0500 Subject: [PATCH 2/3] Add donation address validation to open trades We check at buyers step 1 and step 2 if the donation address is valid and show a popup if not. The Trade manager will move such trades to failed trades at startup. --- .../core/trade/DonationAddressValidation.java | 86 +++++++++++++++++++ .../java/bisq/core/trade/TradeManager.java | 9 ++ .../buyer/BuyerVerifiesDonationAddress.java | 47 +++------- .../resources/i18n/displayStrings.properties | 7 ++ .../pendingtrades/PendingTradesDataModel.java | 4 + .../steps/buyer/BuyerStep1View.java | 20 +++++ .../steps/buyer/BuyerStep2View.java | 13 +++ 7 files changed, 149 insertions(+), 37 deletions(-) create mode 100644 core/src/main/java/bisq/core/trade/DonationAddressValidation.java diff --git a/core/src/main/java/bisq/core/trade/DonationAddressValidation.java b/core/src/main/java/bisq/core/trade/DonationAddressValidation.java new file mode 100644 index 00000000000..fd1b17a2b1a --- /dev/null +++ b/core/src/main/java/bisq/core/trade/DonationAddressValidation.java @@ -0,0 +1,86 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.trade; + +import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.param.Param; + +import org.bitcoinj.core.Address; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionOutput; + +import lombok.Value; +import lombok.extern.slf4j.Slf4j; + +import static com.google.common.base.Preconditions.checkNotNull; + +@Slf4j +public class DonationAddressValidation { + + @Value + public static class DonationAddressException extends Exception { + private final String addressAsString; + private final String recentDonationAddressString; + private final String defaultDonationAddressString; + + public DonationAddressException(String addressAsString, + String recentDonationAddressString, + String defaultDonationAddressString) { + + this.addressAsString = addressAsString; + this.recentDonationAddressString = recentDonationAddressString; + this.defaultDonationAddressString = defaultDonationAddressString; + } + } + + public static void validate(Transaction delayedPayoutTx, + DaoFacade daoFacade, + BtcWalletService btcWalletService) throws DonationAddressException { + checkNotNull(delayedPayoutTx, "delayedPayoutTx must not be null"); + + // Get most recent donation address. + // We do not support past DAO param addresses to avoid that those receive funds (no bond set up anymore). + // Users who have not synced the DAO cannot trade. + String recentDonationAddressString = daoFacade.getParamValue(Param.RECIPIENT_BTC_ADDRESS); + + // In case the seller has deactivated the DAO the default address will be used. + String defaultDonationAddressString = Param.RECIPIENT_BTC_ADDRESS.getDefaultValue(); + + TransactionOutput output = delayedPayoutTx.getOutput(0); + NetworkParameters params = btcWalletService.getParams(); + Address address = output.getAddressFromP2PKHScript(params); + if (address == null) { + // The donation address can be as well be a multisig address. + address = output.getAddressFromP2SH(params); + checkNotNull(address, "address must not be null"); + } + + String addressAsString = address.toString(); + boolean isValid = recentDonationAddressString.equals(addressAsString) || + defaultDonationAddressString.equals(addressAsString); + if (!isValid) { + log.warn("Donation address is invalid." + + "\nAddress used by BTC seller: " + addressAsString + + "\nRecent donation address:" + recentDonationAddressString + + "\nDefault donation address: " + defaultDonationAddressString); + throw new DonationAddressException(addressAsString, recentDonationAddressString, defaultDonationAddressString); + } + } +} diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index f55b8bd0d0c..b6f2868deb3 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -297,6 +297,15 @@ private void initPendingTrades() { trade.getId()); tradesWithoutDepositTx.add(trade); } + + try { + DonationAddressValidation.validate(trade.getDelayedPayoutTx(), + daoFacade, + btcWalletService); + } catch (DonationAddressValidation.DonationAddressException e) { + // We move it to failed trades so it cannot be continued. + addTradeToFailedTradesList.add(trade); + } } ); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java index c9c19ae3d59..483fb5ef4d7 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java @@ -17,21 +17,14 @@ package bisq.core.trade.protocol.tasks.buyer; -import bisq.core.dao.governance.param.Param; +import bisq.core.trade.DonationAddressValidation; import bisq.core.trade.Trade; import bisq.core.trade.protocol.tasks.TradeTask; import bisq.common.taskrunner.TaskRunner; -import org.bitcoinj.core.Address; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionOutput; - import lombok.extern.slf4j.Slf4j; -import static com.google.common.base.Preconditions.checkNotNull; - @Slf4j public class BuyerVerifiesDonationAddress extends TradeTask { @SuppressWarnings({"unused"}) @@ -44,35 +37,15 @@ protected void run() { try { runInterceptHook(); - Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx(), "preparedDelayedPayoutTx must not be null"); - - // Get most recent donation address. - // We do not support past DAO param addresses to avoid that those receive funds (no bond set up anymore). - // Users who have not synced the DAO cannot trade. - String recentDonationAddressString = processModel.getDaoFacade().getParamValue(Param.RECIPIENT_BTC_ADDRESS); - - // In case the seller has deactivated the DAO the default address will be used. - String defaultDonationAddressString = Param.RECIPIENT_BTC_ADDRESS.getDefaultValue(); - - TransactionOutput output = preparedDelayedPayoutTx.getOutput(0); - NetworkParameters params = processModel.getBtcWalletService().getParams(); - Address address = output.getAddressFromP2PKHScript(params); - if (address == null) { - // The donation address can be as well be a multisig address. - address = output.getAddressFromP2SH(params); - checkNotNull(address, "address must not be null"); - } - - String addressAsString = address.toString(); - if (recentDonationAddressString.equals(addressAsString) || - defaultDonationAddressString.equals(addressAsString)) { - complete(); - } else { - failed("Sellers donation address not recognized." + - "\nAddress used by BTC seller: " + addressAsString + - "\nRecent donation address:" + recentDonationAddressString + - "\nDefault donation address: " + defaultDonationAddressString); - } + DonationAddressValidation.validate(processModel.getPreparedDelayedPayoutTx(), + processModel.getDaoFacade(), + processModel.getBtcWalletService()); + complete(); + } catch (DonationAddressValidation.DonationAddressException e) { + failed("Sellers donation address is invalid." + + "\nAddress used by BTC seller: " + e.getAddressAsString() + + "\nRecent donation address:" + e.getRecentDonationAddressString() + + "\nDefault donation address: " + e.getDefaultDonationAddressString()); } catch (Throwable t) { failed(t); } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 47764e19d3a..f6e9f2ef4b1 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -555,6 +555,13 @@ portfolio.tab.history=History portfolio.tab.failed=Failed portfolio.tab.editOpenOffer=Edit offer +portfolio.pending.invalidDonationAddress=The donation address in the delayed payout transaction is invalid.\n\n\ + Please do NOT send the Altcoin or Fiat payment but contact the Bisq developers at 'https://bisq.community' or \ + the Keybase channel.\n\n\ + Address used by BTC seller: {0}\n\ + Recent donation address: {1}\n\ + Default donation address: {2}; + portfolio.pending.step1.waitForConf=Wait for blockchain confirmation portfolio.pending.step2_buyer.startPayment=Start payment portfolio.pending.step2_seller.waitPaymentStarted=Wait until payment has started 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 88f45602f13..49d79a0874a 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 @@ -31,6 +31,7 @@ import bisq.core.account.witness.AccountAgeWitnessService; import bisq.core.btc.setup.WalletsSetup; import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.dao.DaoFacade; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; @@ -99,6 +100,7 @@ public class PendingTradesDataModel extends ActivatableDataModel { private final WalletsSetup walletsSetup; @Getter private final AccountAgeWitnessService accountAgeWitnessService; + public final DaoFacade daoFacade; public final Navigation navigation; public final WalletPasswordWindow walletPasswordWindow; private final NotificationCenter notificationCenter; @@ -134,6 +136,7 @@ public PendingTradesDataModel(TradeManager tradeManager, P2PService p2PService, WalletsSetup walletsSetup, AccountAgeWitnessService accountAgeWitnessService, + DaoFacade daoFacade, Navigation navigation, WalletPasswordWindow walletPasswordWindow, NotificationCenter notificationCenter) { @@ -147,6 +150,7 @@ public PendingTradesDataModel(TradeManager tradeManager, this.p2PService = p2PService; this.walletsSetup = walletsSetup; this.accountAgeWitnessService = accountAgeWitnessService; + this.daoFacade = daoFacade; this.navigation = navigation; this.walletPasswordWindow = walletPasswordWindow; this.notificationCenter = notificationCenter; diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java index 2c1d75fa501..5510bb98565 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java @@ -17,10 +17,12 @@ package bisq.desktop.main.portfolio.pendingtrades.steps.buyer; +import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel; import bisq.desktop.main.portfolio.pendingtrades.steps.TradeStepView; import bisq.core.locale.Res; +import bisq.core.trade.DonationAddressValidation; public class BuyerStep1View extends TradeStepView { @@ -32,6 +34,24 @@ public BuyerStep1View(PendingTradesViewModel model) { super(model); } + @Override + public void activate() { + super.activate(); + + try { + DonationAddressValidation.validate(trade.getDelayedPayoutTx(), + model.dataModel.daoFacade, + model.dataModel.btcWalletService); + } catch (DonationAddressValidation.DonationAddressException e) { + new Popup().warning(Res.get("portfolio.pending.invalidDonationAddress", + e.getAddressAsString(), + e.getRecentDonationAddressString(), + e.getDefaultDonationAddressString())) + .show(); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// // Info /////////////////////////////////////////////////////////////////////////////////////////// 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 80cb21526b5..21e254aa900 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 @@ -69,6 +69,7 @@ import bisq.core.payment.payload.PaymentMethod; import bisq.core.payment.payload.USPostalMoneyOrderAccountPayload; import bisq.core.payment.payload.WesternUnionAccountPayload; +import bisq.core.trade.DonationAddressValidation; import bisq.core.trade.Trade; import bisq.core.user.DontShowAgainLookup; @@ -114,6 +115,18 @@ public BuyerStep2View(PendingTradesViewModel model) { public void activate() { super.activate(); + try { + DonationAddressValidation.validate(trade.getDelayedPayoutTx(), + model.dataModel.daoFacade, + model.dataModel.btcWalletService); + } catch (DonationAddressValidation.DonationAddressException e) { + new Popup().warning(Res.get("portfolio.pending.invalidDonationAddress", + e.getAddressAsString(), + e.getRecentDonationAddressString(), + e.getDefaultDonationAddressString())) + .show(); + } + if (timeoutTimer != null) timeoutTimer.stop(); From e92be6cf867f7005ddebce2a1bf4b0a2e09ea8ef Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 7 Apr 2020 20:32:49 -0500 Subject: [PATCH 3/3] Fix issue with failed trades at startup --- .../core/trade/DonationAddressValidation.java | 22 +++++++++++++------ .../java/bisq/core/trade/TradeManager.java | 3 ++- .../buyer/BuyerVerifiesDonationAddress.java | 2 ++ .../steps/buyer/BuyerStep1View.java | 3 +++ .../steps/buyer/BuyerStep2View.java | 3 +++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/bisq/core/trade/DonationAddressValidation.java b/core/src/main/java/bisq/core/trade/DonationAddressValidation.java index fd1b17a2b1a..8d798409c4e 100644 --- a/core/src/main/java/bisq/core/trade/DonationAddressValidation.java +++ b/core/src/main/java/bisq/core/trade/DonationAddressValidation.java @@ -26,7 +26,7 @@ import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionOutput; -import lombok.Value; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import static com.google.common.base.Preconditions.checkNotNull; @@ -34,15 +34,15 @@ @Slf4j public class DonationAddressValidation { - @Value + @Getter public static class DonationAddressException extends Exception { private final String addressAsString; private final String recentDonationAddressString; private final String defaultDonationAddressString; - public DonationAddressException(String addressAsString, - String recentDonationAddressString, - String defaultDonationAddressString) { + DonationAddressException(String addressAsString, + String recentDonationAddressString, + String defaultDonationAddressString) { this.addressAsString = addressAsString; this.recentDonationAddressString = recentDonationAddressString; @@ -50,10 +50,18 @@ public DonationAddressException(String addressAsString, } } + public static class MissingDelayedPayoutTxException extends Exception { + public MissingDelayedPayoutTxException(String msg) { + super(msg); + } + } + public static void validate(Transaction delayedPayoutTx, DaoFacade daoFacade, - BtcWalletService btcWalletService) throws DonationAddressException { - checkNotNull(delayedPayoutTx, "delayedPayoutTx must not be null"); + BtcWalletService btcWalletService) throws DonationAddressException, MissingDelayedPayoutTxException { + if (delayedPayoutTx == null) { + throw new MissingDelayedPayoutTxException("DelayedPayoutTx must not be null"); + } // Get most recent donation address. // We do not support past DAO param addresses to avoid that those receive funds (no bond set up anymore). diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index b6f2868deb3..a981895b0d2 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -302,7 +302,8 @@ private void initPendingTrades() { DonationAddressValidation.validate(trade.getDelayedPayoutTx(), daoFacade, btcWalletService); - } catch (DonationAddressValidation.DonationAddressException e) { + } catch (DonationAddressValidation.DonationAddressException | + DonationAddressValidation.MissingDelayedPayoutTxException e) { // We move it to failed trades so it cannot be continued. addTradeToFailedTradesList.add(trade); } diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java index 483fb5ef4d7..5e91dc39c5d 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java @@ -46,6 +46,8 @@ protected void run() { "\nAddress used by BTC seller: " + e.getAddressAsString() + "\nRecent donation address:" + e.getRecentDonationAddressString() + "\nDefault donation address: " + e.getDefaultDonationAddressString()); + } catch (DonationAddressValidation.MissingDelayedPayoutTxException e) { + failed(e.getMessage()); } catch (Throwable t) { failed(t); } diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java index 5510bb98565..3d74690eaf6 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep1View.java @@ -48,6 +48,9 @@ public void activate() { e.getRecentDonationAddressString(), e.getDefaultDonationAddressString())) .show(); + } catch (DonationAddressValidation.MissingDelayedPayoutTxException e) { + // We don't react on that error as a failed trade might get listed initially but getting removed from the + // trade manager after initPendingTrades which happens after activate might be called. } } 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 21e254aa900..367e3852610 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 @@ -125,6 +125,9 @@ public void activate() { e.getRecentDonationAddressString(), e.getDefaultDonationAddressString())) .show(); + } catch (DonationAddressValidation.MissingDelayedPayoutTxException ignore) { + // We don't react on that error as a failed trade might get listed initially but getting removed from the + // trade manager after initPendingTrades which happens after activate might be called. } if (timeoutTimer != null)