further improvements on wallet importing wrt pruned nodes

This commit is contained in:
Craig Raw 2023-02-01 14:30:24 +02:00
parent 2cd64aa650
commit 06026b0a09
2 changed files with 19 additions and 12 deletions

View file

@ -61,7 +61,6 @@ public class BitcoindClient {
private Exception lastPollException; private Exception lastPollException;
private boolean pruned; private boolean pruned;
private boolean prunedWarningShown = false;
private boolean legacyWalletExists; private boolean legacyWalletExists;
private final Lock syncingLock = new ReentrantLock(); private final Lock syncingLock = new ReentrantLock();
@ -148,7 +147,10 @@ public class BitcoindClient {
try { try {
importDescriptors(getWalletDescriptors(wallets)); importDescriptors(getWalletDescriptors(wallets));
} catch(ScanDateBeforePruneException e) { } catch(ScanDateBeforePruneException e) {
List<Wallet> prePruneWallets = wallets.stream().filter(wallet -> wallet.getBirthDate() != null && wallet.getBirthDate().before(e.getPrunedDate()) && wallet.isValid()).sorted(Comparator.comparingLong(o -> o.getBirthDate().getTime())).collect(Collectors.toList()); List<Wallet> prePruneWallets = wallets.stream()
.filter(wallet -> wallet.getBirthDate() != null && wallet.getBirthDate().before(e.getPrunedDate()) && wallet.isValid()
&& OutputDescriptor.getOutputDescriptor(wallet, KeyPurpose.RECEIVE).toString(false, true).equals(e.getDescriptor()))
.sorted(Comparator.comparingLong(o -> o.getBirthDate().getTime())).collect(Collectors.toList());
if(!prePruneWallets.isEmpty()) { if(!prePruneWallets.isEmpty()) {
Platform.runLater(() -> EventManager.get().post(new CormorantPruneStatusEvent("Error: Wallet birthday earlier than Bitcoin Core prune date", prePruneWallets.get(0), e.getRescanSince(), e.getPrunedDate(), legacyWalletExists))); Platform.runLater(() -> EventManager.get().post(new CormorantPruneStatusEvent("Error: Wallet birthday earlier than Bitcoin Core prune date", prePruneWallets.get(0), e.getRescanSince(), e.getPrunedDate(), legacyWalletExists)));
} }
@ -175,19 +177,18 @@ public class BitcoindClient {
private Map<String, ScanDate> getWalletDescriptors(Collection<Wallet> wallets) throws ImportFailedException { private Map<String, ScanDate> getWalletDescriptors(Collection<Wallet> wallets) throws ImportFailedException {
List<Wallet> validWallets = wallets.stream().filter(Wallet::isValid).collect(Collectors.toList()); List<Wallet> validWallets = wallets.stream().filter(Wallet::isValid).collect(Collectors.toList());
Date earliestBirthDate = validWallets.stream().map(Wallet::getBirthDate).filter(Objects::nonNull).sorted().findFirst().orElse(null);
Map<String, ScanDate> outputDescriptors = new LinkedHashMap<>(); Map<String, ScanDate> outputDescriptors = new LinkedHashMap<>();
for(Wallet wallet : validWallets) { for(Wallet wallet : validWallets) {
String receiveOutputDescriptor = OutputDescriptor.getOutputDescriptor(wallet, KeyPurpose.RECEIVE).toString(false, false); String receiveOutputDescriptor = OutputDescriptor.getOutputDescriptor(wallet, KeyPurpose.RECEIVE).toString(false, false);
addOutputDescriptor(outputDescriptors, receiveOutputDescriptor, wallet, KeyPurpose.RECEIVE, earliestBirthDate); addOutputDescriptor(outputDescriptors, receiveOutputDescriptor, wallet, KeyPurpose.RECEIVE, wallet.getBirthDate());
String changeOutputDescriptor = OutputDescriptor.getOutputDescriptor(wallet, KeyPurpose.CHANGE).toString(false, false); String changeOutputDescriptor = OutputDescriptor.getOutputDescriptor(wallet, KeyPurpose.CHANGE).toString(false, false);
addOutputDescriptor(outputDescriptors, changeOutputDescriptor, wallet, KeyPurpose.CHANGE, earliestBirthDate); addOutputDescriptor(outputDescriptors, changeOutputDescriptor, wallet, KeyPurpose.CHANGE, wallet.getBirthDate());
if(wallet.isMasterWallet() && wallet.hasPaymentCode()) { if(wallet.isMasterWallet() && wallet.hasPaymentCode()) {
Wallet notificationWallet = wallet.getNotificationWallet(); Wallet notificationWallet = wallet.getNotificationWallet();
WalletNode notificationNode = notificationWallet.getNode(KeyPurpose.NOTIFICATION); WalletNode notificationNode = notificationWallet.getNode(KeyPurpose.NOTIFICATION);
String notificationOutputDescriptor = OutputDescriptor.toDescriptorString(notificationNode.getAddress()); String notificationOutputDescriptor = OutputDescriptor.toDescriptorString(notificationNode.getAddress());
addOutputDescriptor(outputDescriptors, notificationOutputDescriptor, wallet, null, earliestBirthDate); addOutputDescriptor(outputDescriptors, notificationOutputDescriptor, wallet, null, wallet.getBirthDate());
for(Wallet childWallet : wallet.getChildWallets()) { for(Wallet childWallet : wallet.getChildWallets()) {
if(childWallet.isNested()) { if(childWallet.isNested()) {
@ -199,7 +200,7 @@ public class BitcoindClient {
purposeNode.fillToIndex(gapLimit - 1); purposeNode.fillToIndex(gapLimit - 1);
for(WalletNode addressNode : purposeNode.getChildren()) { for(WalletNode addressNode : purposeNode.getChildren()) {
String addressOutputDescriptor = OutputDescriptor.toDescriptorString(addressNode.getAddress()); String addressOutputDescriptor = OutputDescriptor.toDescriptorString(addressNode.getAddress());
addOutputDescriptor(outputDescriptors, addressOutputDescriptor, copyChildWallet, null, earliestBirthDate); addOutputDescriptor(outputDescriptors, addressOutputDescriptor, copyChildWallet, null, wallet.getBirthDate());
} }
} }
} }
@ -305,10 +306,10 @@ public class BitcoindClient {
Optional<Date> optPrunedDate = getPrunedDate(); Optional<Date> optPrunedDate = getPrunedDate();
if(optPrunedDate.isPresent()) { if(optPrunedDate.isPresent()) {
Date prunedDate = optPrunedDate.get(); Date prunedDate = optPrunedDate.get();
Optional<ScanDate> prePruneImport = importingDescriptors.values().stream().filter(scanDate -> scanDate.rescanSince != null && scanDate.rescanSince.before(prunedDate)).findFirst(); Optional<Map.Entry<String, ScanDate>> optPrePruneImport = importingDescriptors.entrySet().stream().filter(entry -> entry.getValue().rescanSince != null && entry.getValue().rescanSince.before(prunedDate)).findFirst();
if(prePruneImport.isPresent()) { if(optPrePruneImport.isPresent()) {
ScanDate scanDate = prePruneImport.get(); Map.Entry<String, ScanDate> prePruneImport = optPrePruneImport.get();
throw new ScanDateBeforePruneException(scanDate.rescanSince, prunedDate); throw new ScanDateBeforePruneException(prePruneImport.getKey(), prePruneImport.getValue().rescanSince, prunedDate);
} }
} }
} }

View file

@ -3,14 +3,20 @@ package com.sparrowwallet.sparrow.net.cormorant.bitcoind;
import java.util.Date; import java.util.Date;
public class ScanDateBeforePruneException extends Exception { public class ScanDateBeforePruneException extends Exception {
private final String descriptor;
private final Date rescanSince; private final Date rescanSince;
private final Date prunedDate; private final Date prunedDate;
public ScanDateBeforePruneException(Date rescanSince, Date prunedDate) { public ScanDateBeforePruneException(String descriptor, Date rescanSince, Date prunedDate) {
this.descriptor = descriptor;
this.rescanSince = rescanSince; this.rescanSince = rescanSince;
this.prunedDate = prunedDate; this.prunedDate = prunedDate;
} }
public String getDescriptor() {
return descriptor;
}
public Date getRescanSince() { public Date getRescanSince() {
return rescanSince; return rescanSince;
} }