mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
set null date on unconfirmed txes, dont let external utxos show as spendable
This commit is contained in:
parent
fa082e892f
commit
189ac75467
9 changed files with 49 additions and 18 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 446eac3483229fc4c798e82f367ca9d8f797d16e
|
Subproject commit e8bb733ea8a6e476982e5ea78c288105d0bd8644
|
|
@ -39,6 +39,7 @@ public class BalanceChart extends LineChart<Number, Number> {
|
||||||
|
|
||||||
List<Data<Number, Number>> balanceDataList = walletTransactionsEntry.getChildren().stream()
|
List<Data<Number, Number>> balanceDataList = walletTransactionsEntry.getChildren().stream()
|
||||||
.map(entry -> (TransactionEntry)entry)
|
.map(entry -> (TransactionEntry)entry)
|
||||||
|
.filter(txEntry -> txEntry.getBlockTransaction().getHeight() > 0)
|
||||||
.map(txEntry -> new XYChart.Data<>((Number)txEntry.getBlockTransaction().getDate().getTime(), (Number)txEntry.getBalance(), txEntry))
|
.map(txEntry -> new XYChart.Data<>((Number)txEntry.getBlockTransaction().getDate().getTime(), (Number)txEntry.getBalance(), txEntry))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ public class BalanceChart extends LineChart<Number, Number> {
|
||||||
XYChart.Data<Number, Number> data = balanceSeries.getData().get(i);
|
XYChart.Data<Number, Number> data = balanceSeries.getData().get(i);
|
||||||
Node symbol = lookup(".chart-line-symbol.data" + i);
|
Node symbol = lookup(".chart-line-symbol.data" + i);
|
||||||
if(symbol != null) {
|
if(symbol != null) {
|
||||||
if(data.getXValue().equals(transactionEntry.getBlockTransaction().getDate().getTime()) && data.getExtraValue() != null) {
|
if(transactionEntry.getBlockTransaction().getDate() != null && data.getXValue().equals(transactionEntry.getBlockTransaction().getDate().getTime()) && data.getExtraValue() != null) {
|
||||||
symbol.getStyleClass().add("selected");
|
symbol.getStyleClass().add("selected");
|
||||||
selectedEntry = transactionEntry;
|
selectedEntry = transactionEntry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,14 @@ public class DateCell extends TreeTableCell<Entry, Entry> {
|
||||||
} else {
|
} else {
|
||||||
if(entry instanceof UtxoEntry) {
|
if(entry instanceof UtxoEntry) {
|
||||||
UtxoEntry utxoEntry = (UtxoEntry)entry;
|
UtxoEntry utxoEntry = (UtxoEntry)entry;
|
||||||
|
if(utxoEntry.getHashIndex().getHeight() <= 0) {
|
||||||
|
setText("Unconfirmed");
|
||||||
|
} else {
|
||||||
String date = DATE_FORMAT.format(utxoEntry.getHashIndex().getDate());
|
String date = DATE_FORMAT.format(utxoEntry.getHashIndex().getDate());
|
||||||
setText(date);
|
setText(date);
|
||||||
setContextMenu(new DateContextMenu(date, utxoEntry.getHashIndex()));
|
setContextMenu(new DateContextMenu(date, utxoEntry.getHashIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
Tooltip tooltip = new Tooltip();
|
Tooltip tooltip = new Tooltip();
|
||||||
int height = utxoEntry.getHashIndex().getHeight();
|
int height = utxoEntry.getHashIndex().getHeight();
|
||||||
tooltip.setText(height > 0 ? Integer.toString(height) : "Mempool");
|
tooltip.setText(height > 0 ? Integer.toString(height) : "Mempool");
|
||||||
|
|
|
@ -43,9 +43,18 @@ class EntryCell extends TreeTableCell<Entry, Entry> {
|
||||||
} else {
|
} else {
|
||||||
if(entry instanceof TransactionEntry) {
|
if(entry instanceof TransactionEntry) {
|
||||||
TransactionEntry transactionEntry = (TransactionEntry)entry;
|
TransactionEntry transactionEntry = (TransactionEntry)entry;
|
||||||
|
if(transactionEntry.getBlockTransaction().getHeight() == -1) {
|
||||||
|
setText("Unconfirmed Parent");
|
||||||
|
setContextMenu(new UnconfirmedTransactionContextMenu(transactionEntry.getBlockTransaction()));
|
||||||
|
} else if(transactionEntry.getBlockTransaction().getHeight() == 0) {
|
||||||
|
setText("Unconfirmed");
|
||||||
|
setContextMenu(new UnconfirmedTransactionContextMenu(transactionEntry.getBlockTransaction()));
|
||||||
|
} else {
|
||||||
String date = DATE_FORMAT.format(transactionEntry.getBlockTransaction().getDate());
|
String date = DATE_FORMAT.format(transactionEntry.getBlockTransaction().getDate());
|
||||||
setText(date);
|
setText(date);
|
||||||
setContextMenu(new TransactionContextMenu(date, transactionEntry.getBlockTransaction()));
|
setContextMenu(new TransactionContextMenu(date, transactionEntry.getBlockTransaction()));
|
||||||
|
}
|
||||||
|
|
||||||
Tooltip tooltip = new Tooltip();
|
Tooltip tooltip = new Tooltip();
|
||||||
tooltip.setText(transactionEntry.getBlockTransaction().getHash().toString());
|
tooltip.setText(transactionEntry.getBlockTransaction().getHash().toString());
|
||||||
setTooltip(tooltip);
|
setTooltip(tooltip);
|
||||||
|
@ -95,7 +104,7 @@ class EntryCell extends TreeTableCell<Entry, Entry> {
|
||||||
});
|
});
|
||||||
actionBox.getChildren().add(viewTransactionButton);
|
actionBox.getChildren().add(viewTransactionButton);
|
||||||
|
|
||||||
if(hashIndexEntry.getType().equals(HashIndexEntry.Type.OUTPUT) && !hashIndexEntry.isSpent()) {
|
if(hashIndexEntry.getType().equals(HashIndexEntry.Type.OUTPUT) && hashIndexEntry.isSpendable()) {
|
||||||
Button spendUtxoButton = new Button("");
|
Button spendUtxoButton = new Button("");
|
||||||
Glyph sendGlyph = new Glyph("FontAwesome", FontAwesome.Glyph.SEND);
|
Glyph sendGlyph = new Glyph("FontAwesome", FontAwesome.Glyph.SEND);
|
||||||
sendGlyph.setFontSize(12);
|
sendGlyph.setFontSize(12);
|
||||||
|
@ -105,7 +114,7 @@ class EntryCell extends TreeTableCell<Entry, Entry> {
|
||||||
.map(tp -> tp.getTreeItem().getValue())
|
.map(tp -> tp.getTreeItem().getValue())
|
||||||
.filter(e -> e instanceof HashIndexEntry)
|
.filter(e -> e instanceof HashIndexEntry)
|
||||||
.map(e -> (HashIndexEntry)e)
|
.map(e -> (HashIndexEntry)e)
|
||||||
.filter(e -> e.getType().equals(HashIndexEntry.Type.OUTPUT) && !hashIndexEntry.isSpent())
|
.filter(e -> e.getType().equals(HashIndexEntry.Type.OUTPUT) && e.isSpendable())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if(!utxoEntries.contains(hashIndexEntry)) {
|
if(!utxoEntries.contains(hashIndexEntry)) {
|
||||||
|
@ -124,6 +133,20 @@ class EntryCell extends TreeTableCell<Entry, Entry> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class UnconfirmedTransactionContextMenu extends ContextMenu {
|
||||||
|
public UnconfirmedTransactionContextMenu(BlockTransaction blockTransaction) {
|
||||||
|
MenuItem copyTxid = new MenuItem("Copy Transaction ID");
|
||||||
|
copyTxid.setOnAction(AE -> {
|
||||||
|
hide();
|
||||||
|
ClipboardContent content = new ClipboardContent();
|
||||||
|
content.putString(blockTransaction.getHashAsString());
|
||||||
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
getItems().addAll(copyTxid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class TransactionContextMenu extends ContextMenu {
|
private static class TransactionContextMenu extends ContextMenu {
|
||||||
public TransactionContextMenu(String date, BlockTransaction blockTransaction) {
|
public TransactionContextMenu(String date, BlockTransaction blockTransaction) {
|
||||||
MenuItem copyDate = new MenuItem("Copy Date");
|
MenuItem copyDate = new MenuItem("Copy Date");
|
||||||
|
|
|
@ -370,7 +370,7 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
BlockTransactionHash reference = optionalReference.get();
|
BlockTransactionHash reference = optionalReference.get();
|
||||||
|
|
||||||
Date blockDate;
|
Date blockDate = null;
|
||||||
if(reference.getHeight() > 0) {
|
if(reference.getHeight() > 0) {
|
||||||
BlockHeader blockHeader = blockHeaderMap.get(reference.getHeight());
|
BlockHeader blockHeader = blockHeaderMap.get(reference.getHeight());
|
||||||
if(blockHeader == null) {
|
if(blockHeader == null) {
|
||||||
|
@ -379,8 +379,6 @@ public class ElectrumServer {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
blockDate = blockHeader.getTimeAsDate();
|
blockDate = blockHeader.getTimeAsDate();
|
||||||
} else {
|
|
||||||
blockDate = new Date();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockTransaction blockchainTransaction = new BlockTransaction(reference.getHash(), reference.getHeight(), blockDate, reference.getFee(), transaction);
|
BlockTransaction blockchainTransaction = new BlockTransaction(reference.getHash(), reference.getHeight(), blockDate, reference.getFee(), transaction);
|
||||||
|
|
|
@ -210,12 +210,12 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
||||||
result.put(targetBlock, targetBlocksFeeRateBtcKb);
|
result.put(targetBlock, targetBlocksFeeRateBtcKb);
|
||||||
} catch(IllegalStateException | IllegalArgumentException e) {
|
} catch(IllegalStateException | IllegalArgumentException e) {
|
||||||
log.warn("Failed to retrieve fee rate for target blocks: " + targetBlock + " (" + e.getMessage() + ")");
|
log.warn("Failed to retrieve fee rate for target blocks: " + targetBlock + " (" + e.getMessage() + ")");
|
||||||
result.put(targetBlock, 1d);
|
result.put(targetBlock, 0.0001d);
|
||||||
} catch(JsonRpcException e) {
|
} catch(JsonRpcException e) {
|
||||||
throw new ElectrumServerRpcException("Failed to retrieve fee rate for target blocks: " + targetBlock, e);
|
throw new ElectrumServerRpcException("Failed to retrieve fee rate for target blocks: " + targetBlock, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.put(targetBlock, 1d);
|
result.put(targetBlock, 0.0001d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,17 @@ public class HashIndexEntry extends Entry implements Comparable<HashIndexEntry>
|
||||||
return (type.equals(Type.INPUT) ? "Spent by input " : "Received from output ") +
|
return (type.equals(Type.INPUT) ? "Spent by input " : "Received from output ") +
|
||||||
getHashIndex().getHash().toString().substring(0, 8) + "..:" +
|
getHashIndex().getHash().toString().substring(0, 8) + "..:" +
|
||||||
getHashIndex().getIndex() +
|
getHashIndex().getIndex() +
|
||||||
" on " + DateLabel.getShortDateFormat(getHashIndex().getDate());
|
(getHashIndex().getHeight() <= 0 ? " (Unconfirmed)" : " on " + DateLabel.getShortDateFormat(getHashIndex().getDate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSpent() {
|
public boolean isSpent() {
|
||||||
return getType().equals(HashIndexEntry.Type.INPUT) || getHashIndex().getSpentBy() != null;
|
return getType().equals(HashIndexEntry.Type.INPUT) || getHashIndex().getSpentBy() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSpendable() {
|
||||||
|
return !isSpent() && (hashIndex.getHeight() > 0 || wallet.allInputsFromWallet(hashIndex.getHash()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getValue() {
|
public Long getValue() {
|
||||||
return hashIndex.getValue();
|
return hashIndex.getValue();
|
||||||
|
|
|
@ -144,7 +144,7 @@ public class ReceiveController extends WalletFormController implements Initializ
|
||||||
} else if(!currentOutputs.isEmpty()) {
|
} else if(!currentOutputs.isEmpty()) {
|
||||||
long count = currentOutputs.size();
|
long count = currentOutputs.size();
|
||||||
BlockTransactionHashIndex lastUsedReference = currentOutputs.stream().skip(count - 1).findFirst().get();
|
BlockTransactionHashIndex lastUsedReference = currentOutputs.stream().skip(count - 1).findFirst().get();
|
||||||
lastUsed.setText(DATE_FORMAT.format(lastUsedReference.getDate()));
|
lastUsed.setText(lastUsedReference.getHeight() <= 0 ? "Unconfirmed Transaction" : DATE_FORMAT.format(lastUsedReference.getDate()));
|
||||||
lastUsed.setGraphic(getWarningGlyph());
|
lastUsed.setGraphic(getWarningGlyph());
|
||||||
} else {
|
} else {
|
||||||
lastUsed.setText("Unknown");
|
lastUsed.setText("Unknown");
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<AnchorPane>
|
<AnchorPane>
|
||||||
<TransactionDiagram fx:id="transactionDiagram" maxWidth="700" maxHeight="230" AnchorPane.rightAnchor="100" />
|
<TransactionDiagram fx:id="transactionDiagram" maxWidth="700" maxHeight="230" AnchorPane.leftAnchor="60" />
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
</VBox>
|
</VBox>
|
||||||
</center>
|
</center>
|
||||||
|
|
Loading…
Reference in a new issue