mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2026-08-09 00:04:55 +00:00
deduplicate signed keystores on signature
This commit is contained in:
+1
-1
Submodule drongo updated: 55717c31bf...1003527854
@@ -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<SignaturesProgressBar.SignatureProgressSegment> {
|
||||
public SignaturesProgressBar() {
|
||||
setOrientation(Orientation.HORIZONTAL);
|
||||
@@ -25,10 +29,11 @@ public class SignaturesProgressBar extends SegmentedBar<SignaturesProgressBar.Si
|
||||
setInfoNodeFactory(segment -> segment.getKeystore() == null ? null : new SignatureProgressSegmentLabel(segment.getKeystore().getLabel()));
|
||||
}
|
||||
|
||||
public void initialize(ObservableList<Keystore> signedKeystores, int threshold) {
|
||||
public void initialize(ObservableMap<TransactionSignature, Keystore> signatureKeystoreMap, int threshold) {
|
||||
getStyleClass().add("signatures-progress-bar");
|
||||
getSegments().clear();
|
||||
|
||||
List<Keystore> 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<SignaturesProgressBar.Si
|
||||
}
|
||||
}
|
||||
|
||||
signedKeystores.addListener((ListChangeListener<Keystore>) c -> {
|
||||
int numSegments1 = Math.max(threshold, c.getList().size());
|
||||
double newSegmentSize = 100d / numSegments1;
|
||||
signatureKeystoreMap.addListener((MapChangeListener<TransactionSignature, Keystore>) c -> {
|
||||
List<Keystore> 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) {
|
||||
|
||||
@@ -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<PSBTInput, List<Keystore>> signedKeystoresMap = signingWallet.getSignedKeystores(headersForm.getPsbt());
|
||||
Optional<List<Keystore>> optSignedKeystores = signedKeystoresMap.values().stream().filter(list -> !list.isEmpty()).min(Comparator.comparingInt(List::size));
|
||||
Map<PSBTInput, Map<TransactionSignature, Keystore>> signedKeystoresMap = signingWallet.getSignedKeystores(headersForm.getPsbt());
|
||||
Optional<Map<TransactionSignature, Keystore>> optSignedKeystores = signedKeystoresMap.values().stream().filter(map -> !map.isEmpty()).min(Comparator.comparingInt(Map::size));
|
||||
optSignedKeystores.ifPresent(signedKeystores -> {
|
||||
List<Keystore> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Keystore>) c -> {
|
||||
inputForm.getSignatureKeystoreMap().addListener((MapChangeListener<TransactionSignature, Keystore>) c -> {
|
||||
updateSignatures(inputForm.getPsbtInput());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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<Keystore>) c -> {
|
||||
inputsForm.getSignatureKeystoreMap().addListener((MapChangeListener<TransactionSignature, Keystore>) c -> {
|
||||
updatePSBTInputs(inputsForm.getPsbt());
|
||||
});
|
||||
} else if(inputsForm.getInputTransactions() != null) {
|
||||
|
||||
@@ -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<Wallet, Storage> availableWallets = FXCollections.observableHashMap();
|
||||
private final SimpleObjectProperty<Wallet> signingWallet = new SimpleObjectProperty<>(this, "signingWallet", null);
|
||||
private final ObservableList<Keystore> signedKeystores = FXCollections.observableArrayList();
|
||||
private final ObservableMap<TransactionSignature, Keystore> 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<Keystore> getSignedKeystores() {
|
||||
return signedKeystores;
|
||||
public ObservableMap<TransactionSignature, Keystore> getSignatureKeystoreMap() {
|
||||
return signatureKeystoreMap;
|
||||
}
|
||||
|
||||
public Collection<Keystore> getSignedKeystores() {
|
||||
return signatureKeystoreMap.values();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Keystore> getSignedKeystores() {
|
||||
public ObservableMap<TransactionSignature, Keystore> getSignatureKeystoreMap() {
|
||||
return txdata.getSignatureKeystoreMap();
|
||||
}
|
||||
|
||||
public Collection<Keystore> getSignedKeystores() {
|
||||
return txdata.getSignedKeystores();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user