mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-26 01:56:44 +00:00
add detached labels map to store labels during a wallet refresh
This commit is contained in:
parent
ee732fb223
commit
de87ab1102
2 changed files with 87 additions and 8 deletions
|
@ -37,6 +37,7 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
private List<Keystore> keystores = new ArrayList<>();
|
private List<Keystore> keystores = new ArrayList<>();
|
||||||
private final TreeSet<WalletNode> purposeNodes = new TreeSet<>();
|
private final TreeSet<WalletNode> purposeNodes = new TreeSet<>();
|
||||||
private final Map<Sha256Hash, BlockTransaction> transactions = new HashMap<>();
|
private final Map<Sha256Hash, BlockTransaction> transactions = new HashMap<>();
|
||||||
|
private final Map<String, String> detachedLabels = new HashMap<>();
|
||||||
private MixConfig mixConfig;
|
private MixConfig mixConfig;
|
||||||
private final Map<Sha256Hash, UtxoMixData> utxoMixes = new HashMap<>();
|
private final Map<Sha256Hash, UtxoMixData> utxoMixes = new HashMap<>();
|
||||||
private Integer storedBlockHeight;
|
private Integer storedBlockHeight;
|
||||||
|
@ -116,6 +117,7 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
childWallet.setName(standardAccount.getName());
|
childWallet.setName(standardAccount.getName());
|
||||||
childWallet.purposeNodes.clear();
|
childWallet.purposeNodes.clear();
|
||||||
childWallet.transactions.clear();
|
childWallet.transactions.clear();
|
||||||
|
childWallet.detachedLabels.clear();
|
||||||
childWallet.storedBlockHeight = null;
|
childWallet.storedBlockHeight = null;
|
||||||
childWallet.gapLimit = standardAccount.getMinimumGapLimit();
|
childWallet.gapLimit = standardAccount.getMinimumGapLimit();
|
||||||
childWallet.birthDate = null;
|
childWallet.birthDate = null;
|
||||||
|
@ -273,10 +275,19 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
|
|
||||||
public synchronized void updateTransactions(Map<Sha256Hash, BlockTransaction> updatedTransactions) {
|
public synchronized void updateTransactions(Map<Sha256Hash, BlockTransaction> updatedTransactions) {
|
||||||
for(BlockTransaction blockTx : updatedTransactions.values()) {
|
for(BlockTransaction blockTx : updatedTransactions.values()) {
|
||||||
|
if(!transactions.isEmpty()) {
|
||||||
Optional<String> optionalLabel = transactions.values().stream().filter(oldBlTx -> oldBlTx.getHash().equals(blockTx.getHash())).map(BlockTransaction::getLabel).filter(Objects::nonNull).findFirst();
|
Optional<String> optionalLabel = transactions.values().stream().filter(oldBlTx -> oldBlTx.getHash().equals(blockTx.getHash())).map(BlockTransaction::getLabel).filter(Objects::nonNull).findFirst();
|
||||||
optionalLabel.ifPresent(blockTx::setLabel);
|
optionalLabel.ifPresent(blockTx::setLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!detachedLabels.isEmpty()) {
|
||||||
|
String label = detachedLabels.remove(blockTx.getHashAsString());
|
||||||
|
if(label != null && (blockTx.getLabel() == null || blockTx.getLabel().isEmpty())) {
|
||||||
|
blockTx.setLabel(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transactions.putAll(updatedTransactions);
|
transactions.putAll(updatedTransactions);
|
||||||
|
|
||||||
if(!transactions.isEmpty()) {
|
if(!transactions.isEmpty()) {
|
||||||
|
@ -284,6 +295,10 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getDetachedLabels() {
|
||||||
|
return detachedLabels;
|
||||||
|
}
|
||||||
|
|
||||||
public MixConfig getMixConfig() {
|
public MixConfig getMixConfig() {
|
||||||
return mixConfig;
|
return mixConfig;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +409,7 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
purposeNode = optionalPurposeNode.get();
|
purposeNode = optionalPurposeNode.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
purposeNode.fillToIndex(getLookAheadIndex(purposeNode));
|
purposeNode.fillToIndex(this, getLookAheadIndex(purposeNode));
|
||||||
return purposeNode;
|
return purposeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +441,7 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index >= node.getChildren().size()) {
|
if(index >= node.getChildren().size()) {
|
||||||
node.fillToIndex(index);
|
node.fillToIndex(this, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(WalletNode childNode : node.getChildren()) {
|
for(WalletNode childNode : node.getChildren()) {
|
||||||
|
@ -1311,13 +1326,15 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
return BitcoinUnit.SATOSHIS;
|
return BitcoinUnit.SATOSHIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearNodes() {
|
public void clearNodes(Wallet previousWallet) {
|
||||||
|
detachedLabels.putAll(previousWallet.getDetachedLabels(true));
|
||||||
purposeNodes.clear();
|
purposeNodes.clear();
|
||||||
transactions.clear();
|
transactions.clear();
|
||||||
storedBlockHeight = 0;
|
storedBlockHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearHistory() {
|
public void clearHistory() {
|
||||||
|
detachedLabels.putAll(getDetachedLabels(false));
|
||||||
for(WalletNode purposeNode : purposeNodes) {
|
for(WalletNode purposeNode : purposeNodes) {
|
||||||
purposeNode.clearHistory();
|
purposeNode.clearHistory();
|
||||||
}
|
}
|
||||||
|
@ -1326,6 +1343,35 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
storedBlockHeight = 0;
|
storedBlockHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getDetachedLabels(boolean includeAddresses) {
|
||||||
|
Map<String, String> labels = new HashMap<>();
|
||||||
|
for(BlockTransaction blockTransaction : transactions.values()) {
|
||||||
|
if(blockTransaction.getLabel() != null && !blockTransaction.getLabel().isEmpty()) {
|
||||||
|
labels.put(blockTransaction.getHashAsString(), blockTransaction.getLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(WalletNode purposeNode : purposeNodes) {
|
||||||
|
for(WalletNode addressNode : purposeNode.getChildren()) {
|
||||||
|
if(includeAddresses && addressNode.getLabel() != null && !addressNode.getLabel().isEmpty()) {
|
||||||
|
labels.put(getAddress(addressNode).toString(), addressNode.getLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(BlockTransactionHashIndex output : addressNode.getTransactionOutputs()) {
|
||||||
|
if(output.getLabel() != null && !output.getLabel().isEmpty()) {
|
||||||
|
labels.put(output.getHash().toString() + "<" + output.getIndex(), output.getLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(output.isSpent() && output.getSpentBy().getLabel() != null && !output.getSpentBy().getLabel().isEmpty()) {
|
||||||
|
labels.put(output.getSpentBy().getHash() + ">" + output.getSpentBy().getIndex(), output.getSpentBy().getLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
try {
|
try {
|
||||||
checkWallet();
|
checkWallet();
|
||||||
|
@ -1466,6 +1512,9 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
|
||||||
for(Sha256Hash hash : transactions.keySet()) {
|
for(Sha256Hash hash : transactions.keySet()) {
|
||||||
copy.transactions.put(hash, transactions.get(hash));
|
copy.transactions.put(hash, transactions.get(hash));
|
||||||
}
|
}
|
||||||
|
for(String entry : detachedLabels.keySet()) {
|
||||||
|
copy.detachedLabels.put(entry, detachedLabels.get(entry));
|
||||||
|
}
|
||||||
copy.setMixConfig(mixConfig == null ? null : mixConfig.copy());
|
copy.setMixConfig(mixConfig == null ? null : mixConfig.copy());
|
||||||
for(Sha256Hash hash : utxoMixes.keySet()) {
|
for(Sha256Hash hash : utxoMixes.keySet()) {
|
||||||
copy.utxoMixes.put(hash, utxoMixes.get(hash));
|
copy.utxoMixes.put(hash, utxoMixes.get(hash));
|
||||||
|
|
|
@ -106,12 +106,28 @@ public class WalletNode extends Persistable implements Comparable<WalletNode> {
|
||||||
this.transactionOutputs = transactionOutputs;
|
this.transactionOutputs = transactionOutputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void updateTransactionOutputs(Set<BlockTransactionHashIndex> updatedOutputs) {
|
public synchronized void updateTransactionOutputs(Wallet wallet, Set<BlockTransactionHashIndex> updatedOutputs) {
|
||||||
for(BlockTransactionHashIndex txo : updatedOutputs) {
|
for(BlockTransactionHashIndex txo : updatedOutputs) {
|
||||||
|
if(!transactionOutputs.isEmpty()) {
|
||||||
Optional<String> optionalLabel = transactionOutputs.stream().filter(oldTxo -> oldTxo.getHash().equals(txo.getHash()) && oldTxo.getIndex() == txo.getIndex()).map(BlockTransactionHash::getLabel).filter(Objects::nonNull).findFirst();
|
Optional<String> optionalLabel = transactionOutputs.stream().filter(oldTxo -> oldTxo.getHash().equals(txo.getHash()) && oldTxo.getIndex() == txo.getIndex()).map(BlockTransactionHash::getLabel).filter(Objects::nonNull).findFirst();
|
||||||
optionalLabel.ifPresent(txo::setLabel);
|
optionalLabel.ifPresent(txo::setLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!wallet.getDetachedLabels().isEmpty()) {
|
||||||
|
String label = wallet.getDetachedLabels().remove(txo.getHash().toString() + "<" + txo.getIndex());
|
||||||
|
if(label != null && (txo.getLabel() == null || txo.getLabel().isEmpty())) {
|
||||||
|
txo.setLabel(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(txo.isSpent()) {
|
||||||
|
String spentByLabel = wallet.getDetachedLabels().remove(txo.getSpentBy().getHash() + ">" + txo.getSpentBy().getIndex());
|
||||||
|
if(spentByLabel != null && (txo.getSpentBy().getLabel() == null || txo.getSpentBy().getLabel().isEmpty())) {
|
||||||
|
txo.getSpentBy().setLabel(spentByLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transactionOutputs.clear();
|
transactionOutputs.clear();
|
||||||
transactionOutputs.addAll(updatedOutputs);
|
transactionOutputs.addAll(updatedOutputs);
|
||||||
}
|
}
|
||||||
|
@ -134,6 +150,20 @@ public class WalletNode extends Persistable implements Comparable<WalletNode> {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<WalletNode> fillToIndex(Wallet wallet, int index) {
|
||||||
|
Set<WalletNode> newNodes = fillToIndex(index);
|
||||||
|
if(!wallet.getDetachedLabels().isEmpty()) {
|
||||||
|
for(WalletNode newNode : newNodes) {
|
||||||
|
String label = wallet.getDetachedLabels().remove(wallet.getAddress(newNode).toString());
|
||||||
|
if(label != null && (newNode.getLabel() == null || newNode.getLabel().isEmpty())) {
|
||||||
|
newNode.setLabel(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newNodes;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized Set<WalletNode> fillToIndex(int index) {
|
public synchronized Set<WalletNode> fillToIndex(int index) {
|
||||||
Set<WalletNode> newNodes = new TreeSet<>();
|
Set<WalletNode> newNodes = new TreeSet<>();
|
||||||
for(int i = 0; i <= index; i++) {
|
for(int i = 0; i <= index; i++) {
|
||||||
|
|
Loading…
Reference in a new issue