mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2026-07-30 19:46:16 +00:00
hide wallet rescan hyperlink when nothing further can be scanned
This commit is contained in:
+1
-1
Submodule drongo updated: 29cd4b7909...e4b63fbd19
@@ -16,7 +16,10 @@ import com.sparrowwallet.sparrow.event.WalletDataChangedEvent;
|
||||
import com.sparrowwallet.sparrow.event.WalletHistoryStatusEvent;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import com.sparrowwallet.sparrow.net.ElectrumServer;
|
||||
import com.sparrowwallet.sparrow.net.ServerType;
|
||||
import com.sparrowwallet.sparrow.net.cormorant.Cormorant;
|
||||
import com.sparrowwallet.sparrow.net.cormorant.bitcoind.BitcoindClient;
|
||||
import com.sparrowwallet.sparrow.wallet.Entry;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
@@ -107,7 +110,7 @@ public class CoinTreeTable extends TreeTableView<Entry> {
|
||||
setPlaceholder(new Label("Error loading transactions: " + event.getErrorMessage()));
|
||||
} else if(event.isLoading()) {
|
||||
if(event.getStatusMessage() != null) {
|
||||
setPlaceholder(new Label(event.getStatusMessage() + "..."));
|
||||
setPlaceholder(new Label(event.getStatusMessage() + (event.getStatusMessage().contains("...") ? "" : "...")));
|
||||
} else {
|
||||
setPlaceholder(new Label("Loading transactions..."));
|
||||
}
|
||||
@@ -123,7 +126,7 @@ public class CoinTreeTable extends TreeTableView<Entry> {
|
||||
StackPane stackPane = new StackPane();
|
||||
stackPane.getChildren().add(AppServices.isConnecting() ? new Label("Loading transactions...") : new Label("No transactions"));
|
||||
|
||||
if((Config.get().getServerType() == ServerType.BITCOIN_CORE || wallet.getPolicyType() == PolicyType.SINGLE_SP) && !AppServices.isConnecting()) {
|
||||
if((Config.get().getServerType() == ServerType.BITCOIN_CORE || wallet.getPolicyType() == PolicyType.SINGLE_SP) && !AppServices.isConnecting() && !isFullyScanned(wallet)) {
|
||||
Hyperlink hyperlink = new Hyperlink();
|
||||
hyperlink.setTranslateY(30);
|
||||
hyperlink.setOnAction(event -> {
|
||||
@@ -150,12 +153,47 @@ public class CoinTreeTable extends TreeTableView<Entry> {
|
||||
}
|
||||
|
||||
stackPane.getChildren().add(hyperlink);
|
||||
} else if(!AppServices.isConnecting() && Config.get().getServerType() == ServerType.BITCOIN_CORE && isFullyScanned(wallet)) {
|
||||
Date prunedDate = getPrunedDate();
|
||||
if(prunedDate != null) {
|
||||
DateFormat dateFormat = new SimpleDateFormat(DateStringConverter.FORMAT_PATTERN);
|
||||
Label prunedLabel = new Label("Scanned to pruned start date of " + dateFormat.format(prunedDate));
|
||||
prunedLabel.setTranslateY(30);
|
||||
stackPane.getChildren().add(prunedLabel);
|
||||
}
|
||||
}
|
||||
|
||||
stackPane.setAlignment(Pos.CENTER);
|
||||
return stackPane;
|
||||
}
|
||||
|
||||
private boolean isFullyScanned(Wallet wallet) {
|
||||
if(wallet.getPolicyType() == PolicyType.SINGLE_SP) {
|
||||
return wallet.isValid() && ElectrumServer.isSilentPaymentsFullyCovered(wallet.getSilentPaymentScanAddress());
|
||||
}
|
||||
|
||||
if(Config.get().getServerType() == ServerType.BITCOIN_CORE) {
|
||||
Date prunedDate = getPrunedDate();
|
||||
return prunedDate != null && wallet.getBirthDate() != null && !wallet.getBirthDate().after(prunedDate);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Date getPrunedDate() {
|
||||
Cormorant cormorant = ElectrumServer.getCormorant();
|
||||
if(cormorant == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BitcoindClient bitcoindClient = cormorant.getBitcoindClient();
|
||||
if(bitcoindClient == null || !bitcoindClient.isPruned()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return bitcoindClient.getCachedPrunedDate();
|
||||
}
|
||||
|
||||
protected void setupColumnSort(int defaultColumnIndex, TreeTableColumn.SortType defaultSortType) {
|
||||
WalletTable.Sort columnSort = getSavedColumnSort();
|
||||
if(columnSort == null) {
|
||||
|
||||
@@ -89,6 +89,8 @@ public class ElectrumServer {
|
||||
|
||||
private static final Map<String, SilentPaymentsScanCache> spScanCaches = new ConcurrentHashMap<>();
|
||||
|
||||
private static final int TAPROOT_ACTIVATION_HEIGHT = 709632;
|
||||
|
||||
private final static Map<String, Integer> subscribedRecent = new ConcurrentHashMap<>();
|
||||
|
||||
private final static Map<String, String> broadcastRecent = new ConcurrentHashMap<>();
|
||||
@@ -1377,6 +1379,33 @@ public class ElectrumServer {
|
||||
return spScanCaches.containsKey(scanAddress.getAddress());
|
||||
}
|
||||
|
||||
public static boolean isSilentPaymentsFullyCovered(SilentPaymentScanAddress scanAddress) {
|
||||
if(scanAddress == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SilentPaymentsScanCache cache = spScanCaches.get(scanAddress.getAddress());
|
||||
if(cache == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cache.lock();
|
||||
try {
|
||||
Integer serverStart = cache.getServerStart();
|
||||
if(!cache.isCompleted() || serverStart == null) {
|
||||
return false;
|
||||
}
|
||||
int earliestPossibleStart = Network.get() == Network.MAINNET ? TAPROOT_ACTIVATION_HEIGHT : 0;
|
||||
return serverStart <= earliestPossibleStart;
|
||||
} finally {
|
||||
cache.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static Cormorant getCormorant() {
|
||||
return cormorant;
|
||||
}
|
||||
|
||||
private static void cancelSilentPaymentScans() {
|
||||
for(SilentPaymentsScanCache cache : spScanCaches.values()) {
|
||||
cache.lock();
|
||||
|
||||
@@ -43,6 +43,10 @@ class SilentPaymentsScanCache {
|
||||
return state == State.CANCELLED;
|
||||
}
|
||||
|
||||
boolean isCompleted() {
|
||||
return state == State.COMPLETED;
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
assert lock.isHeldByCurrentThread();
|
||||
if(state == State.SCANNING) {
|
||||
|
||||
@@ -115,4 +115,8 @@ public class Cormorant {
|
||||
public static EventBus getEventBus() {
|
||||
return EVENT_BUS;
|
||||
}
|
||||
|
||||
public BitcoindClient getBitcoindClient() {
|
||||
return bitcoindClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ public class BitcoindClient {
|
||||
private final boolean useWallets;
|
||||
private boolean pruned;
|
||||
private Integer pruneHeight;
|
||||
private volatile Date cachedPrunedDate;
|
||||
private boolean legacyWalletExists;
|
||||
|
||||
private final Lock syncingLock = new ReentrantLock();
|
||||
@@ -285,12 +286,18 @@ public class BitcoindClient {
|
||||
if(blockchainInfo.pruned()) {
|
||||
String pruneBlockHash = getBitcoindService().getBlockHash(blockchainInfo.pruneheight());
|
||||
VerboseBlockHeader pruneBlockHeader = getBitcoindService().getBlockHeader(pruneBlockHash);
|
||||
return Optional.of(new Date(pruneBlockHeader.time() * 1000));
|
||||
Date prunedDate = new Date(pruneBlockHeader.time() * 1000);
|
||||
cachedPrunedDate = prunedDate;
|
||||
return Optional.of(prunedDate);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Date getCachedPrunedDate() {
|
||||
return cachedPrunedDate;
|
||||
}
|
||||
|
||||
private ScanDate getScanDate(String normalizedDescriptor, Wallet wallet, KeyPurpose keyPurpose, Date earliestBirthDate) {
|
||||
Integer range = (keyPurpose == null ? null : Math.max(getWalletRange(normalizedDescriptor, wallet, keyPurpose), getDefaultRange(wallet, keyPurpose)));
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ public class WalletForm {
|
||||
|
||||
boolean shouldHold = !spSubscriptionHeld;
|
||||
|
||||
ElectrumServer.SilentPaymentScanService scanService = new ElectrumServer.SilentPaymentScanService(wallet, shouldHold, computeNeededStart(wallet));
|
||||
ElectrumServer.SilentPaymentScanService scanService = new ElectrumServer.SilentPaymentScanService(wallet, shouldHold, wallet.getNeededScanStart());
|
||||
scanService.setOnSucceeded(workerStateEvent -> {
|
||||
spScanInProgress = false;
|
||||
spSubscriptionHeld = true;
|
||||
@@ -296,20 +296,6 @@ public class WalletForm {
|
||||
}
|
||||
}
|
||||
|
||||
private static int computeNeededStart(Wallet wallet) {
|
||||
Integer stored = wallet.getStoredBlockHeight();
|
||||
if(stored != null && stored > 0) {
|
||||
return Math.max(0, stored - BlockTransactionHash.BLOCKS_TO_FULLY_CONFIRM);
|
||||
}
|
||||
if(wallet.getBirthHeight() != null) {
|
||||
return Math.max(0, wallet.getBirthHeight() - BlockTransactionHash.BLOCKS_TO_FULLY_CONFIRM);
|
||||
}
|
||||
if(wallet.getBirthDate() != null) {
|
||||
return (int)(wallet.getBirthDate().getTime() / 1000L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void updateWallets(Integer blockHeight, Wallet previousWallet) {
|
||||
List<WalletNode> nestedHistoryChangedNodes = new ArrayList<>();
|
||||
for(Wallet childWallet : new ArrayList<>(wallet.getChildWallets())) {
|
||||
|
||||
Reference in New Issue
Block a user