From b808222faa9c9f3bd338deb3c6c10153bcbb9905 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 31 Aug 2020 10:14:48 +0200 Subject: [PATCH] deduplicate signed keystores on signature --- drongo | 2 +- .../control/SignaturesProgressBar.java | 24 ++++++++++++------- .../transaction/HeadersController.java | 12 +++++----- .../sparrow/transaction/InputController.java | 4 ++-- .../sparrow/transaction/InputsController.java | 4 ++-- .../sparrow/transaction/TransactionData.java | 14 +++++++---- .../sparrow/transaction/TransactionForm.java | 9 +++++-- 7 files changed, 43 insertions(+), 26 deletions(-) diff --git a/drongo b/drongo index 55717c31..10035278 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 55717c31bf8046e558ee90a5997c1de769517813 +Subproject commit 10035278543d9ca90b11ae3d396edc3e6131fee2 diff --git a/src/main/java/com/sparrowwallet/sparrow/control/SignaturesProgressBar.java b/src/main/java/com/sparrowwallet/sparrow/control/SignaturesProgressBar.java index 87522de1..f43402c2 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/SignaturesProgressBar.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/SignaturesProgressBar.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.control; +import com.sparrowwallet.drongo.protocol.TransactionSignature; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.event.KeystoreSignedEvent; @@ -7,8 +8,8 @@ import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.beans.property.SimpleObjectProperty; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; +import javafx.collections.MapChangeListener; +import javafx.collections.ObservableMap; import javafx.geometry.Insets; import javafx.geometry.Orientation; import javafx.geometry.Pos; @@ -18,6 +19,9 @@ import javafx.scene.layout.StackPane; import javafx.util.Duration; import org.controlsfx.control.SegmentedBar; +import java.util.ArrayList; +import java.util.List; + public class SignaturesProgressBar extends SegmentedBar { public SignaturesProgressBar() { setOrientation(Orientation.HORIZONTAL); @@ -25,10 +29,11 @@ public class SignaturesProgressBar extends SegmentedBar segment.getKeystore() == null ? null : new SignatureProgressSegmentLabel(segment.getKeystore().getLabel())); } - public void initialize(ObservableList signedKeystores, int threshold) { + public void initialize(ObservableMap signatureKeystoreMap, int threshold) { getStyleClass().add("signatures-progress-bar"); getSegments().clear(); + List signedKeystores = new ArrayList<>(signatureKeystoreMap.values()); int numSegments = Math.max(threshold, signedKeystores.size()); double segmentSize = 100d / numSegments; for(int i = 0; i < numSegments; i++) { @@ -39,19 +44,20 @@ public class SignaturesProgressBar extends SegmentedBar) c -> { - int numSegments1 = Math.max(threshold, c.getList().size()); - double newSegmentSize = 100d / numSegments1; + signatureKeystoreMap.addListener((MapChangeListener) c -> { + List newSignedKeystores = new ArrayList<>(c.getMap().values()); + int newNumSegments = Math.max(threshold, newSignedKeystores.size()); + double newSegmentSize = 100d / newNumSegments; - for(int i = 0; i < numSegments1; i++) { + for(int i = 0; i < newNumSegments; i++) { SignatureProgressSegment segment = null; if(i < getSegments().size()) { segment = getSegments().get(i); } Keystore signedKeystore = null; - if(i < signedKeystores.size()) { - signedKeystore = signedKeystores.get(i); + if(i < newSignedKeystores.size()) { + signedKeystore = newSignedKeystores.get(i); } if(segment != null) { diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index 24d132b3..778e3ec6 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -405,7 +405,7 @@ public class HeadersController extends TransactionFormController implements Init updateSignedKeystores(signingWallet); int threshold = signingWallet.getDefaultPolicy().getNumSignaturesRequired(); - signaturesProgressBar.initialize(headersForm.getSignedKeystores(), threshold); + signaturesProgressBar.initialize(headersForm.getSignatureKeystoreMap(), threshold); }); EventManager.get().post(new RequestOpenWalletsEvent()); @@ -705,12 +705,11 @@ public class HeadersController extends TransactionFormController implements Init } private void updateSignedKeystores(Wallet signingWallet) { - Map> signedKeystoresMap = signingWallet.getSignedKeystores(headersForm.getPsbt()); - Optional> optSignedKeystores = signedKeystoresMap.values().stream().filter(list -> !list.isEmpty()).min(Comparator.comparingInt(List::size)); + Map> signedKeystoresMap = signingWallet.getSignedKeystores(headersForm.getPsbt()); + Optional> optSignedKeystores = signedKeystoresMap.values().stream().filter(map -> !map.isEmpty()).min(Comparator.comparingInt(Map::size)); optSignedKeystores.ifPresent(signedKeystores -> { - List newSignedKeystores = new ArrayList<>(signedKeystores); - newSignedKeystores.removeAll(headersForm.getSignedKeystores()); - headersForm.getSignedKeystores().addAll(newSignedKeystores); + headersForm.getSignatureKeystoreMap().keySet().retainAll(signedKeystores.keySet()); + headersForm.getSignatureKeystoreMap().putAll(signedKeystores); }); } @@ -922,6 +921,7 @@ public class HeadersController extends TransactionFormController implements Init @Subscribe public void keystoreSigned(KeystoreSignedEvent event) { if(headersForm.getSignedKeystores().contains(event.getKeystore()) && headersForm.getPsbt() != null) { + //Attempt to finalize PSBT - will do nothing if all inputs are not signed finalizePSBT(); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java index 14a88af9..2641af03 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java @@ -11,7 +11,7 @@ import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.*; import com.sparrowwallet.sparrow.event.*; -import javafx.collections.ListChangeListener; +import javafx.collections.MapChangeListener; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; @@ -126,7 +126,7 @@ public class InputController extends TransactionFormController implements Initia initializeLocktimeFields(txInput); if(psbtInput != null) { - inputForm.getSignedKeystores().addListener((ListChangeListener) c -> { + inputForm.getSignatureKeystoreMap().addListener((MapChangeListener) c -> { updateSignatures(inputForm.getPsbtInput()); }); } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java index 92d1f7b4..b6ce6f2a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java @@ -13,7 +13,7 @@ import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent; import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent; import com.sparrowwallet.sparrow.event.PSBTCombinedEvent; import com.sparrowwallet.sparrow.event.PSBTFinalizedEvent; -import javafx.collections.ListChangeListener; +import javafx.collections.MapChangeListener; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.chart.PieChart; @@ -62,7 +62,7 @@ public class InputsController extends TransactionFormController implements Initi if(inputsForm.getPsbt() != null) { updatePSBTInputs(inputsForm.getPsbt()); - inputsForm.getSignedKeystores().addListener((ListChangeListener) c -> { + inputsForm.getSignatureKeystoreMap().addListener((MapChangeListener) c -> { updatePSBTInputs(inputsForm.getPsbt()); }); } else if(inputsForm.getInputTransactions() != null) { diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java index 9161d208..559b6f97 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionData.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.transaction; import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.protocol.Transaction; +import com.sparrowwallet.drongo.protocol.TransactionSignature; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.wallet.BlockTransaction; import com.sparrowwallet.drongo.wallet.Keystore; @@ -9,9 +10,10 @@ import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.io.Storage; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; -import javafx.collections.ObservableList; import javafx.collections.ObservableMap; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -30,7 +32,7 @@ public class TransactionData { private final ObservableMap availableWallets = FXCollections.observableHashMap(); private final SimpleObjectProperty signingWallet = new SimpleObjectProperty<>(this, "signingWallet", null); - private final ObservableList signedKeystores = FXCollections.observableArrayList(); + private final ObservableMap signatureKeystoreMap = FXCollections.observableMap(new LinkedHashMap<>()); public TransactionData(String name, PSBT psbt) { this(name, psbt.getTransaction()); @@ -147,7 +149,11 @@ public class TransactionData { this.signingWallet.set(wallet); } - public ObservableList getSignedKeystores() { - return signedKeystores; + public ObservableMap getSignatureKeystoreMap() { + return signatureKeystoreMap; + } + + public Collection getSignedKeystores() { + return signatureKeystoreMap.values(); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java index 93a342f0..c7c24f78 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionForm.java @@ -2,17 +2,18 @@ package com.sparrowwallet.sparrow.transaction; import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.protocol.Transaction; +import com.sparrowwallet.drongo.protocol.TransactionSignature; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.wallet.BlockTransaction; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.io.Storage; import javafx.beans.property.SimpleObjectProperty; -import javafx.collections.ObservableList; import javafx.collections.ObservableMap; import javafx.scene.Node; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -83,7 +84,11 @@ public abstract class TransactionForm { txdata.setSigningWallet(signingWallet); } - public ObservableList getSignedKeystores() { + public ObservableMap getSignatureKeystoreMap() { + return txdata.getSignatureKeystoreMap(); + } + + public Collection getSignedKeystores() { return txdata.getSignedKeystores(); }