mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
avoid losing tx, address and txo labels when performing a full wallet refresh
This commit is contained in:
parent
3ffb09c5e6
commit
11a0e3765b
5 changed files with 45 additions and 17 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 44b29b2b7b6cb849f645ce9db7af18691b438553
|
Subproject commit 3882a4b4bd9a738329bfffcaff72b477bb3a2d2f
|
|
@ -84,6 +84,7 @@ public class CoinTreeTable extends TreeTableView<Entry> {
|
||||||
WalletBirthDateDialog dlg = new WalletBirthDateDialog(wallet.getBirthDate());
|
WalletBirthDateDialog dlg = new WalletBirthDateDialog(wallet.getBirthDate());
|
||||||
Optional<Date> optDate = dlg.showAndWait();
|
Optional<Date> optDate = dlg.showAndWait();
|
||||||
if(optDate.isPresent()) {
|
if(optDate.isPresent()) {
|
||||||
|
Wallet pastWallet = wallet.copy();
|
||||||
wallet.setBirthDate(optDate.get());
|
wallet.setBirthDate(optDate.get());
|
||||||
Storage storage = AppServices.get().getOpenWallets().get(wallet);
|
Storage storage = AppServices.get().getOpenWallets().get(wallet);
|
||||||
if(storage != null) {
|
if(storage != null) {
|
||||||
|
@ -91,7 +92,7 @@ public class CoinTreeTable extends TreeTableView<Entry> {
|
||||||
EventManager.get().post(new WalletDataChangedEvent(wallet));
|
EventManager.get().post(new WalletDataChangedEvent(wallet));
|
||||||
//Trigger full wallet rescan
|
//Trigger full wallet rescan
|
||||||
wallet.clearHistory();
|
wallet.clearHistory();
|
||||||
EventManager.get().post(new WalletSettingsChangedEvent(wallet, storage.getWalletFile()));
|
EventManager.get().post(new WalletSettingsChangedEvent(wallet, pastWallet, storage.getWalletFile()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,13 +12,19 @@ import java.io.File;
|
||||||
* Note that all wallet detail controllers that share a WalletForm, and that class posts WalletNodesChangedEvent once it has cleared it's entry caches.
|
* Note that all wallet detail controllers that share a WalletForm, and that class posts WalletNodesChangedEvent once it has cleared it's entry caches.
|
||||||
*/
|
*/
|
||||||
public class WalletSettingsChangedEvent extends WalletChangedEvent {
|
public class WalletSettingsChangedEvent extends WalletChangedEvent {
|
||||||
|
private final Wallet pastWallet;
|
||||||
private final File walletFile;
|
private final File walletFile;
|
||||||
|
|
||||||
public WalletSettingsChangedEvent(Wallet wallet, File walletFile) {
|
public WalletSettingsChangedEvent(Wallet wallet, Wallet pastWallet, File walletFile) {
|
||||||
super(wallet);
|
super(wallet);
|
||||||
|
this.pastWallet = pastWallet;
|
||||||
this.walletFile = walletFile;
|
this.walletFile = walletFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Wallet getPastWallet() {
|
||||||
|
return pastWallet;
|
||||||
|
}
|
||||||
|
|
||||||
public File getWalletFile() {
|
public File getWalletFile() {
|
||||||
return walletFile;
|
return walletFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ public class SettingsWalletForm extends WalletForm {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAndRefresh() throws IOException {
|
public void saveAndRefresh() throws IOException {
|
||||||
|
Wallet pastWallet = wallet.copy();
|
||||||
|
|
||||||
boolean refreshAll = isRefreshNecessary(wallet, walletCopy);
|
boolean refreshAll = isRefreshNecessary(wallet, walletCopy);
|
||||||
if(refreshAll) {
|
if(refreshAll) {
|
||||||
walletCopy.clearNodes();
|
walletCopy.clearNodes();
|
||||||
|
@ -47,7 +49,7 @@ public class SettingsWalletForm extends WalletForm {
|
||||||
save();
|
save();
|
||||||
|
|
||||||
if(refreshAll) {
|
if(refreshAll) {
|
||||||
EventManager.get().post(new WalletSettingsChangedEvent(wallet, getWalletFile()));
|
EventManager.get().post(new WalletSettingsChangedEvent(wallet, pastWallet, getWalletFile()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.drongo.KeyPurpose;
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import com.sparrowwallet.sparrow.AppServices;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
|
@ -32,7 +34,7 @@ public class WalletForm {
|
||||||
public WalletForm(Storage storage, Wallet currentWallet) {
|
public WalletForm(Storage storage, Wallet currentWallet) {
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
this.wallet = currentWallet;
|
this.wallet = currentWallet;
|
||||||
refreshHistory(AppServices.getCurrentBlockHeight());
|
refreshHistory(AppServices.getCurrentBlockHeight(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Wallet getWallet() {
|
public Wallet getWallet() {
|
||||||
|
@ -60,27 +62,28 @@ public class WalletForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveAndRefresh() throws IOException {
|
public void saveAndRefresh() throws IOException {
|
||||||
|
Wallet pastWallet = wallet.copy();
|
||||||
wallet.clearHistory();
|
wallet.clearHistory();
|
||||||
save();
|
save();
|
||||||
refreshHistory(AppServices.getCurrentBlockHeight());
|
refreshHistory(AppServices.getCurrentBlockHeight(), pastWallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveBackup() throws IOException {
|
public void saveBackup() throws IOException {
|
||||||
storage.backupWallet();
|
storage.backupWallet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshHistory(Integer blockHeight) {
|
public void refreshHistory(Integer blockHeight, Wallet pastWallet) {
|
||||||
refreshHistory(blockHeight, null);
|
refreshHistory(blockHeight, pastWallet, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshHistory(Integer blockHeight, WalletNode node) {
|
public void refreshHistory(Integer blockHeight, Wallet pastWallet, WalletNode node) {
|
||||||
Wallet previousWallet = wallet.copy();
|
Wallet previousWallet = wallet.copy();
|
||||||
if(wallet.isValid() && AppServices.isConnected()) {
|
if(wallet.isValid() && AppServices.isConnected()) {
|
||||||
log.debug(node == null ? wallet.getName() + " refreshing full wallet history" : wallet.getName() + " requesting node wallet history for " + node.getDerivationPath());
|
log.debug(node == null ? wallet.getName() + " refreshing full wallet history" : wallet.getName() + " requesting node wallet history for " + node.getDerivationPath());
|
||||||
ElectrumServer.TransactionHistoryService historyService = new ElectrumServer.TransactionHistoryService(wallet, getWalletTransactionNodes(node));
|
ElectrumServer.TransactionHistoryService historyService = new ElectrumServer.TransactionHistoryService(wallet, getWalletTransactionNodes(node));
|
||||||
historyService.setOnSucceeded(workerStateEvent -> {
|
historyService.setOnSucceeded(workerStateEvent -> {
|
||||||
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false));
|
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false));
|
||||||
updateWallet(previousWallet, blockHeight);
|
updateWallet(blockHeight, pastWallet, previousWallet);
|
||||||
});
|
});
|
||||||
historyService.setOnFailed(workerStateEvent -> {
|
historyService.setOnFailed(workerStateEvent -> {
|
||||||
log.error("Error retrieving wallet history", workerStateEvent.getSource().getException());
|
log.error("Error retrieving wallet history", workerStateEvent.getSource().getException());
|
||||||
|
@ -91,15 +94,31 @@ public class WalletForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateWallet(Wallet previousWallet, Integer blockHeight) {
|
private void updateWallet(Integer blockHeight, Wallet pastWallet, Wallet previousWallet) {
|
||||||
if(blockHeight != null) {
|
if(blockHeight != null) {
|
||||||
wallet.setStoredBlockHeight(blockHeight);
|
wallet.setStoredBlockHeight(blockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyIfChanged(previousWallet, blockHeight);
|
if(pastWallet != null) {
|
||||||
|
copyLabels(pastWallet);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyIfChanged(blockHeight, previousWallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyIfChanged(Wallet previousWallet, Integer blockHeight) {
|
private void copyLabels(Wallet pastWallet) {
|
||||||
|
wallet.getNode(KeyPurpose.RECEIVE).copyLabels(pastWallet.getNode(KeyPurpose.RECEIVE));
|
||||||
|
wallet.getNode(KeyPurpose.CHANGE).copyLabels(pastWallet.getNode(KeyPurpose.CHANGE));
|
||||||
|
|
||||||
|
for(Map.Entry<Sha256Hash, BlockTransaction> txEntry : wallet.getTransactions().entrySet()) {
|
||||||
|
BlockTransaction pastBlockTransaction = pastWallet.getTransactions().get(txEntry.getKey());
|
||||||
|
if(pastBlockTransaction != null && txEntry.getValue() != null && txEntry.getValue().getLabel() == null && pastBlockTransaction.getLabel() != null) {
|
||||||
|
txEntry.getValue().setLabel(pastBlockTransaction.getLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyIfChanged(Integer blockHeight, Wallet previousWallet) {
|
||||||
List<WalletNode> historyChangedNodes = new ArrayList<>();
|
List<WalletNode> historyChangedNodes = new ArrayList<>();
|
||||||
historyChangedNodes.addAll(getHistoryChangedNodes(previousWallet.getNode(KeyPurpose.RECEIVE).getChildren(), wallet.getNode(KeyPurpose.RECEIVE).getChildren()));
|
historyChangedNodes.addAll(getHistoryChangedNodes(previousWallet.getNode(KeyPurpose.RECEIVE).getChildren(), wallet.getNode(KeyPurpose.RECEIVE).getChildren()));
|
||||||
historyChangedNodes.addAll(getHistoryChangedNodes(previousWallet.getNode(KeyPurpose.CHANGE).getChildren(), wallet.getNode(KeyPurpose.CHANGE).getChildren()));
|
historyChangedNodes.addAll(getHistoryChangedNodes(previousWallet.getNode(KeyPurpose.CHANGE).getChildren(), wallet.getNode(KeyPurpose.CHANGE).getChildren()));
|
||||||
|
@ -226,7 +245,7 @@ public class WalletForm {
|
||||||
walletUtxosEntry = null;
|
walletUtxosEntry = null;
|
||||||
accountEntries.clear();
|
accountEntries.clear();
|
||||||
EventManager.get().post(new WalletNodesChangedEvent(wallet));
|
EventManager.get().post(new WalletNodesChangedEvent(wallet));
|
||||||
refreshHistory(AppServices.getCurrentBlockHeight());
|
refreshHistory(AppServices.getCurrentBlockHeight(), event.getPastWallet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,13 +253,13 @@ public class WalletForm {
|
||||||
public void newBlock(NewBlockEvent event) {
|
public void newBlock(NewBlockEvent event) {
|
||||||
//Check if wallet is valid to avoid saving wallets in initial setup
|
//Check if wallet is valid to avoid saving wallets in initial setup
|
||||||
if(wallet.isValid()) {
|
if(wallet.isValid()) {
|
||||||
updateWallet(wallet.copy(), event.getHeight());
|
updateWallet(event.getHeight(), null, wallet.copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void connected(ConnectionEvent event) {
|
public void connected(ConnectionEvent event) {
|
||||||
refreshHistory(event.getBlockHeight());
|
refreshHistory(event.getBlockHeight(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -249,7 +268,7 @@ public class WalletForm {
|
||||||
WalletNode walletNode = event.getWalletNode(wallet);
|
WalletNode walletNode = event.getWalletNode(wallet);
|
||||||
if(walletNode != null) {
|
if(walletNode != null) {
|
||||||
log.debug(wallet.getName() + " history event for node " + walletNode + " (" + event.getScriptHash() + ")");
|
log.debug(wallet.getName() + " history event for node " + walletNode + " (" + event.getScriptHash() + ")");
|
||||||
refreshHistory(AppServices.getCurrentBlockHeight(), walletNode);
|
refreshHistory(AppServices.getCurrentBlockHeight(), null, walletNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue