diff --git a/drongo b/drongo index f0aa9491..b9ef670e 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit f0aa9491746cfa9d12630ff1f5ccdcf97cc4aa90 +Subproject commit b9ef670e61885362f6d7d4879c61ea6792434d2a diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index bb2146f7..77d7e4bd 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -967,7 +967,7 @@ public class AppController implements Initializable { String text; if(event.getBlockTransactions().size() == 1) { BlockTransaction blockTransaction = event.getBlockTransactions().get(0); - if(blockTransaction.getHeight() == 0) { + if(blockTransaction.getHeight() <= 0) { text = "New mempool transaction: "; } else { int confirmations = blockTransaction.getConfirmations(getCurrentBlockHeight()); @@ -1003,7 +1003,7 @@ public class AppController implements Initializable { .title("Sparrow - " + event.getWallet().getName()) .text(text) .graphic(new ImageView(image)) - .hideAfter(Duration.seconds(5)) + .hideAfter(Duration.seconds(15)) .position(Pos.TOP_RIGHT) .threshold(5, Notifications.create().title("Sparrow").text("Multiple new wallet transactions").graphic(new ImageView(image))) .onAction(e -> selectTab(event.getWallet())); diff --git a/src/main/java/com/sparrowwallet/sparrow/net/VerboseTransaction.java b/src/main/java/com/sparrowwallet/sparrow/net/VerboseTransaction.java index 800bdd43..89f55fe8 100644 --- a/src/main/java/com/sparrowwallet/sparrow/net/VerboseTransaction.java +++ b/src/main/java/com/sparrowwallet/sparrow/net/VerboseTransaction.java @@ -22,6 +22,10 @@ class VerboseTransaction { public int version; public int getHeight() { + if(confirmations <= 0) { + return 0; + } + Integer currentHeight = AppController.getCurrentBlockHeight(); if(currentHeight != null) { return currentHeight - confirmations + 1; @@ -31,6 +35,11 @@ class VerboseTransaction { } public Date getDate() { + if(blocktime == 0) { + //Ok to return as null here as date inspection for verbose txes is only done by HeadersController, which checks for null values + return null; + } + return new Date(blocktime * 1000); } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index de675349..ba391090 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.transaction; +import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.SecureString; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.protocol.*; @@ -14,6 +15,9 @@ import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands; import com.sparrowwallet.sparrow.io.Device; import com.sparrowwallet.sparrow.net.ElectrumServer; import com.sparrowwallet.sparrow.io.Storage; +import com.sparrowwallet.sparrow.wallet.HashIndexEntry; +import com.sparrowwallet.sparrow.wallet.TransactionEntry; +import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -905,13 +909,40 @@ public class HeadersController extends TransactionFormController implements Init updateBlockchainForm(blockTransaction, AppController.getCurrentBlockHeight()); } }); - transactionReferenceService.setOnSucceeded(failEvent -> { + transactionReferenceService.setOnFailed(failEvent -> { log.error("Could not update block transaction", failEvent.getSource().getException()); }); transactionReferenceService.start(); } } + @Subscribe + public void walletHistoryChanged(WalletHistoryChangedEvent event) { + //Update tx and input/output reference labels on history changed wallet if this txid matches and label is null + if(headersForm.getSigningWallet() != null && !(headersForm.getSigningWallet() instanceof FinalizingPSBTWallet)) { + Sha256Hash txid = headersForm.getTransaction().getTxId(); + + BlockTransaction blockTransaction = event.getWallet().getTransactions().get(txid); + if(blockTransaction != null && blockTransaction.getLabel() == null) { + blockTransaction.setLabel(headersForm.getName()); + Platform.runLater(() -> EventManager.get().post(new WalletEntryLabelChangedEvent(event.getWallet(), new TransactionEntry(event.getWallet(), blockTransaction, Collections.emptyMap(), Collections.emptyMap())))); + } + + for(WalletNode walletNode : event.getHistoryChangedNodes()) { + for(BlockTransactionHashIndex output : walletNode.getTransactionOutputs()) { + if(output.getHash().equals(txid) && output.getLabel() == null) { //If we send to ourselves, usually change + output.setLabel(headersForm.getName() + (walletNode.getKeyPurpose() == KeyPurpose.CHANGE ? " (change)" : " (received)")); + Platform.runLater(() -> EventManager.get().post(new WalletEntryLabelChangedEvent(event.getWallet(), new HashIndexEntry(event.getWallet(), output, HashIndexEntry.Type.OUTPUT, walletNode.getKeyPurpose())))); + } + if(output.getSpentBy() != null && output.getSpentBy().getHash().equals(txid) && output.getSpentBy().getLabel() == null) { //The norm - sending out + output.getSpentBy().setLabel(headersForm.getName() + " (input)"); + Platform.runLater(() -> EventManager.get().post(new WalletEntryLabelChangedEvent(event.getWallet(), new HashIndexEntry(event.getWallet(), output.getSpentBy(), HashIndexEntry.Type.INPUT, walletNode.getKeyPurpose())))); + } + } + } + } + } + @Subscribe public void newBlock(NewBlockEvent event) { if(headersForm.getBlockTransaction() != null) { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java index 045619aa..756c8b88 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java @@ -94,7 +94,7 @@ public class HashIndexEntry extends Entry implements Comparable } if(getHashIndex().getHeight() != o.getHashIndex().getHeight()) { - return (o.getHashIndex().getHeight() > 0 ? o.getHashIndex().getHeight() : Integer.MAX_VALUE) - (getHashIndex().getHeight() > 0 ? getHashIndex().getHeight() : Integer.MAX_VALUE); + return o.getHashIndex().getComparisonHeight() - getHashIndex().getComparisonHeight(); } return (int)o.getHashIndex().getIndex() - (int)getHashIndex().getIndex();