mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 13:16:44 +00:00
cormorant: fix descriptor range calculation and extend range from pruned date only where necessary
This commit is contained in:
parent
d425933189
commit
6ee3755ce4
1 changed files with 16 additions and 13 deletions
|
@ -46,6 +46,8 @@ public class BitcoindClient {
|
||||||
private static final int DEFAULT_GAP_LIMIT = 1000;
|
private static final int DEFAULT_GAP_LIMIT = 1000;
|
||||||
private static final int POSTMIX_GAP_LIMIT = 4000;
|
private static final int POSTMIX_GAP_LIMIT = 4000;
|
||||||
|
|
||||||
|
private static final long PRUNED_RESCAN_TIMEGAP_MILLIS = 7200*1000;
|
||||||
|
|
||||||
private final JsonRpcClient jsonRpcClient;
|
private final JsonRpcClient jsonRpcClient;
|
||||||
private final Timer timer = new Timer(true);
|
private final Timer timer = new Timer(true);
|
||||||
private final Store store = new Store();
|
private final Store store = new Store();
|
||||||
|
@ -258,7 +260,7 @@ public class BitcoindClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScanDate getScanDate(String normalizedDescriptor, Wallet wallet, KeyPurpose keyPurpose, Date earliestBirthDate) {
|
private ScanDate getScanDate(String normalizedDescriptor, Wallet wallet, KeyPurpose keyPurpose, Date earliestBirthDate) {
|
||||||
Integer range = (keyPurpose == null ? null : getHighestUsedIndex(normalizedDescriptor, wallet, keyPurpose) + getGapLimit(wallet, keyPurpose));
|
Integer range = (keyPurpose == null ? null : Math.max(getHighestUsedIndex(normalizedDescriptor, wallet, keyPurpose) + wallet.getGapLimit(), getDefaultRange(wallet, keyPurpose)));
|
||||||
|
|
||||||
//Force a rescan if loading a wallet with a birthday later than existing transactions, or if the wallet birthdate has been set or changed to an earlier date from the last check
|
//Force a rescan if loading a wallet with a birthday later than existing transactions, or if the wallet birthdate has been set or changed to an earlier date from the last check
|
||||||
boolean forceRescan = false;
|
boolean forceRescan = false;
|
||||||
|
@ -277,8 +279,8 @@ public class BitcoindClient {
|
||||||
return descriptorUsedIndexes.compute(descriptor, (d, lastHighestUsedIndex) -> lastHighestUsedIndex == null ? highestUsedIndex : Math.max(highestUsedIndex, lastHighestUsedIndex));
|
return descriptorUsedIndexes.compute(descriptor, (d, lastHighestUsedIndex) -> lastHighestUsedIndex == null ? highestUsedIndex : Math.max(highestUsedIndex, lastHighestUsedIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getGapLimit(Wallet wallet, KeyPurpose keyPurpose) {
|
private int getDefaultRange(Wallet wallet, KeyPurpose keyPurpose) {
|
||||||
return Math.max(wallet.getGapLimit(), wallet.getStandardAccountType() == StandardAccount.WHIRLPOOL_POSTMIX && keyPurpose == KeyPurpose.RECEIVE ? POSTMIX_GAP_LIMIT : DEFAULT_GAP_LIMIT);
|
return wallet.getStandardAccountType() == StandardAccount.WHIRLPOOL_POSTMIX && keyPurpose == KeyPurpose.RECEIVE ? POSTMIX_GAP_LIMIT : DEFAULT_GAP_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importDescriptors(Map<String, ScanDate> descriptors) throws ScanDateBeforePruneException {
|
private void importDescriptors(Map<String, ScanDate> descriptors) throws ScanDateBeforePruneException {
|
||||||
|
@ -320,6 +322,7 @@ public class BitcoindClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<Date> optPrunedDate = pruned ? getPrunedDate() : Optional.empty();
|
||||||
Map<String, ScanDate> importingDescriptors = new LinkedHashMap<>(descriptors);
|
Map<String, ScanDate> importingDescriptors = new LinkedHashMap<>(descriptors);
|
||||||
importingDescriptors.keySet().removeAll(importedDescriptors.keySet());
|
importingDescriptors.keySet().removeAll(importedDescriptors.keySet());
|
||||||
for(Map.Entry<String, ScanDate> entry : descriptors.entrySet()) {
|
for(Map.Entry<String, ScanDate> entry : descriptors.entrySet()) {
|
||||||
|
@ -330,7 +333,10 @@ public class BitcoindClient {
|
||||||
ScanDate scanDate = entry.getValue();
|
ScanDate scanDate = entry.getValue();
|
||||||
ScanDate importedScanDate = importedDescriptors.get(entry.getKey());
|
ScanDate importedScanDate = importedDescriptors.get(entry.getKey());
|
||||||
if(scanDate.range != null && importedScanDate != null && importedScanDate.range != null && scanDate.range > importedScanDate.range) {
|
if(scanDate.range != null && importedScanDate != null && importedScanDate.range != null && scanDate.range > importedScanDate.range) {
|
||||||
importingDescriptors.put(entry.getKey(), new ScanDate(importedScanDate.rescanSince == null || scanDate.forceRescan ? scanDate.rescanSince : importedScanDate.rescanSince, scanDate.range, false));
|
Date rescanSince = scanDate.rescanSince != null && (importedScanDate.rescanSince == null || scanDate.rescanSince.before(importedScanDate.rescanSince)) ? scanDate.rescanSince : importedScanDate.rescanSince;
|
||||||
|
Optional<Date> optPrunedStart = optPrunedDate.map(date -> new Date(date.getTime() + PRUNED_RESCAN_TIMEGAP_MILLIS));
|
||||||
|
rescanSince = optPrunedStart.isPresent() && (rescanSince == null || optPrunedStart.get().after(rescanSince)) ? optPrunedStart.get() : rescanSince;
|
||||||
|
importingDescriptors.put(entry.getKey(), new ScanDate(rescanSince, scanDate.range, false));
|
||||||
} else if(scanDate.forceRescan) {
|
} else if(scanDate.forceRescan) {
|
||||||
if(scanDate.rescanSince != null && (importedScanDate == null || importedScanDate.rescanSince == null || scanDate.rescanSince.before(importedScanDate.rescanSince))) {
|
if(scanDate.rescanSince != null && (importedScanDate == null || importedScanDate.rescanSince == null || scanDate.rescanSince.before(importedScanDate.rescanSince))) {
|
||||||
importingDescriptors.put(entry.getKey(), new ScanDate(scanDate.rescanSince, importedScanDate != null ? importedScanDate.range : scanDate.range, false));
|
importingDescriptors.put(entry.getKey(), new ScanDate(scanDate.rescanSince, importedScanDate != null ? importedScanDate.range : scanDate.range, false));
|
||||||
|
@ -338,15 +344,12 @@ public class BitcoindClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pruned) {
|
if(optPrunedDate.isPresent()) {
|
||||||
Optional<Date> optPrunedDate = getPrunedDate();
|
Date prunedDate = optPrunedDate.get();
|
||||||
if(optPrunedDate.isPresent()) {
|
Optional<Map.Entry<String, ScanDate>> optPrePruneImport = importingDescriptors.entrySet().stream().filter(entry -> entry.getValue().rescanSince != null && entry.getValue().rescanSince.before(prunedDate)).findFirst();
|
||||||
Date prunedDate = optPrunedDate.get();
|
if(optPrePruneImport.isPresent()) {
|
||||||
Optional<Map.Entry<String, ScanDate>> optPrePruneImport = importingDescriptors.entrySet().stream().filter(entry -> entry.getValue().rescanSince != null && entry.getValue().rescanSince.before(prunedDate)).findFirst();
|
Map.Entry<String, ScanDate> prePruneImport = optPrePruneImport.get();
|
||||||
if(optPrePruneImport.isPresent()) {
|
throw new ScanDateBeforePruneException(prePruneImport.getKey(), prePruneImport.getValue().rescanSince, prunedDate);
|
||||||
Map.Entry<String, ScanDate> prePruneImport = optPrePruneImport.get();
|
|
||||||
throw new ScanDateBeforePruneException(prePruneImport.getKey(), prePruneImport.getValue().rescanSince, prunedDate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue