mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
refactor transport and speedup private server delay on connection failure
This commit is contained in:
parent
04917c45b6
commit
258fe34101
5 changed files with 53 additions and 28 deletions
|
@ -73,9 +73,11 @@ public class AppServices {
|
|||
|
||||
private static final int SERVER_PING_PERIOD_SECS = 60;
|
||||
private static final int PUBLIC_SERVER_RETRY_PERIOD_SECS = 3;
|
||||
private static final int PRIVATE_SERVER_RETRY_PERIOD_SECS = 15;
|
||||
public static final int ENUMERATE_HW_PERIOD_SECS = 30;
|
||||
private static final int RATES_PERIOD_SECS = 5 * 60;
|
||||
private static final int VERSION_CHECK_PERIOD_HOURS = 24;
|
||||
private static final int CONNECTION_DELAY_SECS = 2;
|
||||
private static final ExchangeSource DEFAULT_EXCHANGE_SOURCE = ExchangeSource.COINGECKO;
|
||||
private static final Currency DEFAULT_FIAT_CURRENCY = Currency.getInstance("USD");
|
||||
private static final String TOR_DEFAULT_PROXY_CIRCUIT_ID = "default";
|
||||
|
@ -251,7 +253,7 @@ public class AppServices {
|
|||
private ElectrumServer.ConnectionService createConnectionService() {
|
||||
ElectrumServer.ConnectionService connectionService = new ElectrumServer.ConnectionService();
|
||||
//Delay startup on first connection to Bitcoin Core to allow any unencrypted wallets to open first
|
||||
connectionService.setDelay(Config.get().getServerType() == ServerType.BITCOIN_CORE ? Duration.seconds(2) : Duration.ZERO);
|
||||
connectionService.setDelay(Config.get().getServerType() == ServerType.BITCOIN_CORE ? Duration.seconds(CONNECTION_DELAY_SECS) : Duration.ZERO);
|
||||
connectionService.setPeriod(Duration.seconds(SERVER_PING_PERIOD_SECS));
|
||||
connectionService.setRestartOnFailure(true);
|
||||
EventManager.get().register(connectionService);
|
||||
|
@ -323,6 +325,8 @@ public class AppServices {
|
|||
if(Config.get().getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER) {
|
||||
Config.get().changePublicServer();
|
||||
connectionService.setPeriod(Duration.seconds(PUBLIC_SERVER_RETRY_PERIOD_SECS));
|
||||
} else {
|
||||
connectionService.setPeriod(Duration.seconds(PRIVATE_SERVER_RETRY_PERIOD_SECS));
|
||||
}
|
||||
|
||||
log.debug("Connection failed", failEvent.getSource().getException());
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package com.sparrowwallet.sparrow.net;
|
||||
|
||||
import com.github.arteam.simplejsonrpc.client.Transport;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
public interface CloseableTransport extends Transport, Closeable {
|
||||
void connect() throws ServerException;
|
||||
boolean isConnected();
|
||||
boolean isClosed();
|
||||
}
|
|
@ -47,7 +47,7 @@ public class ElectrumServer {
|
|||
|
||||
public static final BlockTransaction UNFETCHABLE_BLOCK_TRANSACTION = new BlockTransaction(Sha256Hash.ZERO_HASH, 0, null, null, null);
|
||||
|
||||
private static Transport transport;
|
||||
private static CloseableTransport transport;
|
||||
|
||||
private static final Map<String, List<String>> subscribedScriptHashes = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class ElectrumServer {
|
|||
|
||||
private static final Pattern RPC_WALLET_LOADING_PATTERN = Pattern.compile(".*\"(Wallet loading failed:[^\"]*)\".*");
|
||||
|
||||
private static synchronized Transport getTransport() throws ServerException {
|
||||
private static synchronized CloseableTransport getTransport() throws ServerException {
|
||||
if(transport == null) {
|
||||
try {
|
||||
String electrumServer = null;
|
||||
|
@ -133,8 +133,8 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
public void connect() throws ServerException {
|
||||
TcpTransport tcpTransport = (TcpTransport)getTransport();
|
||||
tcpTransport.connect();
|
||||
CloseableTransport closeableTransport = getTransport();
|
||||
closeableTransport.connect();
|
||||
}
|
||||
|
||||
public void ping() throws ServerException {
|
||||
|
@ -163,12 +163,15 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
public static synchronized void closeActiveConnection() throws ServerException {
|
||||
if(transport != null) {
|
||||
closeConnection(transport);
|
||||
transport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void closeConnection(Closeable closeableTransport) throws ServerException {
|
||||
try {
|
||||
if(transport != null) {
|
||||
Closeable closeableTransport = (Closeable)transport;
|
||||
closeableTransport.close();
|
||||
transport = null;
|
||||
}
|
||||
closeableTransport.close();
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.security.cert.CertificateException;
|
|||
public enum Protocol {
|
||||
TCP {
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server) {
|
||||
public CloseableTransport getTransport(HostAndPort server) {
|
||||
if(isOnionAddress(server)) {
|
||||
return new TorTcpTransport(server);
|
||||
}
|
||||
|
@ -22,24 +22,24 @@ public enum Protocol {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, File serverCert) {
|
||||
public CloseableTransport getTransport(HostAndPort server, File serverCert) {
|
||||
return getTransport(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, HostAndPort proxy) {
|
||||
public CloseableTransport getTransport(HostAndPort server, HostAndPort proxy) {
|
||||
//Avoid using a TorSocket if a proxy is specified, even if a .onion address
|
||||
return new TcpTransport(server, proxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) {
|
||||
public CloseableTransport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) {
|
||||
return getTransport(server, proxy);
|
||||
}
|
||||
},
|
||||
SSL {
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
public CloseableTransport getTransport(HostAndPort server) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
if(isOnionAddress(server)) {
|
||||
return new TorTcpOverTlsTransport(server);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public enum Protocol {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, File serverCert) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
public CloseableTransport getTransport(HostAndPort server, File serverCert) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
if(isOnionAddress(server)) {
|
||||
return new TorTcpOverTlsTransport(server, serverCert);
|
||||
}
|
||||
|
@ -57,44 +57,44 @@ public enum Protocol {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
public CloseableTransport getTransport(HostAndPort server, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
return new ProxyTcpOverTlsTransport(server, proxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
public CloseableTransport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||
return new ProxyTcpOverTlsTransport(server, serverCert, proxy);
|
||||
}
|
||||
},
|
||||
HTTP {
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server) {
|
||||
public CloseableTransport getTransport(HostAndPort server) {
|
||||
throw new UnsupportedOperationException("No transport supported for HTTP");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, File serverCert) {
|
||||
public CloseableTransport getTransport(HostAndPort server, File serverCert) {
|
||||
throw new UnsupportedOperationException("No transport supported for HTTP");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, HostAndPort proxy) {
|
||||
public CloseableTransport getTransport(HostAndPort server, HostAndPort proxy) {
|
||||
throw new UnsupportedOperationException("No transport supported for HTTP");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) {
|
||||
public CloseableTransport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) {
|
||||
throw new UnsupportedOperationException("No transport supported for HTTP");
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Transport getTransport(HostAndPort server) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
public abstract CloseableTransport getTransport(HostAndPort server) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
|
||||
public abstract Transport getTransport(HostAndPort server, File serverCert) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
public abstract CloseableTransport getTransport(HostAndPort server, File serverCert) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
|
||||
public abstract Transport getTransport(HostAndPort server, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
public abstract CloseableTransport getTransport(HostAndPort server, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
|
||||
public abstract Transport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
public abstract CloseableTransport getTransport(HostAndPort server, File serverCert, HostAndPort proxy) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException;
|
||||
|
||||
public HostAndPort getServerHostAndPort(String url) {
|
||||
return HostAndPort.fromString(url.substring(this.toUrlString().length()));
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class TcpTransport implements Transport, Closeable, TimeoutCounter {
|
||||
public class TcpTransport implements CloseableTransport, TimeoutCounter {
|
||||
private static final Logger log = LoggerFactory.getLogger(TcpTransport.class);
|
||||
|
||||
public static final int DEFAULT_PORT = 50001;
|
||||
|
@ -46,6 +46,7 @@ public class TcpTransport implements Transport, Closeable, TimeoutCounter {
|
|||
private final ReentrantLock clientRequestLock = new ReentrantLock();
|
||||
private boolean running = false;
|
||||
private volatile boolean reading = true;
|
||||
private boolean closed = false;
|
||||
private boolean firstRead = true;
|
||||
private int readTimeoutIndex;
|
||||
private int requestIdCount = 1;
|
||||
|
@ -223,6 +224,7 @@ public class TcpTransport implements Transport, Closeable, TimeoutCounter {
|
|||
public void connect() throws ServerException {
|
||||
try {
|
||||
socket = createSocket();
|
||||
log.debug("Created " + socket);
|
||||
socket.setSoTimeout(SOCKET_READ_TIMEOUT_MILLIS);
|
||||
running = true;
|
||||
} catch(SSLHandshakeException e) {
|
||||
|
@ -237,18 +239,23 @@ public class TcpTransport implements Transport, Closeable, TimeoutCounter {
|
|||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return socket != null && running;
|
||||
return socket != null && running && !closed;
|
||||
}
|
||||
|
||||
protected Socket createSocket() throws IOException {
|
||||
return socketFactory.createSocket(server.getHost(), server.getPortOrDefault(DEFAULT_PORT));
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if(socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue