diff --git a/core/src/main/java/bisq/core/btc/wallet/TradeWalletService.java b/core/src/main/java/bisq/core/btc/wallet/TradeWalletService.java index baf2a035ba..d6f4a8b4f9 100644 --- a/core/src/main/java/bisq/core/btc/wallet/TradeWalletService.java +++ b/core/src/main/java/bisq/core/btc/wallet/TradeWalletService.java @@ -177,6 +177,9 @@ public class TradeWalletService { checkNotNull(wallet, "Wallet must not be null"); wallet.completeTx(sendRequest); + if (removeDust(tradingFeeTx)) { + wallet.signTransaction(sendRequest); + } WalletService.printTx("tradingFeeTx", tradingFeeTx); if (doBroadcast && callback != null) { @@ -257,6 +260,7 @@ public class TradeWalletService { checkNotNull(wallet, "Wallet must not be null"); wallet.completeTx(sendRequest); Transaction resultTx = sendRequest.tx; + removeDust(resultTx); // Sign all BTC inputs for (int i = preparedBsqTxInputsSize; i < resultTx.getInputs().size(); i++) { @@ -1216,4 +1220,33 @@ public class TradeWalletService { tx.getInputs().forEach(input -> input.setSequenceNumber(TransactionInput.NO_SEQUENCE - 1)); tx.setLockTime(lockTime); } + + // BISQ issue #4039: prevent dust outputs from being created. + // check all the outputs in a proposed transaction, if any are below the dust threshold + // remove them, noting the details in the log. returns 'true' to indicate if any dust was + // removed. + private boolean removeDust(Transaction transaction) { + List originalTransactionOutputs = transaction.getOutputs(); + List keepTransactionOutputs = new ArrayList<>(); + for (TransactionOutput transactionOutput: originalTransactionOutputs) { + if (transactionOutput.getValue().isLessThan(Restrictions.getMinNonDustOutput())) { + log.info("your transaction would have contained a dust output of {}", transactionOutput.toString()); + } + else { + keepTransactionOutputs.add(transactionOutput); + } + } + // if dust was detected, keepTransactionOutputs will have fewer elements than originalTransactionOutputs + // set the transaction outputs to what we saved in keepTransactionOutputs, thus discarding dust. + if (keepTransactionOutputs.size() != originalTransactionOutputs.size()) { + log.info("dust output was detected and removed, the new output is as follows:"); + transaction.clearOutputs(); + for (TransactionOutput transactionOutput : keepTransactionOutputs) { + transaction.addOutput(transactionOutput); + log.info("{}", transactionOutput.toString()); + } + return true; // dust was removed + } + return false; // no action necessary + } }