support broadcasting wallet and non-wallet loaded txes

This commit is contained in:
Craig Raw 2021-01-11 12:27:28 +02:00
parent 72281233e1
commit 628b15a3b5
3 changed files with 67 additions and 12 deletions

2
drongo

@ -1 +1 @@
Subproject commit 4da2c024d4fbe3ecbca9772a0761def6d5269c38
Subproject commit 3e91bdb46cd235247550b2b579285a05609c0837

View file

@ -213,7 +213,7 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
verboseTransaction.blockhash = Sha256Hash.ZERO_HASH.toString();
result.put(txid, verboseTransaction);
} catch(Exception ex) {
throw new ElectrumServerRpcException("Error retrieving transaction: ", ex);
//ignore
}
}
}

View file

@ -25,6 +25,7 @@ import com.sparrowwallet.sparrow.wallet.HashIndexEntry;
import com.sparrowwallet.sparrow.wallet.TransactionEntry;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
@ -415,17 +416,17 @@ public class HeadersController extends TransactionFormController implements Init
}
});
headersForm.signingWalletProperty().addListener((observable, oldValue, signingWallet) -> {
initializeSignButton(signingWallet);
updateSignedKeystores(signingWallet);
int threshold = signingWallet.getDefaultPolicy().getNumSignaturesRequired();
signaturesProgressBar.initialize(headersForm.getSignatureKeystoreMap(), threshold);
});
Platform.runLater(this::requestOpenWallets);
}
headersForm.signingWalletProperty().addListener((observable, oldValue, signingWallet) -> {
initializeSignButton(signingWallet);
updateSignedKeystores(signingWallet);
int threshold = signingWallet.getDefaultPolicy().getNumSignaturesRequired();
signaturesProgressBar.initialize(headersForm.getSignatureKeystoreMap(), threshold);
});
blockchainForm.setDynamicUpdate(this);
}
@ -756,7 +757,7 @@ public class HeadersController extends TransactionFormController implements Init
}
private void updateSignedKeystores(Wallet signingWallet) {
Map<PSBTInput, Map<TransactionSignature, Keystore>> signedKeystoresMap = signingWallet.getSignedKeystores(headersForm.getPsbt());
Map<?, Map<TransactionSignature, Keystore>> signedKeystoresMap = headersForm.getPsbt() == null ? signingWallet.getSignedKeystores(headersForm.getTransaction()) : signingWallet.getSignedKeystores(headersForm.getPsbt());
Optional<Map<TransactionSignature, Keystore>> optSignedKeystores = signedKeystoresMap.values().stream().filter(map -> !map.isEmpty()).min(Comparator.comparingInt(Map::size));
optSignedKeystores.ifPresent(signedKeystores -> {
headersForm.getSignatureKeystoreMap().keySet().retainAll(signedKeystores.keySet());
@ -781,7 +782,9 @@ public class HeadersController extends TransactionFormController implements Init
public void broadcastTransaction(ActionEvent event) {
broadcastButton.setDisable(true);
extractTransaction(event);
if(headersForm.getPsbt() != null) {
extractTransaction(event);
}
if(headersForm.getSigningWallet() instanceof FinalizingPSBTWallet) {
//Ensure the script hashes of the UTXOs in FinalizingPSBTWallet are subscribed to
@ -818,6 +821,21 @@ public class HeadersController extends TransactionFormController implements Init
}
});
transactionMempoolService.start();
} else {
Sha256Hash txid = headersForm.getTransaction().getTxId();
ElectrumServer.TransactionReferenceService transactionReferenceService = new ElectrumServer.TransactionReferenceService(Set.of(txid));
transactionReferenceService.setOnSucceeded(successEvent -> {
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
BlockTransaction blockTransaction = transactionMap.get(txid);
if(blockTransaction != null) {
headersForm.setBlockTransaction(blockTransaction);
updateBlockchainForm(blockTransaction, AppServices.getCurrentBlockHeight());
}
});
transactionReferenceService.setOnFailed(failedEvent -> {
log.error("Error fetching broadcasted transaction", failedEvent.getSource().getException());
});
transactionReferenceService.start();
}
});
broadcastTransactionService.setOnFailed(workerStateEvent -> {
@ -903,6 +921,43 @@ public class HeadersController extends TransactionFormController implements Init
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
if(event.getBlockTransaction() != null && (!Sha256Hash.ZERO_HASH.equals(event.getBlockTransaction().getBlockHash()) || headersForm.getBlockTransaction() == null)) {
updateBlockchainForm(event.getBlockTransaction(), AppServices.getCurrentBlockHeight());
} else if(headersForm.getPsbt() == null) {
boolean isSigned = true;
ObservableMap<TransactionSignature, Keystore> signatureKeystoreMap = FXCollections.observableMap(new LinkedHashMap<>());
for(TransactionInput txInput : headersForm.getTransaction().getInputs()) {
List<TransactionSignature> signatures = txInput.hasWitness() ? txInput.getWitness().getSignatures() : txInput.getScriptSig().getSignatures();
if(signatures.isEmpty()) {
isSigned = false;
break;
}
if(signatureKeystoreMap.isEmpty()) {
for(int i = 0; i < signatures.size(); i++) {
signatureKeystoreMap.put(signatures.get(i), new Keystore("Keystore " + (i+1)));
}
}
}
if(isSigned) {
blockchainForm.setVisible(false);
signaturesForm.setVisible(true);
broadcastButtonBox.setVisible(true);
viewFinalButton.setDisable(true);
if(headersForm.getSigningWallet() == null) {
for(Wallet wallet : AppServices.get().getOpenWallets().keySet()) {
if(wallet.canSign(headersForm.getTransaction())) {
headersForm.setSigningWallet(wallet);
break;
}
}
}
if(headersForm.getSigningWallet() == null) {
signaturesProgressBar.initialize(signatureKeystoreMap, signatureKeystoreMap.size());
}
}
}
Long feeAmt = calculateFee(event.getInputTransactions());