detect if electrum server supports scripthash unsubscribe capability

This commit is contained in:
Craig Raw 2025-06-03 12:38:03 +02:00
parent 8885e48ed9
commit 38f0068411
2 changed files with 23 additions and 14 deletions

View file

@ -1255,11 +1255,11 @@ public class ElectrumServer {
if(!serverVersion.isEmpty()) { if(!serverVersion.isEmpty()) {
String server = serverVersion.getFirst().toLowerCase(Locale.ROOT); String server = serverVersion.getFirst().toLowerCase(Locale.ROOT);
if(server.contains("electrumx")) { if(server.contains("electrumx")) {
return new ServerCapability(true); return new ServerCapability(true, false);
} }
if(server.startsWith("cormorant")) { if(server.startsWith("cormorant")) {
return new ServerCapability(true, false, true); return new ServerCapability(true, false, true, false);
} }
if(server.startsWith("electrs/")) { if(server.startsWith("electrs/")) {
@ -1271,7 +1271,7 @@ public class ElectrumServer {
try { try {
Version version = new Version(electrsVersion); Version version = new Version(electrsVersion);
if(version.compareTo(ELECTRS_MIN_BATCHING_VERSION) >= 0) { if(version.compareTo(ELECTRS_MIN_BATCHING_VERSION) >= 0) {
return new ServerCapability(true); return new ServerCapability(true, true);
} }
} catch(Exception e) { } catch(Exception e) {
//ignore //ignore
@ -1287,7 +1287,7 @@ public class ElectrumServer {
try { try {
Version version = new Version(fulcrumVersion); Version version = new Version(fulcrumVersion);
if(version.compareTo(FULCRUM_MIN_BATCHING_VERSION) >= 0) { if(version.compareTo(FULCRUM_MIN_BATCHING_VERSION) >= 0) {
return new ServerCapability(true); return new ServerCapability(true, true);
} }
} catch(Exception e) { } catch(Exception e) {
//ignore //ignore
@ -1306,7 +1306,7 @@ public class ElectrumServer {
Version version = new Version(mempoolElectrsVersion); Version version = new Version(mempoolElectrsVersion);
if(version.compareTo(MEMPOOL_ELECTRS_MIN_BATCHING_VERSION) > 0 || if(version.compareTo(MEMPOOL_ELECTRS_MIN_BATCHING_VERSION) > 0 ||
(version.compareTo(MEMPOOL_ELECTRS_MIN_BATCHING_VERSION) == 0 && (!mempoolElectrsSuffix.contains("dev") || mempoolElectrsSuffix.contains("dev-249848d")))) { (version.compareTo(MEMPOOL_ELECTRS_MIN_BATCHING_VERSION) == 0 && (!mempoolElectrsSuffix.contains("dev") || mempoolElectrsSuffix.contains("dev-249848d")))) {
return new ServerCapability(true, 25); return new ServerCapability(true, 25, false);
} }
} catch(Exception e) { } catch(Exception e) {
//ignore //ignore
@ -1314,7 +1314,7 @@ public class ElectrumServer {
} }
} }
return new ServerCapability(false); return new ServerCapability(false, true);
} }
public static class ServerVersionService extends Service<List<String>> { public static class ServerVersionService extends Service<List<String>> {
@ -2051,7 +2051,9 @@ public class ElectrumServer {
private void subscribeRecent(ElectrumServer electrumServer) { private void subscribeRecent(ElectrumServer electrumServer) {
Set<String> unsubscribeScriptHashes = new HashSet<>(subscribedRecent); Set<String> unsubscribeScriptHashes = new HashSet<>(subscribedRecent);
unsubscribeScriptHashes.removeIf(subscribedScriptHashes::containsKey); unsubscribeScriptHashes.removeIf(subscribedScriptHashes::containsKey);
electrumServerRpc.unsubscribeScriptHashes(transport, unsubscribeScriptHashes); if(!unsubscribeScriptHashes.isEmpty() && serverCapability.supportsUnsubscribe()) {
electrumServerRpc.unsubscribeScriptHashes(transport, unsubscribeScriptHashes);
}
subscribedRecent.removeAll(unsubscribeScriptHashes); subscribedRecent.removeAll(unsubscribeScriptHashes);
broadcastRecent.clear(); broadcastRecent.clear();
@ -2072,7 +2074,7 @@ public class ElectrumServer {
if(!subscribeScriptHashes.isEmpty()) { if(!subscribeScriptHashes.isEmpty()) {
Random random = new Random(); Random random = new Random();
int additionalRandomScriptHashes = random.nextInt(8) + 4; int additionalRandomScriptHashes = random.nextInt(4) + 4;
for(int i = 0; i < additionalRandomScriptHashes; i++) { for(int i = 0; i < additionalRandomScriptHashes; i++) {
byte[] randomScriptHashBytes = new byte[32]; byte[] randomScriptHashBytes = new byte[32];
random.nextBytes(randomScriptHashBytes); random.nextBytes(randomScriptHashBytes);

View file

@ -7,27 +7,30 @@ public class ServerCapability {
private final int maxTargetBlocks; private final int maxTargetBlocks;
private final boolean supportsRecentMempool; private final boolean supportsRecentMempool;
private final boolean supportsBlockStats; private final boolean supportsBlockStats;
private final boolean supportsUnsubscribe;
public ServerCapability(boolean supportsBatching) { public ServerCapability(boolean supportsBatching, boolean supportsUnsubscribe) {
this(supportsBatching, AppServices.TARGET_BLOCKS_RANGE.getLast()); this(supportsBatching, AppServices.TARGET_BLOCKS_RANGE.getLast(), supportsUnsubscribe);
} }
public ServerCapability(boolean supportsBatching, int maxTargetBlocks) { public ServerCapability(boolean supportsBatching, int maxTargetBlocks, boolean supportsUnsubscribe) {
this.supportsBatching = supportsBatching; this.supportsBatching = supportsBatching;
this.maxTargetBlocks = maxTargetBlocks; this.maxTargetBlocks = maxTargetBlocks;
this.supportsRecentMempool = false; this.supportsRecentMempool = false;
this.supportsBlockStats = false; this.supportsBlockStats = false;
this.supportsUnsubscribe = supportsUnsubscribe;
} }
public ServerCapability(boolean supportsBatching, boolean supportsRecentMempool, boolean supportsBlockStats) { public ServerCapability(boolean supportsBatching, boolean supportsRecentMempool, boolean supportsBlockStats, boolean supportsUnsubscribe) {
this(supportsBatching, AppServices.TARGET_BLOCKS_RANGE.getLast(), supportsRecentMempool, supportsBlockStats); this(supportsBatching, AppServices.TARGET_BLOCKS_RANGE.getLast(), supportsRecentMempool, supportsBlockStats, supportsUnsubscribe);
} }
public ServerCapability(boolean supportsBatching, int maxTargetBlocks, boolean supportsRecentMempool, boolean supportsBlockStats) { public ServerCapability(boolean supportsBatching, int maxTargetBlocks, boolean supportsRecentMempool, boolean supportsBlockStats, boolean supportsUnsubscribe) {
this.supportsBatching = supportsBatching; this.supportsBatching = supportsBatching;
this.maxTargetBlocks = maxTargetBlocks; this.maxTargetBlocks = maxTargetBlocks;
this.supportsRecentMempool = supportsRecentMempool; this.supportsRecentMempool = supportsRecentMempool;
this.supportsBlockStats = supportsBlockStats; this.supportsBlockStats = supportsBlockStats;
this.supportsUnsubscribe = supportsUnsubscribe;
} }
public boolean supportsBatching() { public boolean supportsBatching() {
@ -45,4 +48,8 @@ public class ServerCapability {
public boolean supportsBlockStats() { public boolean supportsBlockStats() {
return supportsBlockStats; return supportsBlockStats;
} }
public boolean supportsUnsubscribe() {
return supportsUnsubscribe;
}
} }