mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2025-11-05 11:56:37 +00:00
improve electrum server script hash unsubscribe support
This commit is contained in:
parent
364909cfa3
commit
4d93381124
4 changed files with 45 additions and 12 deletions
|
|
@ -69,6 +69,7 @@ public class Config {
|
|||
private File coreDataDir;
|
||||
private String coreAuth;
|
||||
private boolean useLegacyCoreWallet;
|
||||
private boolean legacyServer;
|
||||
private Server electrumServer;
|
||||
private List<Server> recentElectrumServers;
|
||||
private File electrumServerCert;
|
||||
|
|
@ -549,6 +550,15 @@ public class Config {
|
|||
flush();
|
||||
}
|
||||
|
||||
public boolean isLegacyServer() {
|
||||
return legacyServer;
|
||||
}
|
||||
|
||||
public void setLegacyServer(boolean legacyServer) {
|
||||
this.legacyServer = legacyServer;
|
||||
flush();
|
||||
}
|
||||
|
||||
public Server getElectrumServer() {
|
||||
return electrumServer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ public class ElectrumPersonalServer implements WalletExport {
|
|||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
|
||||
writer.write("# Electrum Personal Server configuration file fragments\n");
|
||||
writer.write("# Copy the lines below into the relevant sections in your EPS config.ini file\n\n");
|
||||
writer.write("# First close Sparrow and edit your config file in Sparrow home to set \"legacyServer\": true\n");
|
||||
writer.write("# Then copy the lines below into the relevant sections in your EPS config.ini file\n\n");
|
||||
writer.write("# Copy into [master-public-keys] section\n");
|
||||
Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet();
|
||||
writeWalletXpub(masterWallet, writer);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class ElectrumServer {
|
|||
|
||||
private static final Set<String> sameHeightTxioScriptHashes = ConcurrentHashMap.newKeySet();
|
||||
|
||||
private final static Set<String> subscribedRecent = ConcurrentHashMap.newKeySet();
|
||||
private final static Map<String, Integer> subscribedRecent = new ConcurrentHashMap<>();
|
||||
|
||||
private final static Map<String, String> broadcastRecent = new ConcurrentHashMap<>();
|
||||
|
||||
|
|
@ -1255,7 +1255,7 @@ public class ElectrumServer {
|
|||
if(!serverVersion.isEmpty()) {
|
||||
String server = serverVersion.getFirst().toLowerCase(Locale.ROOT);
|
||||
if(server.contains("electrumx")) {
|
||||
return new ServerCapability(true, false);
|
||||
return new ServerCapability(true, true);
|
||||
}
|
||||
|
||||
if(server.startsWith("cormorant")) {
|
||||
|
|
@ -1312,6 +1312,10 @@ public class ElectrumServer {
|
|||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
if(server.startsWith("electrumpersonalserver")) {
|
||||
return new ServerCapability(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
return new ServerCapability(false, true);
|
||||
|
|
@ -1626,7 +1630,7 @@ public class ElectrumServer {
|
|||
|
||||
try {
|
||||
electrumServerRpc.subscribeScriptHashes(transport, null, subscribeScriptHashes);
|
||||
subscribedRecent.addAll(subscribeScriptHashes.values());
|
||||
subscribeScriptHashes.values().forEach(scriptHash -> subscribedRecent.put(scriptHash, AppServices.getCurrentBlockHeight()));
|
||||
} catch(ElectrumServerRpcException e) {
|
||||
log.debug("Error subscribing to recent mempool transaction outputs", e);
|
||||
}
|
||||
|
|
@ -2032,7 +2036,7 @@ public class ElectrumServer {
|
|||
Config config = Config.get();
|
||||
if(!isBlockstorm(totalBlocks) && !AppServices.isUsingProxy() && config.getServer().getProtocol().equals(Protocol.SSL)
|
||||
&& (config.getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER || config.getServerType() == ServerType.ELECTRUM_SERVER)) {
|
||||
subscribeRecent(electrumServer);
|
||||
subscribeRecent(electrumServer, AppServices.getCurrentBlockHeight() == null ? endHeight : AppServices.getCurrentBlockHeight());
|
||||
}
|
||||
|
||||
Double nextBlockMedianFeeRate = null;
|
||||
|
|
@ -2048,13 +2052,14 @@ public class ElectrumServer {
|
|||
return Network.get() != Network.MAINNET && totalBlocks > 2;
|
||||
}
|
||||
|
||||
private void subscribeRecent(ElectrumServer electrumServer) {
|
||||
Set<String> unsubscribeScriptHashes = new HashSet<>(subscribedRecent);
|
||||
private void subscribeRecent(ElectrumServer electrumServer, int currentHeight) {
|
||||
Set<String> unsubscribeScriptHashes = subscribedRecent.entrySet().stream().filter(entry -> entry.getValue() == null || entry.getValue() <= currentHeight - 3)
|
||||
.map(Map.Entry::getKey).collect(Collectors.toSet());
|
||||
unsubscribeScriptHashes.removeIf(subscribedScriptHashes::containsKey);
|
||||
if(!unsubscribeScriptHashes.isEmpty() && serverCapability.supportsUnsubscribe()) {
|
||||
electrumServerRpc.unsubscribeScriptHashes(transport, unsubscribeScriptHashes);
|
||||
}
|
||||
subscribedRecent.removeAll(unsubscribeScriptHashes);
|
||||
subscribedRecent.keySet().removeAll(unsubscribeScriptHashes);
|
||||
broadcastRecent.clear();
|
||||
|
||||
Map<String, String> subscribeScriptHashes = new HashMap<>();
|
||||
|
|
@ -2074,7 +2079,7 @@ public class ElectrumServer {
|
|||
|
||||
if(!subscribeScriptHashes.isEmpty()) {
|
||||
Random random = new Random();
|
||||
int additionalRandomScriptHashes = random.nextInt(4) + 4;
|
||||
int additionalRandomScriptHashes = random.nextInt(8);
|
||||
for(int i = 0; i < additionalRandomScriptHashes; i++) {
|
||||
byte[] randomScriptHashBytes = new byte[32];
|
||||
random.nextBytes(randomScriptHashBytes);
|
||||
|
|
@ -2086,7 +2091,7 @@ public class ElectrumServer {
|
|||
|
||||
try {
|
||||
electrumServerRpc.subscribeScriptHashes(transport, null, subscribeScriptHashes);
|
||||
subscribedRecent.addAll(subscribeScriptHashes.values());
|
||||
subscribeScriptHashes.values().forEach(scriptHash -> subscribedRecent.put(scriptHash, currentHeight));
|
||||
} catch(ElectrumServerRpcException e) {
|
||||
log.debug("Error subscribing to recent mempool transactions", e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.sparrowwallet.drongo.wallet.Wallet;
|
|||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.WalletHistoryStatusEvent;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -38,16 +39,32 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
|||
|
||||
@Override
|
||||
public List<String> getServerVersion(Transport transport, String clientName, String[] supportedVersions) {
|
||||
if(Config.get().isLegacyServer()) {
|
||||
return getLegacyServerVersion(transport, clientName);
|
||||
}
|
||||
|
||||
try {
|
||||
JsonRpcClient client = new JsonRpcClient(transport);
|
||||
//Using 1.4 as the version number as EPS tries to parse this number to a float :(
|
||||
return new RetryLogic<List<String>>(MAX_RETRIES, RETRY_DELAY, IllegalStateException.class).getResult(() ->
|
||||
client.createRequest().returnAsList(String.class).method("server.version").id(idCounter.incrementAndGet()).params(clientName, "1.4").execute());
|
||||
client.createRequest().returnAsList(String.class).method("server.version").id(idCounter.incrementAndGet()).params(clientName, supportedVersions).execute());
|
||||
} catch(JsonRpcException e) {
|
||||
return getLegacyServerVersion(transport, clientName);
|
||||
} catch(Exception e) {
|
||||
throw new ElectrumServerRpcException("Error getting server version", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getLegacyServerVersion(Transport transport, String clientName) {
|
||||
try {
|
||||
//Fallback to using 1.4 as the version number as EPS tries to parse this number to a float :(
|
||||
JsonRpcClient client = new JsonRpcClient(transport);
|
||||
return new RetryLogic<List<String>>(MAX_RETRIES, RETRY_DELAY, IllegalStateException.class).getResult(() ->
|
||||
client.createRequest().returnAsList(String.class).method("server.version").id(idCounter.incrementAndGet()).params(clientName, "1.4").execute());
|
||||
} catch(Exception ex) {
|
||||
throw new ElectrumServerRpcException("Error getting legacy server version", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerBanner(Transport transport) {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in a new issue