add cancel transaction via rbf to unconfirmed tx context menu

This commit is contained in:
Craig Raw 2022-10-26 11:33:36 +02:00
parent 29cd321724
commit 60dbc8ed84

View file

@ -101,7 +101,7 @@ public class EntryCell extends TreeTableCell<Entry, Entry> {
Button increaseFeeButton = new Button(""); Button increaseFeeButton = new Button("");
increaseFeeButton.setGraphic(getIncreaseFeeRBFGlyph()); increaseFeeButton.setGraphic(getIncreaseFeeRBFGlyph());
increaseFeeButton.setOnAction(event -> { increaseFeeButton.setOnAction(event -> {
increaseFee(transactionEntry); increaseFee(transactionEntry, false);
}); });
actionBox.getChildren().add(increaseFeeButton); actionBox.getChildren().add(increaseFeeButton);
} }
@ -189,7 +189,7 @@ public class EntryCell extends TreeTableCell<Entry, Entry> {
} }
} }
private static void increaseFee(TransactionEntry transactionEntry) { private static void increaseFee(TransactionEntry transactionEntry, boolean cancelTransaction) {
BlockTransaction blockTransaction = transactionEntry.getBlockTransaction(); BlockTransaction blockTransaction = transactionEntry.getBlockTransaction();
Map<BlockTransactionHashIndex, WalletNode> walletTxos = transactionEntry.getWallet().getWalletTxos(); Map<BlockTransactionHashIndex, WalletNode> walletTxos = transactionEntry.getWallet().getWalletTxos();
List<BlockTransactionHashIndex> utxos = transactionEntry.getChildren().stream() List<BlockTransactionHashIndex> utxos = transactionEntry.getChildren().stream()
@ -229,7 +229,7 @@ public class EntryCell extends TreeTableCell<Entry, Entry> {
//Remove any UTXOs created by the transaction that is to be replaced //Remove any UTXOs created by the transaction that is to be replaced
walletUtxos.removeIf(utxo -> ourOutputs.stream().anyMatch(output -> output.getHash().equals(utxo.getHash()) && output.getIndex() == utxo.getIndex())); walletUtxos.removeIf(utxo -> ourOutputs.stream().anyMatch(output -> output.getHash().equals(utxo.getHash()) && output.getIndex() == utxo.getIndex()));
Collections.shuffle(walletUtxos); Collections.shuffle(walletUtxos);
while((double)changeTotal / vSize < getMaxFeeRate() && !walletUtxos.isEmpty()) { while((double)changeTotal / vSize < getMaxFeeRate() && !walletUtxos.isEmpty() && !cancelTransaction) {
//If there is insufficient change output, include another random UTXO so the fee can be increased //If there is insufficient change output, include another random UTXO so the fee can be increased
BlockTransactionHashIndex utxo = walletUtxos.remove(0); BlockTransactionHashIndex utxo = walletUtxos.remove(0);
utxos.add(utxo); utxos.add(utxo);
@ -286,6 +286,15 @@ public class EntryCell extends TreeTableCell<Entry, Entry> {
return; return;
} }
if(cancelTransaction) {
Payment existing = payments.get(0);
Address address = transactionEntry.getWallet().getFreshNode(KeyPurpose.CHANGE).getAddress();
Payment payment = new Payment(address, existing.getLabel(), existing.getAmount(), true);
payments.clear();
payments.add(payment);
opReturns.clear();
}
EventManager.get().post(new SendActionEvent(transactionEntry.getWallet(), utxos)); EventManager.get().post(new SendActionEvent(transactionEntry.getWallet(), utxos));
Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(transactionEntry.getWallet(), utxos, payments, opReturns.isEmpty() ? null : opReturns, blockTransaction.getFee(), true))); Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(transactionEntry.getWallet(), utxos, payments, opReturns.isEmpty() ? null : opReturns, blockTransaction.getFee(), true)));
} }
@ -417,6 +426,12 @@ public class EntryCell extends TreeTableCell<Entry, Entry> {
return increaseFeeGlyph; return increaseFeeGlyph;
} }
private static Glyph getCancelTransactionRBFGlyph() {
Glyph cancelTxGlyph = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.BAN);
cancelTxGlyph.setFontSize(12);
return cancelTxGlyph;
}
private static Glyph getIncreaseFeeCPFPGlyph() { private static Glyph getIncreaseFeeCPFPGlyph() {
Glyph cpfpGlyph = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.SIGN_OUT_ALT); Glyph cpfpGlyph = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.SIGN_OUT_ALT);
cpfpGlyph.setFontSize(12); cpfpGlyph.setFontSize(12);
@ -475,12 +490,23 @@ public class EntryCell extends TreeTableCell<Entry, Entry> {
increaseFee.setGraphic(getIncreaseFeeRBFGlyph()); increaseFee.setGraphic(getIncreaseFeeRBFGlyph());
increaseFee.setOnAction(AE -> { increaseFee.setOnAction(AE -> {
hide(); hide();
increaseFee(transactionEntry); increaseFee(transactionEntry, false);
}); });
getItems().add(increaseFee); getItems().add(increaseFee);
} }
if(blockTransaction.getTransaction().isReplaceByFee() && Config.get().isIncludeMempoolOutputs() && transactionEntry.getWallet().allInputsFromWallet(blockTransaction.getHash())) {
MenuItem cancelTx = new MenuItem("Cancel Transaction (RBF)");
cancelTx.setGraphic(getCancelTransactionRBFGlyph());
cancelTx.setOnAction(AE -> {
hide();
increaseFee(transactionEntry, true);
});
getItems().add(cancelTx);
}
if(containsWalletOutputs(transactionEntry)) { if(containsWalletOutputs(transactionEntry)) {
MenuItem createCpfp = new MenuItem("Increase Effective Fee (CPFP)"); MenuItem createCpfp = new MenuItem("Increase Effective Fee (CPFP)");
createCpfp.setGraphic(getIncreaseFeeCPFPGlyph()); createCpfp.setGraphic(getIncreaseFeeCPFPGlyph());