diff --git a/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java b/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java index 373d9c03..cb2472ab 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java @@ -231,14 +231,14 @@ public class EntryCell extends TreeTableCell implements Confirmati .filter(e -> e instanceof HashIndexEntry) .map(e -> (HashIndexEntry)e) .filter(e -> e.getType().equals(HashIndexEntry.Type.OUTPUT)) - .map(e -> e.getBlockTransaction().getTransaction().getOutputs().get((int)e.getHashIndex().getIndex())) + .map(e -> blockTransaction.getTransaction().getOutputs().get((int)e.getHashIndex().getIndex())) .collect(Collectors.toList()); List consolidationOutputs = transactionEntry.getChildren().stream() .filter(e -> e instanceof HashIndexEntry) .map(e -> (HashIndexEntry)e) .filter(e -> e.getType().equals(HashIndexEntry.Type.OUTPUT) && e.getKeyPurpose() == KeyPurpose.RECEIVE) - .map(e -> e.getBlockTransaction().getTransaction().getOutputs().get((int)e.getHashIndex().getIndex())) + .map(e -> blockTransaction.getTransaction().getOutputs().get((int)e.getHashIndex().getIndex())) .collect(Collectors.toList()); boolean consolidationTransaction = consolidationOutputs.size() == blockTransaction.getTransaction().getOutputs().size() && consolidationOutputs.size() == 1; diff --git a/src/main/java/com/sparrowwallet/sparrow/net/ElectrumServer.java b/src/main/java/com/sparrowwallet/sparrow/net/ElectrumServer.java index 7db6652e..4a27fe7a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/net/ElectrumServer.java +++ b/src/main/java/com/sparrowwallet/sparrow/net/ElectrumServer.java @@ -355,14 +355,14 @@ public class ElectrumServer { //Because node children are added sequentially in WalletNode.fillToIndex, we can simply look at the number of children to determine the highest filled index int historySize = purposeNode.getChildren().size(); //The gap limit size takes the highest used index in the retrieved history and adds the gap limit (plus one to be comparable to the number of children since index is zero based) - int gapLimitSize = getGapLimitSize(wallet, nodeTransactionMap); + int gapLimitSize = getGapLimitSize(wallet, nodeTransactionMap, purposeNode); while(historySize < gapLimitSize) { purposeNode.fillToIndex(wallet, gapLimitSize - 1); subscribeWalletNodes(wallet, getAddressNodes(wallet, purposeNode), nodeTransactionMap, historySize); getReferences(wallet, nodeTransactionMap.keySet(), nodeTransactionMap, historySize); getReferencedTransactions(wallet, nodeTransactionMap); historySize = purposeNode.getChildren().size(); - gapLimitSize = getGapLimitSize(wallet, nodeTransactionMap); + gapLimitSize = getGapLimitSize(wallet, nodeTransactionMap, purposeNode); } } @@ -377,8 +377,9 @@ public class ElectrumServer { return purposeNode.getChildren().stream().filter(walletNode -> walletNode.getIndex() >= startFromIndex).collect(Collectors.toCollection(TreeSet::new)); } - private int getGapLimitSize(Wallet wallet, Map> nodeTransactionMap) { - int highestIndex = nodeTransactionMap.keySet().stream().filter(node -> node.getDerivation().size() > 1).map(WalletNode::getIndex).max(Comparator.comparing(Integer::valueOf)).orElse(-1); + private int getGapLimitSize(Wallet wallet, Map> nodeTransactionMap, WalletNode purposeNode) { + int highestIndex = nodeTransactionMap.keySet().stream().filter(node -> node.getDerivation().size() > 1 && purposeNode.getKeyPurpose() == node.getKeyPurpose()) + .map(WalletNode::getIndex).max(Comparator.comparing(Integer::valueOf)).orElse(-1); return highestIndex + wallet.getGapLimit() + 1; } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionEntry.java index b628fde9..badc75f8 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionEntry.java @@ -103,7 +103,9 @@ public class TransactionEntry extends Entry implements Comparable ((HashIndexEntry)entry).getHashIndex().toString().equals(ref.getSpentBy().toString()) && ((HashIndexEntry)entry).getType().equals(HashIndexEntry.Type.INPUT))) { + if(!ref.isSpent()) { + log.warn("TransactionEntry " + blockTransaction.getHash() + " for wallet " + getWallet().getFullName() + " missing spending reference on output " + ref); + } else if(getChildren().stream().noneMatch(entry -> ((HashIndexEntry)entry).getHashIndex().toString().equals(ref.getSpentBy().toString()) && ((HashIndexEntry)entry).getType().equals(HashIndexEntry.Type.INPUT))) { log.warn("TransactionEntry " + blockTransaction.getHash() + " for wallet " + getWallet().getFullName() + " missing child for input " + ref.getSpentBy() + " on output " + ref); return false; } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java index bbbdc014..72a30f17 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java @@ -95,8 +95,9 @@ public class WalletTransactionsEntry extends Entry { } if(entriesAdded.size() > entriesComplete.size()) { - entriesAdded.removeAll(entriesComplete); - for(Entry entry : entriesAdded) { + Set incompleteEntries = new HashSet<>(entriesAdded); + entriesComplete.forEach(incompleteEntries::remove); + for(Entry entry : incompleteEntries) { TransactionEntry txEntry = (TransactionEntry)entry; getChildren().remove(txEntry); log.warn("Removing and not notifying incomplete entry " + ((TransactionEntry)entry).getBlockTransaction().getHashAsString() + " value " + txEntry.getValue()