From 40faaec31e200c8b55ff4d5291ce74fb8c0be401 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 26 Apr 2021 14:40:11 +0200 Subject: [PATCH] handle user defined fee amount better by requiring a fee rate of 1 sat/vb for utxo selectors --- drongo | 2 +- .../sparrow/wallet/PaymentController.java | 2 +- .../sparrow/wallet/SendController.java | 24 ++++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drongo b/drongo index db05e09f..db9617ee 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit db05e09fe54d80d611153cc4326d83cc91359ffa +Subproject commit db9617ee10383bb78e71ec2252d92bb7fe639440 diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java index 0aa80d9f..c1d76064 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java @@ -219,7 +219,7 @@ public class PaymentController extends WalletFormController implements Initializ } TransactionOutput txOutput = new TransactionOutput(new Transaction(), 1L, address.getOutputScript()); - return address.getScriptType().getDustThreshold(txOutput, sendController.getFeeRate()); + return address.getScriptType().getDustThreshold(txOutput, Transaction.DUST_RELAY_TX_FEE); } private void setFiatAmount(CurrencyRate currencyRate, Long amount) { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java index 80ccc32e..e1f2dad3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java @@ -342,10 +342,6 @@ public class SendController extends WalletFormController implements Initializabl if(userFeeSet.get()) { setTargetBlocks(getTargetBlocks(feeRate)); setFeeRangeRate(feeRate); - - if(walletTransaction.getFee() != getFeeValueSats() && feeRate > getMinimumFeeRate()) { - setFeeValueSats(walletTransaction.getFee()); - } } else { setFeeValueSats(walletTransaction.getFee()); } @@ -483,17 +479,18 @@ public class SendController extends WalletFormController implements Initializabl if(!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0)) { Wallet wallet = getWalletForm().getWallet(); Long userFee = userFeeSet.get() ? getFeeValueSats() : null; + double feeRate = getUserFeeRate(); Integer currentBlockHeight = AppServices.getCurrentBlockHeight(); boolean groupByAddress = Config.get().isGroupByAddress(); boolean includeMempoolOutputs = Config.get().isIncludeMempoolOutputs(); boolean includeSpentMempoolOutputs = includeSpentMempoolOutputsProperty.get(); - WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), payments, getFeeRate(), getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); + WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), payments, feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); walletTransactionProperty.setValue(walletTransaction); insufficientInputsProperty.set(false); return; } - } catch(InvalidAddressException | IllegalStateException e) { + } catch(InvalidAddressException | IllegalStateException | IllegalArgumentException e) { //ignore } catch(InsufficientFundsException e) { insufficientInputsProperty.set(true); @@ -508,8 +505,8 @@ public class SendController extends WalletFormController implements Initializabl } Wallet wallet = getWalletForm().getWallet(); - long noInputsFee = wallet.getNoInputsFee(getPayments(), getFeeRate()); - long costOfChange = wallet.getCostOfChange(getFeeRate(), getMinimumFeeRate()); + long noInputsFee = wallet.getNoInputsFee(getPayments(), getUserFeeRate()); + long costOfChange = wallet.getCostOfChange(getUserFeeRate(), getMinimumFeeRate()); return List.of(new BnBUtxoSelector(noInputsFee, costOfChange), new KnapsackUtxoSelector(noInputsFee)); } @@ -619,6 +616,17 @@ public class SendController extends WalletFormController implements Initializabl feeRange.valueProperty().addListener(feeRangeListener); } + /** + * This method retrieves the fee rate used as input to constructing the transaction. + * Where the user has set a custom fee amount, using the slider fee rate can mean the UTXO selectors underestimate the UTXO effective values and fail to find a solution + * In this case, use a fee rate of 1 sat/VB for maximum flexibility + * + * @return the fee rate to use when constructing a transaction + */ + public Double getUserFeeRate() { + return (userFeeSet.get() ? Transaction.DEFAULT_MIN_RELAY_FEE : getFeeRate()); + } + public Double getFeeRate() { if(targetBlocksField.isVisible()) { return getTargetBlocksFeeRates().get(getTargetBlocks());