handle support for multiple payments in a tx

This commit is contained in:
Craig Raw 2020-10-19 11:06:59 +02:00
parent 4ea5ec6c0a
commit ee9247c066
4 changed files with 59 additions and 25 deletions

View file

@ -52,7 +52,9 @@ dependencies {
exclude group: 'org.slf4j'
}
implementation('com.sparrowwallet:hummingbird:1.2')
implementation('com.nativelibs4java:bridj:0.7-20140918-3')
implementation('com.nativelibs4java:bridj:0.7-20140918-3') {
exclude group: 'com.google.android.tools', module: 'dx'
}
implementation('com.github.sarxos:webcam-capture:0.3.13-SNAPSHOT') {
exclude group: 'com.nativelibs4java', module: 'bridj'
}

2
drongo

@ -1 +1 @@
Subproject commit 661e88447f232e44f96f69ee795f151233099ed6
Subproject commit 8b07336d71f32094acb8eb8c162ebd8621ffc4aa

View file

@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.control;
import com.sparrowwallet.drongo.protocol.Sha256Hash;
import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
import com.sparrowwallet.drongo.wallet.Payment;
import com.sparrowwallet.drongo.wallet.WalletNode;
import com.sparrowwallet.drongo.wallet.WalletTransaction;
import com.sparrowwallet.sparrow.EventManager;
@ -26,6 +27,7 @@ import java.util.*;
public class TransactionDiagram extends GridPane {
private static final int MAX_UTXOS = 8;
private static final int MAX_PAYMENTS = 6;
private static final double DIAGRAM_HEIGHT = 230.0;
private static final int TOOLTIP_SHOW_DELAY = 50;
@ -55,10 +57,12 @@ public class TransactionDiagram extends GridPane {
Pane txPane = getTransactionPane();
GridPane.setConstraints(txPane, 3, 0);
Pane outputsLinesPane = getOutputsLines();
List<Payment> displayedPayments = getDisplayedPayments();
Pane outputsLinesPane = getOutputsLines(displayedPayments);
GridPane.setConstraints(outputsLinesPane, 4, 0);
Pane outputsPane = getOutputsLabels();
Pane outputsPane = getOutputsLabels(displayedPayments);
GridPane.setConstraints(outputsPane, 5, 0);
getChildren().clear();
@ -241,7 +245,28 @@ public class TransactionDiagram extends GridPane {
return value * (1.0 - scaleFactor) + additional;
}
private Pane getOutputsLines() {
private List<Payment> getDisplayedPayments() {
List<Payment> payments = walletTx.getPayments();
if(payments.size() > MAX_PAYMENTS) {
List<Payment> displayedPayments = new ArrayList<>();
List<Payment> additional = new ArrayList<>();
for(Payment payment : payments) {
if(displayedPayments.size() < MAX_PAYMENTS) {
displayedPayments.add(payment);
} else {
additional.add(payment);
}
}
displayedPayments.add(new AdditionalPayment(additional));
return displayedPayments;
} else {
return payments;
}
}
private Pane getOutputsLines(List<Payment> displayedPayments) {
VBox pane = new VBox();
Group group = new Group();
VBox.setVgrow(group, Priority.ALWAYS);
@ -255,7 +280,7 @@ public class TransactionDiagram extends GridPane {
group.getChildren().add(yaxisLine);
double width = 140.0;
int numOutputs = (walletTx.getChangeNode() == null ? 2 : 3);
int numOutputs = displayedPayments.size() + (walletTx.getChangeNode() == null ? 1 : 2);
for(int i = 1; i <= numOutputs; i++) {
CubicCurve curve = new CubicCurve();
curve.getStyleClass().add("output-line");
@ -280,23 +305,25 @@ public class TransactionDiagram extends GridPane {
return pane;
}
private Pane getOutputsLabels() {
private Pane getOutputsLabels(List<Payment> displayedPayments) {
VBox outputsBox = new VBox();
outputsBox.setMaxWidth(150);
outputsBox.setPadding(new Insets(0, 20, 0, 10));
outputsBox.setAlignment(Pos.CENTER_LEFT);
outputsBox.getChildren().add(createSpacer());
boolean isConsolidation = walletTx.isConsolidationSend();
String recipientDesc = walletTx.getRecipientAddress().toString().substring(0, 8) + "...";
Label recipientLabel = new Label(recipientDesc, isConsolidation ? getConsolidationGlyph() : getPaymentGlyph());
recipientLabel.getStyleClass().addAll("output-label", "recipient-label");
Tooltip recipientTooltip = new Tooltip((isConsolidation ? "Consolidate " : "Pay ") + getSatsValue(walletTx.getRecipientAmount()) + " sats to\n" + walletTx.getRecipientAddress().toString());
recipientTooltip.getStyleClass().add("recipient-label");
recipientTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY));
recipientLabel.setTooltip(recipientTooltip);
outputsBox.getChildren().add(recipientLabel);
outputsBox.getChildren().add(createSpacer());
for(Payment payment : displayedPayments) {
boolean isConsolidation = walletTx.isConsolidationSend(payment);
String recipientDesc = payment instanceof AdditionalPayment ? payment.getLabel() : payment.getAddress().toString().substring(0, 8) + "...";
Label recipientLabel = new Label(recipientDesc, isConsolidation ? getConsolidationGlyph() : getPaymentGlyph());
recipientLabel.getStyleClass().addAll("output-label", "recipient-label");
Tooltip recipientTooltip = new Tooltip((isConsolidation ? "Consolidate " : "Pay ") + getSatsValue(payment.getAmount()) + " sats to\n" + payment.getAddress().toString());
recipientTooltip.getStyleClass().add("recipient-label");
recipientTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY));
recipientLabel.setTooltip(recipientTooltip);
outputsBox.getChildren().add(recipientLabel);
outputsBox.getChildren().add(createSpacer());
}
if(walletTx.getChangeNode() != null) {
String changeDesc = walletTx.getChangeAddress().toString().substring(0, 8) + "...";
@ -412,4 +439,10 @@ public class TransactionDiagram extends GridPane {
return additionalInputs;
}
}
private static class AdditionalPayment extends Payment {
public AdditionalPayment(List<Payment> additionalPayments) {
super(null, additionalPayments.size() + " more...", additionalPayments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(), false);
}
}
}

View file

@ -275,9 +275,9 @@ public class SendController extends WalletFormController implements Initializabl
walletTransactionProperty.addListener((observable, oldValue, walletTransaction) -> {
if(walletTransaction != null) {
if(getRecipientValueSats() == null || walletTransaction.getRecipientAmount() != getRecipientValueSats()) {
setRecipientValueSats(walletTransaction.getRecipientAmount());
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), walletTransaction.getRecipientAmount());
if(getRecipientValueSats() == null || walletTransaction.getPayments().get(0).getAmount() != getRecipientValueSats()) {
setRecipientValueSats(walletTransaction.getPayments().get(0).getAmount());
setFiatAmount(AppController.getFiatCurrencyExchangeRate(), walletTransaction.getPayments().get(0).getAmount());
}
double feeRate = walletTransaction.getFeeRate();
@ -329,11 +329,12 @@ public class SendController extends WalletFormController implements Initializabl
Long recipientAmount = sendAll ? Long.valueOf(recipientDustThreshold + 1) : getRecipientValueSats();
if(recipientAmount != null && recipientAmount > recipientDustThreshold && (!userFeeSet.get() || (getFeeValueSats() != null && getFeeValueSats() > 0))) {
Wallet wallet = getWalletForm().getWallet();
List<Payment> payments = List.of(new Payment(recipientAddress, label.getText(), recipientAmount, sendAll));
Long userFee = userFeeSet.get() ? getFeeValueSats() : null;
Integer currentBlockHeight = AppController.getCurrentBlockHeight();
boolean groupByAddress = Config.get().isGroupByAddress();
boolean includeMempoolChange = Config.get().isIncludeMempoolChange();
WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), recipientAddress, recipientAmount, getFeeRate(), getMinimumFeeRate(), userFee, currentBlockHeight, sendAll, groupByAddress, includeMempoolChange);
WalletTransaction walletTransaction = wallet.createWalletTransaction(getUtxoSelectors(), getUtxoFilters(), payments, getFeeRate(), getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolChange);
walletTransactionProperty.setValue(walletTransaction);
insufficientInputsProperty.set(false);
@ -611,10 +612,8 @@ public class SendController extends WalletFormController implements Initializabl
WalletTransaction walletTransaction = walletTransactionProperty.get();
Set<WalletNode> nodes = new LinkedHashSet<>(walletTransaction.getSelectedUtxos().values());
nodes.add(walletTransaction.getChangeNode());
WalletNode consolidationNode = walletTransaction.getConsolidationSendNode();
if(consolidationNode != null) {
nodes.add(consolidationNode);
}
List<WalletNode> consolidationNodes = walletTransaction.getConsolidationSendNodes();
nodes.addAll(consolidationNodes);
//All wallet nodes applicable to this transaction are stored so when the subscription status for one is updated, the history for all can be fetched in one atomic update
walletForm.addWalletTransactionNodes(nodes);