include all utxos when sending max amount

This commit is contained in:
Craig Raw 2021-04-21 09:53:53 +02:00
parent efaa6a066d
commit b0d37fe8fe

View file

@ -461,11 +461,12 @@ public class Wallet {
} }
public WalletTransaction createWalletTransaction(List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, List<Payment> payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { public WalletTransaction createWalletTransaction(List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, List<Payment> payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException {
boolean sendMax = payments.stream().anyMatch(Payment::isSendMax);
long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum();
long valueRequiredAmt = totalPaymentAmount; long valueRequiredAmt = totalPaymentAmount;
while(true) { while(true) {
Map<BlockTransactionHashIndex, WalletNode> selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); Map<BlockTransactionHashIndex, WalletNode> selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs, sendMax);
long totalSelectedAmt = selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); long totalSelectedAmt = selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum();
Transaction transaction = new Transaction(); Transaction transaction = new Transaction();
@ -501,7 +502,7 @@ public class Wallet {
throw new InsufficientFundsException("Not enough combined value in selected UTXOs for fee of " + noChangeFeeRequiredAmt); throw new InsufficientFundsException("Not enough combined value in selected UTXOs for fee of " + noChangeFeeRequiredAmt);
} }
Optional<Payment> optMaxPayment = payments.stream().filter(payment -> payment.isSendMax()).findFirst(); Optional<Payment> optMaxPayment = payments.stream().filter(Payment::isSendMax).findFirst();
if(optMaxPayment.isPresent()) { if(optMaxPayment.isPresent()) {
Payment maxPayment = optMaxPayment.get(); Payment maxPayment = optMaxPayment.get();
maxSendAmt = maxSendAmt - payments.stream().filter(payment -> !maxPayment.equals(payment)).map(Payment::getAmount).mapToLong(v -> v).sum(); maxSendAmt = maxSendAmt - payments.stream().filter(payment -> !maxPayment.equals(payment)).map(Payment::getAmount).mapToLong(v -> v).sum();
@ -567,7 +568,7 @@ public class Wallet {
} }
} }
private Map<BlockTransactionHashIndex, WalletNode> selectInputs(List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { private Map<BlockTransactionHashIndex, WalletNode> selectInputs(List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs, boolean sendMax) throws InsufficientFundsException {
List<OutputGroup> utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); List<OutputGroup> utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs);
List<OutputGroup.Filter> filters = new ArrayList<>(); List<OutputGroup.Filter> filters = new ArrayList<>();
@ -577,6 +578,10 @@ public class Wallet {
filters.add(new OutputGroup.Filter(0, 0)); filters.add(new OutputGroup.Filter(0, 0));
} }
if(sendMax) {
Collections.reverse(filters);
}
for(OutputGroup.Filter filter : filters) { for(OutputGroup.Filter filter : filters) {
List<OutputGroup> filteredPool = utxoPool.stream().filter(filter::isEligible).collect(Collectors.toList()); List<OutputGroup> filteredPool = utxoPool.stream().filter(filter::isEligible).collect(Collectors.toList());