Compare commits

...

1 Commits

Author SHA1 Message Date
Craig Raw
ea40591d9f use cte in query to scan for change label 2025-09-12 15:45:40 +02:00
5 changed files with 23 additions and 20 deletions

2
drongo

@ -1 +1 @@
Subproject commit 0b3b1a5c3f45e1c81cdc15ea565c194ef615f814
Subproject commit 9c826d7819c9c20fb65b27f441797d509860b111

View File

@ -203,7 +203,7 @@ public class ElectrumServerService {
requestHandler.subscribeSilentPaymentsAddress(silentPaymentScanAddress);
int startHeight = getStartHeight(start);
indexQuerier.startHistoryScan(silentPaymentScanAddress, startHeight, null, new WeakReference<>(requestHandler));
indexQuerier.startHistoryScan(silentPaymentScanAddress, startHeight, new WeakReference<>(requestHandler));
return silentPaymentScanAddress.getAddress();
}

View File

@ -148,7 +148,7 @@ public class RequestHandler implements Runnable, SubscriptionStatus {
public void silentPaymentsBlocksIndexUpdate(SilentPaymentsBlocksIndexUpdate update) {
for(SilentPaymentAddressSubscription subscription : silentPaymentsAddressesSubscribed.values()) {
if(update.fromBlockHeight() > subscription.getHighestBlockHeight()) {
electrumServerService.getIndexQuerier().startHistoryScan(subscription.getAddress(), update.fromBlockHeight(), null, new WeakReference<>(this), false);
electrumServerService.getIndexQuerier().startHistoryScan(subscription.getAddress(), update.fromBlockHeight(), new WeakReference<>(this), false);
}
}
}

View File

@ -173,34 +173,37 @@ public class Index {
}
}
public List<TxEntry> getHistoryAsync(SilentPaymentScanAddress scanAddress, SilentPaymentsSubscription subscription, Integer startHeight, Integer endHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef) {
public List<TxEntry> getHistoryAsync(SilentPaymentScanAddress scanAddress, SilentPaymentsSubscription subscription, Integer startHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef, boolean includeChange) {
ConcurrentLinkedQueue<TxEntry> queue = new ConcurrentLinkedQueue<>();
AtomicLong rowsProcessedStart = new AtomicLong(0L);
try {
dbManager.executeRead(connection -> {
String sql = "SELECT txid, height FROM " + TWEAK_TABLE +
" WHERE list_contains(outputs, hash_prefix_to_int(secp256k1_ec_pubkey_combine([?, secp256k1_ec_pubkey_create(secp256k1_tagged_sha256('BIP0352/SharedSecret', secp256k1_ec_pubkey_tweak_mul(tweak_key, ?) || int_to_big_endian(0)))]), 1))";
String sql = "WITH computed_t AS (SELECT txid, height, outputs, tweak_key, secp256k1_ec_pubkey_create(secp256k1_tagged_sha256('BIP0352/SharedSecret', secp256k1_ec_pubkey_tweak_mul(tweak_key, ?) || int_to_big_endian(0))) AS t_0 FROM tweak";
if(startHeight != null) {
sql += " AND height >= ?";
sql += " WHERE height >= ?";
}
if(endHeight != null) {
sql += " AND height <= ?";
sql += "), spend_keys AS (SELECT ? AS spend_pubkey";
if(includeChange) {
sql += " UNION ALL SELECT ? AS spend_pubkey UNION ALL SELECT ? AS spend_pubkey";
}
sql += ") SELECT t.txid, t.height FROM computed_t t CROSS JOIN spend_keys sk WHERE list_contains(t.outputs, hash_prefix_to_int(secp256k1_ec_pubkey_combine([sk.spend_pubkey, t.t_0]), 1))";
try(DuckDBPreparedStatement statement = connection.prepareStatement(sql).unwrap(DuckDBPreparedStatement.class)) {
if(isUnsubscribed(scanAddress, subscriptionStatusRef)) {
return false;
}
statement.setBytes(1, scanAddress.getSpendKey().getPubKey());
statement.setBytes(2, scanAddress.getScanKey().getPrivKeyBytes());
statement.setBytes(1, scanAddress.getScanKey().getPrivKeyBytes());
if(startHeight != null) {
statement.setInt(3, startHeight);
statement.setInt(2, startHeight);
}
if(endHeight != null) {
statement.setInt(startHeight == null ? 3 : 4, endHeight);
statement.setBytes(startHeight == null ? 2 : 3, scanAddress.getSpendKey().getPubKey());
if(includeChange) {
statement.setBytes(startHeight == null ? 3 : 4, scanAddress.getChangeAddress().getSpendKey().getPubKey());
statement.setBytes(startHeight == null ? 4 : 5, scanAddress.getChangeAddress().getSpendKey().negate().getPubKey());
}
statement.setFetchSize(1);

View File

@ -33,14 +33,14 @@ public class IndexQuerier {
return t;
});
public void startHistoryScan(SilentPaymentScanAddress scanAddress, Integer startHeight, Integer endHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef) {
startHistoryScan(scanAddress, startHeight, endHeight, subscriptionStatusRef, true);
public void startHistoryScan(SilentPaymentScanAddress scanAddress, Integer startHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef) {
startHistoryScan(scanAddress, startHeight, subscriptionStatusRef, true);
}
public void startHistoryScan(SilentPaymentScanAddress scanAddress, Integer startHeight, Integer endHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef, boolean postIfEmpty) {
public void startHistoryScan(SilentPaymentScanAddress scanAddress, Integer startHeight, WeakReference<SubscriptionStatus> subscriptionStatusRef, boolean postIfEmpty) {
queryPool.submit(() -> {
SilentPaymentsSubscription subscription = new SilentPaymentsSubscription(scanAddress.toString(), startHeight == null ? 0 : startHeight);
List<TxEntry> history = blocksIndex.getHistoryAsync(scanAddress, subscription, startHeight, endHeight, subscriptionStatusRef);
List<TxEntry> history = blocksIndex.getHistoryAsync(scanAddress, subscription, startHeight, subscriptionStatusRef, true);
List<TxEntry> mempoolHistory = getMempoolHistory(scanAddress, subscriptionStatusRef, subscription);
history.addAll(mempoolHistory);
@ -62,7 +62,7 @@ public class IndexQuerier {
}
private List<TxEntry> getMempoolHistory(SilentPaymentScanAddress scanAddress, WeakReference<SubscriptionStatus> subscriptionStatusRef, SilentPaymentsSubscription subscription) {
List<TxEntry> mempoolHistory = mempoolIndex.getHistoryAsync(scanAddress, subscription, null, null, subscriptionStatusRef);
List<TxEntry> mempoolHistory = mempoolIndex.getHistoryAsync(scanAddress, subscription, null, subscriptionStatusRef, true);
SubscriptionStatus subscriptionStatus = subscriptionStatusRef.get();
if(subscriptionStatus != null && subscriptionStatus.getSilentPaymentsMempoolTxids(scanAddress.toString()) != null) {
mempoolHistory.removeIf(txEntry -> subscriptionStatus.getSilentPaymentsMempoolTxids(scanAddress.toString()).contains(Sha256Hash.wrap(txEntry.tx_hash)));