mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 07:07:43 +01:00
Fixes https://github.com/bisq-network/bisq/issues/2804 and https://github.com/bisq-network/bisq/issues/2826
This commit is contained in:
parent
b8cf1d7e67
commit
25ee98dbce
4 changed files with 69 additions and 8 deletions
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.core.btc.exceptions;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public class BsqChangeBelowDustException extends Exception {
|
||||||
|
@Getter
|
||||||
|
private final Coin outputValue;
|
||||||
|
|
||||||
|
public BsqChangeBelowDustException(String message, Coin outputValue) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.outputValue = outputValue;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package bisq.core.btc.wallet;
|
package bisq.core.btc.wallet;
|
||||||
|
|
||||||
|
import bisq.core.btc.exceptions.BsqChangeBelowDustException;
|
||||||
import bisq.core.btc.exceptions.InsufficientBsqException;
|
import bisq.core.btc.exceptions.InsufficientBsqException;
|
||||||
import bisq.core.btc.exceptions.TransactionVerificationException;
|
import bisq.core.btc.exceptions.TransactionVerificationException;
|
||||||
import bisq.core.btc.exceptions.WalletException;
|
import bisq.core.btc.exceptions.WalletException;
|
||||||
|
@ -475,7 +476,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public Transaction getPreparedSendBsqTx(String receiverAddress, Coin receiverAmount)
|
public Transaction getPreparedSendBsqTx(String receiverAddress, Coin receiverAmount)
|
||||||
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException {
|
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException, BsqChangeBelowDustException {
|
||||||
return getPreparedSendTx(receiverAddress, receiverAmount, bsqCoinSelector);
|
return getPreparedSendTx(receiverAddress, receiverAmount, bsqCoinSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,12 +485,12 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public Transaction getPreparedSendBtcTx(String receiverAddress, Coin receiverAmount)
|
public Transaction getPreparedSendBtcTx(String receiverAddress, Coin receiverAmount)
|
||||||
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException {
|
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException, BsqChangeBelowDustException {
|
||||||
return getPreparedSendTx(receiverAddress, receiverAmount, nonBsqCoinSelector);
|
return getPreparedSendTx(receiverAddress, receiverAmount, nonBsqCoinSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Transaction getPreparedSendTx(String receiverAddress, Coin receiverAmount, CoinSelector coinSelector)
|
private Transaction getPreparedSendTx(String receiverAddress, Coin receiverAmount, CoinSelector coinSelector)
|
||||||
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException {
|
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException, BsqChangeBelowDustException {
|
||||||
DaoKillSwitch.assertDaoIsNotDisabled();
|
DaoKillSwitch.assertDaoIsNotDisabled();
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
checkArgument(Restrictions.isAboveDust(receiverAmount),
|
checkArgument(Restrictions.isAboveDust(receiverAmount),
|
||||||
|
@ -510,6 +511,18 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||||
checkWalletConsistency(wallet);
|
checkWalletConsistency(wallet);
|
||||||
verifyTransaction(tx);
|
verifyTransaction(tx);
|
||||||
// printTx("prepareSendTx", tx);
|
// printTx("prepareSendTx", tx);
|
||||||
|
|
||||||
|
// Tx has as first output BSQ and an optional second BSQ change output.
|
||||||
|
// At that stage we do not have added the BTC inputs so there is no BTC change output here.
|
||||||
|
if (tx.getOutputs().size() == 2) {
|
||||||
|
TransactionOutput bsqChangeOutput = tx.getOutputs().get(1);
|
||||||
|
if (!Restrictions.isAboveDust(bsqChangeOutput.getValue())) {
|
||||||
|
String msg = "BSQ change output is below dust limit. outputValue=" + bsqChangeOutput.getValue().toFriendlyString();
|
||||||
|
log.warn(msg);
|
||||||
|
throw new BsqChangeBelowDustException(msg, bsqChangeOutput.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
} catch (InsufficientMoneyException e) {
|
} catch (InsufficientMoneyException e) {
|
||||||
log.error(e.toString());
|
log.error(e.toString());
|
||||||
|
|
|
@ -2278,6 +2278,15 @@ popup.warning.noPriceFeedAvailable=There is no price feed available for that cur
|
||||||
popup.warning.sendMsgFailed=Sending message to your trading partner failed.\nPlease try again and if it continue to fail report a bug.
|
popup.warning.sendMsgFailed=Sending message to your trading partner failed.\nPlease try again and if it continue to fail report a bug.
|
||||||
popup.warning.insufficientBtcFundsForBsqTx=You don''t have sufficient BTC funds for paying the miner fee for that transaction.\n\
|
popup.warning.insufficientBtcFundsForBsqTx=You don''t have sufficient BTC funds for paying the miner fee for that transaction.\n\
|
||||||
Please fund your BTC wallet.\nMissing funds: {0}
|
Please fund your BTC wallet.\nMissing funds: {0}
|
||||||
|
popup.warning.bsqChangeBelowDustException=This transaction creates a BSQ change output which is below dust \
|
||||||
|
limit (5.46 BSQ) and would be rejected by the bitcoin network.\n\n\
|
||||||
|
You need to either send a higher amount to avoid the change output (e.g. by adding the dust amount to your \
|
||||||
|
sending amount) or add more BSQ funds to your wallet so you avoid to generate a dust output.\n\n\
|
||||||
|
The dust output is {0}.
|
||||||
|
popup.warning.btcChangeBelowDustException=This transaction creates a change output which is below dust \
|
||||||
|
limit (546 Satoshi) and would be rejected by the bitcoin network.\n\n\
|
||||||
|
You need to add the dust amount to your sending amount to avoid to generate a dust output.\n\n\
|
||||||
|
The dust output is {0}.
|
||||||
|
|
||||||
popup.warning.insufficientBsqFundsForBtcFeePayment=You don''t have sufficient BSQ funds for paying the trade fee in BSQ. \
|
popup.warning.insufficientBsqFundsForBtcFeePayment=You don''t have sufficient BSQ funds for paying the trade fee in BSQ. \
|
||||||
You can pay the fee in BTC or you need to fund your BSQ wallet. You can buy BSQ in Bisq.\n\n\
|
You can pay the fee in BTC or you need to fund your BSQ wallet. You can buy BSQ in Bisq.\n\n\
|
||||||
|
|
|
@ -33,6 +33,7 @@ import bisq.desktop.util.validation.BsqAddressValidator;
|
||||||
import bisq.desktop.util.validation.BsqValidator;
|
import bisq.desktop.util.validation.BsqValidator;
|
||||||
import bisq.desktop.util.validation.BtcValidator;
|
import bisq.desktop.util.validation.BtcValidator;
|
||||||
|
|
||||||
|
import bisq.core.btc.exceptions.BsqChangeBelowDustException;
|
||||||
import bisq.core.btc.exceptions.TxBroadcastException;
|
import bisq.core.btc.exceptions.TxBroadcastException;
|
||||||
import bisq.core.btc.listeners.BsqBalanceListener;
|
import bisq.core.btc.listeners.BsqBalanceListener;
|
||||||
import bisq.core.btc.setup.WalletsSetup;
|
import bisq.core.btc.setup.WalletsSetup;
|
||||||
|
@ -85,7 +86,7 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
|
||||||
|
|
||||||
private int gridRow = 0;
|
private int gridRow = 0;
|
||||||
private InputTextField amountInputTextField, btcAmountInputTextField;
|
private InputTextField amountInputTextField, btcAmountInputTextField;
|
||||||
private Button sendButton, sendBtcButton;
|
private Button sendBsqButton, sendBtcButton;
|
||||||
private InputTextField receiversAddressInputTextField, receiversBtcAddressInputTextField;
|
private InputTextField receiversAddressInputTextField, receiversBtcAddressInputTextField;
|
||||||
private ChangeListener<Boolean> focusOutListener;
|
private ChangeListener<Boolean> focusOutListener;
|
||||||
private TitledGroupBg btcTitledGroupBg;
|
private TitledGroupBg btcTitledGroupBg;
|
||||||
|
@ -200,7 +201,7 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
|
||||||
bsqValidator.setAvailableBalance(availableConfirmedBalance);
|
bsqValidator.setAvailableBalance(availableConfirmedBalance);
|
||||||
boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid &&
|
boolean isValid = bsqAddressValidator.validate(receiversAddressInputTextField.getText()).isValid &&
|
||||||
bsqValidator.validate(amountInputTextField.getText()).isValid;
|
bsqValidator.validate(amountInputTextField.getText()).isValid;
|
||||||
sendButton.setDisable(!isValid);
|
sendBsqButton.setDisable(!isValid);
|
||||||
|
|
||||||
boolean isBtcValid = btcAddressValidator.validate(receiversBtcAddressInputTextField.getText()).isValid &&
|
boolean isBtcValid = btcAddressValidator.validate(receiversBtcAddressInputTextField.getText()).isValid &&
|
||||||
btcValidator.validate(btcAmountInputTextField.getText()).isValid;
|
btcValidator.validate(btcAmountInputTextField.getText()).isValid;
|
||||||
|
@ -227,9 +228,9 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
|
||||||
onUpdateBalances();
|
onUpdateBalances();
|
||||||
};
|
};
|
||||||
|
|
||||||
sendButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.wallet.send.send"));
|
sendBsqButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.wallet.send.send"));
|
||||||
|
|
||||||
sendButton.setOnAction((event) -> {
|
sendBsqButton.setOnAction((event) -> {
|
||||||
// TODO break up in methods
|
// TODO break up in methods
|
||||||
if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) {
|
if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) {
|
||||||
String receiversAddressString = bsqFormatter.getAddressFromBsqAddress(receiversAddressInputTextField.getText()).toString();
|
String receiversAddressString = bsqFormatter.getAddressFromBsqAddress(receiversAddressInputTextField.getText()).toString();
|
||||||
|
@ -252,6 +253,9 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
|
||||||
receiversAddressInputTextField.setText("");
|
receiversAddressInputTextField.setText("");
|
||||||
amountInputTextField.setText("");
|
amountInputTextField.setText("");
|
||||||
});
|
});
|
||||||
|
} catch (BsqChangeBelowDustException e) {
|
||||||
|
String msg = Res.get("popup.warning.bsqChangeBelowDustException", bsqFormatter.formatCoinWithCode(e.getOutputValue()));
|
||||||
|
new Popup<>().warning(msg).show();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
handleError(t);
|
handleError(t);
|
||||||
}
|
}
|
||||||
|
@ -314,7 +318,9 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} catch (BsqChangeBelowDustException e) {
|
||||||
|
String msg = Res.get("popup.warning.btcChangeBelowDustException", btcFormatter.formatCoinWithCode(e.getOutputValue()));
|
||||||
|
new Popup<>().warning(msg).show();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
handleError(t);
|
handleError(t);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue