Updated on 2026-08-14

This commit is contained in:
Tangem 2018-11-19 15:17:22 +03:00
parent 983278c3e1
commit 6a0207897d
3 changed files with 164 additions and 82 deletions

View file

@ -20,7 +20,10 @@ import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.cert.CertificateFactory;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -29,10 +32,13 @@ import java.util.Random;
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -62,9 +68,8 @@ public class ServerApiElectrum {
public void electrumRequestData(TangemCard card, ElectrumRequest electrumRequest) {
Observable<ElectrumRequest> checkElectrumDataObserver = Observable.just(electrumRequest)
// .doOnNext(electrumRequest1 -> doElectrumRequest(card, electrumRequest))
.doOnNext(electrumRequest1 -> testSslSocket(card, electrumRequest))
// .doOnNext(electrumRequest1 -> doElectrumRequestTcp(card, electrumRequest))
.doOnNext(electrumRequest1 -> doElectrumRequestSsl(card, electrumRequest))
.flatMap(electrumRequest1 -> {
if (electrumRequest1.answerData == null) {
@ -74,9 +79,9 @@ public class ServerApiElectrum {
return Observable.just(electrumRequest1);
})
// .retryWhen(errors -> errors
// .filter(throwable -> throwable instanceof NullPointerException)
// .zipWith(Observable.range(1, 4), (n, i) -> i))
.retryWhen(errors -> errors
.filter(throwable -> throwable instanceof NullPointerException)
.zipWith(Observable.range(1, 4), (n, i) -> i))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
@ -106,6 +111,156 @@ public class ServerApiElectrum {
});
}
private List<ElectrumRequest> doElectrumRequestTcp(TangemCard card, ElectrumRequest electrumRequest) {
if (card.getBlockchain() == Blockchain.BitcoinTestNet) {
BitcoinNodeTestNet bitcoinNodeTestNet = BitcoinNodeTestNet.values()[new Random().nextInt(BitcoinNodeTestNet.values().length)];
this.host = bitcoinNodeTestNet.getHost();
this.port = bitcoinNodeTestNet.getPort();
} else if (card.getBlockchain() == Blockchain.BitcoinCash) {
BitcoinCashNode bitcoinCashNode = BitcoinCashNode.values()[new Random().nextInt(BitcoinCashNode.values().length)];
this.host = bitcoinCashNode.getHost();
this.port = bitcoinCashNode.getPort();
} else if (card.getBlockchain() == Blockchain.Bitcoin) {
BitcoinNode bitcoinNode = BitcoinNode.values()[new Random().nextInt(BitcoinNode.values().length)];
this.host = bitcoinNode.getHost();
this.port = bitcoinNode.getPort();
}
List<ElectrumRequest> result = new ArrayList<>();
Collections.addAll(result, electrumRequest);
try {
Socket socket = App.getNetworkComponent().getSocket();
socket.setSoTimeout(3000);
socket.connect(new InetSocketAddress(InetAddress.getByName(host), port));
Log.i(TAG, host + " " + port);
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter out = new OutputStreamWriter(os, "UTF-8");
InputStream is = socket.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
electrumRequest.setID(1);
out.write(electrumRequest.getAsString() + "\n");
out.flush();
electrumRequest.answerData = in.readLine();
electrumRequest.host = host;
electrumRequest.port = port;
if (electrumRequest.answerData != null) {
Log.i(TAG, ">> " + electrumRequest.answerData);
} else {
electrumRequest.error = "No answer from server";
Log.i(TAG, ">> <NULL>");
}
} catch (ConnectException e) {
e.printStackTrace();
electrumRequestDataListener.onFail(e.getMessage());
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " ConnectException " + e.getMessage());
} finally {
Log.i(TAG, "electrumRequestData " + electrumRequest.getMethod() + " CLOSE");
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
electrumRequestDataListener.onFail(e.getMessage());
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " IOException " + e.getMessage());
}
return result;
}
private List<ElectrumRequest> doElectrumRequestSsl(TangemCard card, ElectrumRequest electrumRequest) {
BitcoinNodeSsl bitcoinNodeSsl = BitcoinNodeSsl.values()[new Random().nextInt(BitcoinNodeSsl.values().length)];
this.host = bitcoinNodeSsl.getHost();
this.port = bitcoinNodeSsl.getPort();
try {
// create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} };
// install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory sf = sc.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sf);
// create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
SSLSocket sslSocket;
List<ElectrumRequest> result = new ArrayList<>();
Collections.addAll(result, electrumRequest);
try {
sslSocket = (SSLSocket) sf.createSocket(host, port);
Log.i(TAG, host + " " + port);
try {
OutputStream os = sslSocket.getOutputStream();
OutputStreamWriter out = new OutputStreamWriter(os, "UTF-8");
InputStream is = sslSocket.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
electrumRequest.setID(1);
out.write(electrumRequest.getAsString() + "\n");
out.flush();
electrumRequest.answerData = in.readLine();
if (electrumRequest.answerData != null) {
Log.i(TAG, ">> " + electrumRequest.answerData);
} else {
electrumRequest.error = "No answer from server";
Log.i(TAG, ">> <NULL>");
}
} catch (ConnectException e) {
e.printStackTrace();
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " ConnectException " + e.getMessage());
} finally {
Log.i(TAG, "electrumRequestData " + electrumRequest.getMethod() + " CLOSE");
sslSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " IOException " + e.getMessage());
}
return result;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
Log.e(TAG, e.getMessage());
}
return null;
}
private List<ElectrumRequest> testSslSocket(TangemCard card, ElectrumRequest electrumRequest) {
BitcoinNodeSsl bitcoinNodeSsl = BitcoinNodeSsl.values()[new Random().nextInt(BitcoinNodeSsl.values().length)];
@ -165,65 +320,6 @@ public class ServerApiElectrum {
return result;
}
private List<ElectrumRequest> doElectrumRequest(TangemCard card, ElectrumRequest electrumRequest) {
if (card.getBlockchain() == Blockchain.BitcoinTestNet) {
BitcoinNodeTestNet bitcoinNodeTestNet = BitcoinNodeTestNet.values()[new Random().nextInt(BitcoinNodeTestNet.values().length)];
this.host = bitcoinNodeTestNet.getHost();
this.port = bitcoinNodeTestNet.getPort();
} else if (card.getBlockchain() == Blockchain.BitcoinCash) {
BitcoinCashNode bitcoinCashNode = BitcoinCashNode.values()[new Random().nextInt(BitcoinCashNode.values().length)];
this.host = bitcoinCashNode.getHost();
this.port = bitcoinCashNode.getPort();
} else if (card.getBlockchain() == Blockchain.Bitcoin) {
BitcoinNode bitcoinNode = BitcoinNode.values()[new Random().nextInt(BitcoinNode.values().length)];
this.host = bitcoinNode.getHost();
this.port = bitcoinNode.getPort();
}
List<ElectrumRequest> result = new ArrayList<>();
Collections.addAll(result, electrumRequest);
try {
Socket socket = App.getNetworkComponent().getSocket();
socket.setSoTimeout(3000);
socket.connect(new InetSocketAddress(InetAddress.getByName(host), port));
Log.i(TAG, host + " " + port);
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter out = new OutputStreamWriter(os, "UTF-8");
InputStream is = socket.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
electrumRequest.setID(1);
out.write(electrumRequest.getAsString() + "\n");
out.flush();
electrumRequest.answerData = in.readLine();
electrumRequest.host = host;
electrumRequest.port = port;
if (electrumRequest.answerData != null) {
Log.i(TAG, ">> " + electrumRequest.answerData);
} else {
electrumRequest.error = "No answer from server";
Log.i(TAG, ">> <NULL>");
}
} catch (ConnectException e) {
e.printStackTrace();
electrumRequestDataListener.onFail(e.getMessage());
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " ConnectException " + e.getMessage());
} finally {
Log.i(TAG, "electrumRequestData " + electrumRequest.getMethod() + " CLOSE");
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
electrumRequestDataListener.onFail(e.getMessage());
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " IOException " + e.getMessage());
}
return result;
}
public String getValidationNodeDescription() {
return "Electrum, " + host + ":" + String.valueOf(port);
}

View file

@ -18,19 +18,5 @@ enum class BitcoinNode(val host: String, val port: Int, val proto: String) {
// n14("electrum.eff.ro", 50002, "ssl"),
// n15("vps.hsmiths.com", 50002, "ssl"),
// n16("VPS.hsmiths.com", 50002, "ssl"),
// n17("agapc7dhcqfjqpjb.onion", 50002, "ssl"),
// n18("alviss.coinjoined.com", 50002, "ssl"),
// n19("arihancckjge66iv.onion", 50002, "ssl"),
// n20("aspinall.io", 50002, "ssl"),
// n21("bauerjda5hnedjam.onion", 50002, "ssl"),
// n22("bauerjhejlv6di7s.onion", 50002, "ssl"),
// n23("bauerjhejlv6di7s.onion", 50002, "ssl"),
// n24("btc.asis.io", 50002, "ssl"),
// n25("btc.cihar.com", 50002, "ssl"),
// n26("btc.ex.laodc.com", 443, "ssl"),
// n27("btc.gravitech.net", 50002, "ssl"),
// n28("btc.pr0xima.de", 50002, "ssl"),
// n29("btc.smsys.me", 995, "ssl"),
}