add additional utxos to cpfp transaction if output value is below dust threshold

This commit is contained in:
Craig Raw 2023-06-23 13:39:38 +02:00
parent 5105b503ea
commit ef9723ed44

View file

@ -339,15 +339,35 @@ public class EntryCell extends TreeTableCell<Entry, Entry> implements Confirmati
throw new IllegalStateException("Cannot create CPFP without any wallet outputs to spend"); throw new IllegalStateException("Cannot create CPFP without any wallet outputs to spend");
} }
BlockTransactionHashIndex utxo = ourOutputs.get(0); BlockTransactionHashIndex cpfpUtxo = ourOutputs.get(0);
Address freshAddress = transactionEntry.getWallet().getFreshNode(KeyPurpose.RECEIVE).getAddress();
TransactionOutput txOutput = new TransactionOutput(new Transaction(), cpfpUtxo.getValue(), freshAddress.getOutputScript());
long dustThreshold = freshAddress.getScriptType().getDustThreshold(txOutput, Transaction.DUST_RELAY_TX_FEE);
int inputSize = freshAddress.getScriptType().getInputVbytes();
long vSize = inputSize + txOutput.getLength();
List<BlockTransactionHashIndex> walletUtxos = new ArrayList<>(transactionEntry.getWallet().getWalletUtxos().keySet());
//Remove any UTXOs that are frozen or that we are already spending
walletUtxos.removeIf(utxo -> utxo.getStatus() == Status.FROZEN || utxo.equals(cpfpUtxo));
Collections.shuffle(walletUtxos);
List<BlockTransactionHashIndex> utxos = new ArrayList<>();
utxos.add(cpfpUtxo);
long inputTotal = cpfpUtxo.getValue();
while((inputTotal - (long)(getMaxFeeRate() * vSize)) < dustThreshold && !walletUtxos.isEmpty()) {
//If there is insufficient input value, include another random UTXO so the fee can be increased
BlockTransactionHashIndex utxo = walletUtxos.remove(0);
utxos.add(utxo);
inputTotal += utxo.getValue();
vSize += inputSize;
}
WalletNode freshNode = transactionEntry.getWallet().getFreshNode(KeyPurpose.RECEIVE);
String label = transactionEntry.getLabel() == null ? "" : transactionEntry.getLabel(); String label = transactionEntry.getLabel() == null ? "" : transactionEntry.getLabel();
label += (label.isEmpty() ? "" : " ") + "(CPFP)"; label += (label.isEmpty() ? "" : " ") + "(CPFP)";
Payment payment = new Payment(freshNode.getAddress(), label, utxo.getValue(), true); Payment payment = new Payment(freshAddress, label, inputTotal, true);
EventManager.get().post(new SendActionEvent(transactionEntry.getWallet(), List.of(utxo))); EventManager.get().post(new SendActionEvent(transactionEntry.getWallet(), utxos));
Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(transactionEntry.getWallet(), List.of(utxo), List.of(payment), null, blockTransaction.getFee(), false))); Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(transactionEntry.getWallet(), utxos, List.of(payment), null, blockTransaction.getFee(), false)));
} }
private static boolean canSignMessage(WalletNode walletNode) { private static boolean canSignMessage(WalletNode walletNode) {