mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2025-01-26 02:11:10 +00:00
enable electrum rpc batching on mempool-electrs servers
This commit is contained in:
parent
218c2720e0
commit
fdbcea1625
5 changed files with 75 additions and 19 deletions
|
@ -25,13 +25,11 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
|
|||
static final int RETRY_DELAY_SECS = 1;
|
||||
|
||||
private final AtomicLong idCounter;
|
||||
private final int maxTargetBlocks;
|
||||
|
||||
public BatchedElectrumServerRpc() {
|
||||
this.idCounter = new AtomicLong();
|
||||
}
|
||||
|
||||
public BatchedElectrumServerRpc(long idCounterValue) {
|
||||
public BatchedElectrumServerRpc(long idCounterValue, int maxTargetBlocks) {
|
||||
this.idCounter = new AtomicLong(idCounterValue);
|
||||
this.maxTargetBlocks = maxTargetBlocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -222,11 +220,19 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
|
|||
public Map<Integer, Double> getFeeEstimates(Transport transport, List<Integer> targetBlocks) {
|
||||
PagedBatchRequestBuilder<Integer, Double> batchRequest = PagedBatchRequestBuilder.create(transport, idCounter).keysType(Integer.class).returnType(Double.class);
|
||||
for(Integer targetBlock : targetBlocks) {
|
||||
batchRequest.add(targetBlock, "blockchain.estimatefee", targetBlock);
|
||||
if(targetBlock <= maxTargetBlocks) {
|
||||
batchRequest.add(targetBlock, "blockchain.estimatefee", targetBlock);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return batchRequest.execute();
|
||||
Map<Integer, Double> result = batchRequest.execute();
|
||||
for(Integer targetBlock : targetBlocks) {
|
||||
if(targetBlock > maxTargetBlocks) {
|
||||
result.put(targetBlock, result.values().stream().mapToDouble(v -> v).min().orElse(0.0001d));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch(JsonRpcBatchException e) {
|
||||
throw new ElectrumServerRpcException("Error getting fee estimates from connected server: " + e.getErrors(), e);
|
||||
} catch(Exception e) {
|
||||
|
|
|
@ -47,6 +47,8 @@ public class ElectrumServer {
|
|||
|
||||
private static final Version FULCRUM_MIN_BATCHING_VERSION = new Version("1.6.0");
|
||||
|
||||
private static final Version MEMPOOL_ELECTRS_MIN_BATCHING_VERSION = new Version("3.1.0");
|
||||
|
||||
public static final String CORE_ELECTRUM_HOST = "127.0.0.1";
|
||||
|
||||
private static final int MINIMUM_BROADCASTS = 2;
|
||||
|
@ -1021,15 +1023,15 @@ public class ElectrumServer {
|
|||
existingStatuses.add(status);
|
||||
}
|
||||
|
||||
public static boolean supportsBatching(List<String> serverVersion) {
|
||||
if(serverVersion.size() > 0) {
|
||||
String server = serverVersion.get(0).toLowerCase(Locale.ROOT);
|
||||
public static ServerCapability getServerCapability(List<String> serverVersion) {
|
||||
if(!serverVersion.isEmpty()) {
|
||||
String server = serverVersion.getFirst().toLowerCase(Locale.ROOT);
|
||||
if(server.contains("electrumx")) {
|
||||
return true;
|
||||
return new ServerCapability(true);
|
||||
}
|
||||
|
||||
if(server.startsWith("cormorant")) {
|
||||
return true;
|
||||
return new ServerCapability(true);
|
||||
}
|
||||
|
||||
if(server.startsWith("electrs/")) {
|
||||
|
@ -1041,7 +1043,7 @@ public class ElectrumServer {
|
|||
try {
|
||||
Version version = new Version(electrsVersion);
|
||||
if(version.compareTo(ELECTRS_MIN_BATCHING_VERSION) >= 0) {
|
||||
return true;
|
||||
return new ServerCapability(true);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
//ignore
|
||||
|
@ -1057,7 +1059,26 @@ public class ElectrumServer {
|
|||
try {
|
||||
Version version = new Version(fulcrumVersion);
|
||||
if(version.compareTo(FULCRUM_MIN_BATCHING_VERSION) >= 0) {
|
||||
return true;
|
||||
return new ServerCapability(true);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
if(server.startsWith("mempool-electrs")) {
|
||||
String mempoolElectrsVersion = server.substring("mempool-electrs".length()).trim();
|
||||
int dashIndex = mempoolElectrsVersion.indexOf('-');
|
||||
String mempoolElectrsSuffix = "";
|
||||
if(dashIndex > -1) {
|
||||
mempoolElectrsSuffix = mempoolElectrsVersion.substring(dashIndex);
|
||||
mempoolElectrsVersion = mempoolElectrsVersion.substring(0, dashIndex);
|
||||
}
|
||||
try {
|
||||
Version version = new Version(mempoolElectrsVersion);
|
||||
if(version.compareTo(MEMPOOL_ELECTRS_MIN_BATCHING_VERSION) > 0 ||
|
||||
(version.compareTo(MEMPOOL_ELECTRS_MIN_BATCHING_VERSION) == 0 && (!mempoolElectrsSuffix.contains("dev") || mempoolElectrsSuffix.contains("dev-249848d")))) {
|
||||
return new ServerCapability(true, 25);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
//ignore
|
||||
|
@ -1065,7 +1086,7 @@ public class ElectrumServer {
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return new ServerCapability(false);
|
||||
}
|
||||
|
||||
public static class ServerVersionService extends Service<List<String>> {
|
||||
|
@ -1196,9 +1217,10 @@ public class ElectrumServer {
|
|||
firstCall = false;
|
||||
|
||||
//If electrumx is detected, we can upgrade to batched RPC. Electrs/EPS do not support batching.
|
||||
if(supportsBatching(serverVersion)) {
|
||||
ServerCapability serverCapability = getServerCapability(serverVersion);
|
||||
if(serverCapability.supportsBatching()) {
|
||||
log.debug("Upgrading to batched JSON-RPC");
|
||||
electrumServerRpc = new BatchedElectrumServerRpc(electrumServerRpc.getIdCounterValue());
|
||||
electrumServerRpc = new BatchedElectrumServerRpc(electrumServerRpc.getIdCounterValue(), serverCapability.getMaxTargetBlocks());
|
||||
}
|
||||
|
||||
BlockHeaderTip tip;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.sparrowwallet.sparrow.net;
|
||||
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
|
||||
public class ServerCapability {
|
||||
private final boolean supportsBatching;
|
||||
private final int maxTargetBlocks;
|
||||
|
||||
public ServerCapability(boolean supportsBatching) {
|
||||
this.supportsBatching = supportsBatching;
|
||||
this.maxTargetBlocks = AppServices.TARGET_BLOCKS_RANGE.getLast();
|
||||
}
|
||||
|
||||
public ServerCapability(boolean supportsBatching, int maxTargetBlocks) {
|
||||
this.supportsBatching = supportsBatching;
|
||||
this.maxTargetBlocks = maxTargetBlocks;
|
||||
}
|
||||
|
||||
public boolean supportsBatching() {
|
||||
return supportsBatching;
|
||||
}
|
||||
|
||||
public int getMaxTargetBlocks() {
|
||||
return maxTargetBlocks;
|
||||
}
|
||||
}
|
|
@ -603,7 +603,8 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
testConnection.setGraphic(getGlyph(FontAwesome5.Glyph.CHECK_CIRCLE, "success"));
|
||||
if(serverVersion != null) {
|
||||
testResults.setText("Connected to " + serverVersion.get(0) + " on protocol version " + serverVersion.get(1));
|
||||
if(ElectrumServer.supportsBatching(serverVersion)) {
|
||||
ServerCapability serverCapability = ElectrumServer.getServerCapability(serverVersion);
|
||||
if(serverCapability.supportsBatching()) {
|
||||
testResults.setText(testResults.getText() + "\nBatched RPC enabled.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,8 @@ public class ServerTestDialog extends DialogWindow {
|
|||
testStatus.setText("Success");
|
||||
if(serverVersion != null) {
|
||||
testResults.setText("Connected to " + serverVersion.get(0) + " on protocol version " + serverVersion.get(1));
|
||||
if(ElectrumServer.supportsBatching(serverVersion)) {
|
||||
ServerCapability serverCapability = ElectrumServer.getServerCapability(serverVersion);
|
||||
if(serverCapability.supportsBatching()) {
|
||||
testResults.setText(testResults.getText() + "\nBatched RPC enabled.");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue