Update extension for multi-GPU fix and better progress tracking

This commit is contained in:
Craig Raw 2026-03-30 14:33:07 +02:00
parent f12dd66401
commit 121d4131db
12 changed files with 45 additions and 20 deletions

3
.sdkmanrc Normal file
View File

@ -0,0 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=25.0.2-tem

View File

@ -18,7 +18,6 @@ import com.sparrowwallet.frigate.io.Storage;
import org.duckdb.DuckDBAppender;
import org.duckdb.DuckDBConnection;
import org.duckdb.DuckDBPreparedStatement;
import org.duckdb.QueryProgress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -88,6 +87,9 @@ public class Index {
});
if(backend.startsWith("cpu")) {
if(computeBackend == ComputeBackend.GPU) {
throw new ConfigurationException("No GPU detected, but \"computeBackend\" is set to \"GPU\". Set to \"AUTO\" or \"CPU\", or install a supported GPU.");
}
log.warn("No GPU detected, using CPU backend for scanning. Set \"computeBackend\": \"CPU\" in config to suppress this warning.");
} else {
log.info("Using {} backend for scanning", backend);
@ -97,6 +99,27 @@ public class Index {
}
}
private double pollScanProgress(byte[] scanKeyBytes) {
try {
return dbManager.executeRead(progressConnection -> {
try(PreparedStatement progressStmt = progressConnection.prepareStatement("SELECT ufsecp_progress(?)")) {
progressStmt.setBytes(1, scanKeyBytes);
ResultSet rs = progressStmt.executeQuery();
if(rs.next()) {
double pct = rs.getDouble(1);
if(pct < 0.0d) {
return 0.0d;
}
return Math.min(pct / 100.0d, 1.0d);
}
return 0.0d;
}
});
} catch(Exception e) {
return 0.0d;
}
}
public void close() {
dbManager.close();
}
@ -210,7 +233,7 @@ public class Index {
public List<TxEntry> getHistoryAsync(SilentPaymentScanAddress scanAddress, SilentPaymentsSubscription subscription, Integer startHeight, Integer endHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef) {
ConcurrentLinkedQueue<TxEntry> queue = new ConcurrentLinkedQueue<>();
AtomicLong rowsProcessedStart = new AtomicLong(0L);
byte[] scanKeyBytes = Utils.reverseBytes(scanAddress.getScanKey().getPrivKeyBytes());
try {
dbManager.executeRead(connection -> {
@ -237,18 +260,7 @@ public class Index {
return;
}
QueryProgress queryProgress = statement.getQueryProgress();
if(queryProgress.getRowsProcessed() == queryProgress.getTotalRowsToProcess()) {
return;
}
double progress = 0.0d;
if(rowsProcessedStart.get() == 0L && queryProgress.getRowsProcessed() > 0) {
rowsProcessedStart.set(queryProgress.getRowsProcessed());
}
if(rowsProcessedStart.get() > 0L) {
progress = (queryProgress.getRowsProcessed() - rowsProcessedStart.get()) / (double)(queryProgress.getTotalRowsToProcess() - rowsProcessedStart.get());
}
double progress = pollScanProgress(scanKeyBytes);
List<TxEntry> history = new ArrayList<>();
TxEntry entry;
@ -263,7 +275,7 @@ public class Index {
Frigate.getEventBus().post(new SilentPaymentsNotification(subscription, progress, new ArrayList<>(history), subscriptionStatusRef.get()));
history.clear();
}
} catch(SQLException e) {
} catch(Exception e) {
log.error("Error getting query progress", e);
}
}, 1, 1, TimeUnit.SECONDS);

View File

@ -10,6 +10,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.zip.GZIPInputStream;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.PosixFilePermission;
@ -47,12 +48,21 @@ public class Storage {
File extensionFile = new File(getFrigateCacheDir(), extensionFileName);
try(InputStream is = Storage.class.getResourceAsStream(resourcePath)) {
if(is == null) {
throw new IOException("Could not find " + extensionFileName + " for the current platform: " + osName + " " + osArch);
try {
InputStream is = Storage.class.getResourceAsStream(resourcePath);
if(is != null) {
try(is) {
Files.copy(is, extensionFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
} else {
InputStream gzIs = Storage.class.getResourceAsStream(resourcePath + ".gz");
if(gzIs == null) {
throw new IOException("Could not find " + extensionFileName + " for the current platform: " + osName + " " + osArch);
}
try(GZIPInputStream decompressed = new GZIPInputStream(gzIs)) {
Files.copy(decompressed, extensionFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
Files.copy(is, extensionFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch(IOException e) {
log.error("Error loading " + extensionFileName, e);
}