mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
WIP proxied sockets
This commit is contained in:
parent
ec5ae60a61
commit
281cd98390
3 changed files with 199 additions and 40 deletions
|
@ -15,6 +15,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
|||
import 'package:decimal/decimal.dart';
|
||||
import 'package:stackwallet/electrumx_rpc/rpc.dart';
|
||||
import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart';
|
||||
import 'package:stackwallet/networking/tor_service.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/prefs.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
@ -71,6 +72,8 @@ class ElectrumX {
|
|||
|
||||
final Duration connectionTimeoutForSpecialCaseJsonRPCClients;
|
||||
|
||||
({String host, int port})? proxyInfo;
|
||||
|
||||
ElectrumX({
|
||||
required String host,
|
||||
required int port,
|
||||
|
@ -80,6 +83,7 @@ class ElectrumX {
|
|||
JsonRPC? client,
|
||||
this.connectionTimeoutForSpecialCaseJsonRPCClients =
|
||||
const Duration(seconds: 60),
|
||||
({String host, int port})? proxyInfo,
|
||||
}) {
|
||||
_prefs = prefs;
|
||||
_host = host;
|
||||
|
@ -92,14 +96,38 @@ class ElectrumX {
|
|||
required ElectrumXNode node,
|
||||
required Prefs prefs,
|
||||
required List<ElectrumXNode> failovers,
|
||||
}) =>
|
||||
ElectrumX(
|
||||
({String host, int port})? proxyInfo,
|
||||
}) {
|
||||
if (Prefs.instance.useTor) {
|
||||
if (proxyInfo == null) {
|
||||
// TODO await tor / make sure it's running
|
||||
proxyInfo = (
|
||||
host: InternetAddress.loopbackIPv4.address,
|
||||
port: TorService.sharedInstance.port
|
||||
);
|
||||
Logging.instance.log(
|
||||
"ElectrumX.batchRequest(): no tor proxy info, read $proxyInfo",
|
||||
level: LogLevel.Warning);
|
||||
}
|
||||
return ElectrumX(
|
||||
host: node.address,
|
||||
port: node.port,
|
||||
useSSL: node.useSSL,
|
||||
prefs: prefs,
|
||||
failovers: failovers,
|
||||
proxyInfo: proxyInfo,
|
||||
);
|
||||
} else {
|
||||
return ElectrumX(
|
||||
host: node.address,
|
||||
port: node.port,
|
||||
useSSL: node.useSSL,
|
||||
prefs: prefs,
|
||||
failovers: failovers,
|
||||
proxyInfo: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _allow() async {
|
||||
if (_prefs.wifiOnly) {
|
||||
|
@ -121,12 +149,24 @@ class ElectrumX {
|
|||
throw WifiOnlyException();
|
||||
}
|
||||
|
||||
if (Prefs.instance.useTor) {
|
||||
if (proxyInfo == null) {
|
||||
// TODO await tor / make sure Tor is running
|
||||
proxyInfo = (
|
||||
host: InternetAddress.loopbackIPv4.address,
|
||||
port: TorService.sharedInstance.port
|
||||
);
|
||||
Logging.instance.log(
|
||||
"ElectrumX.batchRequest(): no tor proxy info, read $proxyInfo",
|
||||
level: LogLevel.Warning);
|
||||
}
|
||||
if (currentFailoverIndex == -1) {
|
||||
_rpcClient ??= JsonRPC(
|
||||
host: host,
|
||||
port: port,
|
||||
useSSL: useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: proxyInfo,
|
||||
);
|
||||
} else {
|
||||
_rpcClient = JsonRPC(
|
||||
|
@ -134,8 +174,28 @@ class ElectrumX {
|
|||
port: failovers![currentFailoverIndex].port,
|
||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: proxyInfo,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (currentFailoverIndex == -1) {
|
||||
_rpcClient ??= JsonRPC(
|
||||
host: host,
|
||||
port: port,
|
||||
useSSL: useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: null,
|
||||
);
|
||||
} else {
|
||||
_rpcClient = JsonRPC(
|
||||
host: failovers![currentFailoverIndex].address,
|
||||
port: failovers![currentFailoverIndex].port,
|
||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final requestId = requestID ?? const Uuid().v1();
|
||||
|
@ -221,12 +281,25 @@ class ElectrumX {
|
|||
throw WifiOnlyException();
|
||||
}
|
||||
|
||||
if (Prefs.instance.useTor) {
|
||||
// TODO await tor / make sure Tor is initialized
|
||||
if (proxyInfo == null) {
|
||||
proxyInfo = (
|
||||
host: InternetAddress.loopbackIPv4.address,
|
||||
port: TorService.sharedInstance.port
|
||||
);
|
||||
Logging.instance.log(
|
||||
"ElectrumX.batchRequest(): no tor proxy info, read $proxyInfo",
|
||||
level: LogLevel.Warning);
|
||||
}
|
||||
|
||||
if (currentFailoverIndex == -1) {
|
||||
_rpcClient ??= JsonRPC(
|
||||
host: host,
|
||||
port: port,
|
||||
useSSL: useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: proxyInfo,
|
||||
);
|
||||
} else {
|
||||
_rpcClient = JsonRPC(
|
||||
|
@ -234,8 +307,28 @@ class ElectrumX {
|
|||
port: failovers![currentFailoverIndex].port,
|
||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: proxyInfo,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (currentFailoverIndex == -1) {
|
||||
_rpcClient ??= JsonRPC(
|
||||
host: host,
|
||||
port: port,
|
||||
useSSL: useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: null,
|
||||
);
|
||||
} else {
|
||||
_rpcClient = JsonRPC(
|
||||
host: failovers![currentFailoverIndex].address,
|
||||
port: failovers![currentFailoverIndex].port,
|
||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
proxyInfo: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final List<String> requestStrings = [];
|
||||
|
|
|
@ -14,7 +14,11 @@ import 'dart:io';
|
|||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mutex/mutex.dart';
|
||||
import 'package:socks5_proxy/socks.dart';
|
||||
import 'package:socks5_proxy/src/client/socks_client.dart';
|
||||
import 'package:stackwallet/networking/tor_service.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/prefs.dart';
|
||||
|
||||
// Json RPC class to handle connecting to electrumx servers
|
||||
class JsonRPC {
|
||||
|
@ -23,11 +27,13 @@ class JsonRPC {
|
|||
required this.port,
|
||||
this.useSSL = false,
|
||||
this.connectionTimeout = const Duration(seconds: 60),
|
||||
required ({String host, int port})? proxyInfo,
|
||||
});
|
||||
final bool useSSL;
|
||||
final String host;
|
||||
final int port;
|
||||
final Duration connectionTimeout;
|
||||
({String host, int port})? proxyInfo;
|
||||
|
||||
final _requestMutex = Mutex();
|
||||
final _JsonRPCRequestQueue _requestQueue = _JsonRPCRequestQueue();
|
||||
|
@ -152,6 +158,62 @@ class JsonRPC {
|
|||
);
|
||||
}
|
||||
|
||||
if (Prefs.instance.useTor) {
|
||||
if (proxyInfo == null) {
|
||||
// TODO await tor / make sure it's running
|
||||
proxyInfo = (
|
||||
host: InternetAddress.loopbackIPv4.address,
|
||||
port: TorService.sharedInstance.port
|
||||
);
|
||||
Logging.instance.log(
|
||||
"ElectrumX.connect(): no tor proxy info, read $proxyInfo",
|
||||
level: LogLevel.Warning);
|
||||
}
|
||||
// TODO connect to proxy socket...
|
||||
// https://github.com/LacticWhale/socks_dart/blob/master/lib/src/client/socks_client.dart#L50C46-L50C56
|
||||
|
||||
// TODO implement ssl over tor
|
||||
// if (useSSL) {
|
||||
// _socket = await SecureSocket.connect(
|
||||
// host,
|
||||
// port,
|
||||
// timeout: connectionTimeout,
|
||||
// onBadCertificate: (_) => true,
|
||||
// ); // TODO do not automatically trust bad certificates
|
||||
// final _client = SocksSocket.protected(_socket, type);
|
||||
// } else {
|
||||
// _socket = await Socket.connect(
|
||||
// proxyInfo!.host,
|
||||
// proxyInfo!.port,
|
||||
// timeout: connectionTimeout,
|
||||
// );
|
||||
// final _client = SocksSocket.protected(
|
||||
// _socket!, SocksConnectionType.connect
|
||||
// );
|
||||
final InternetAddress _host =
|
||||
await InternetAddress.lookup(host).then((value) => value.first);
|
||||
var _socket = await SocksSocket.initialize(
|
||||
[
|
||||
ProxySettings(
|
||||
InternetAddress.loopbackIPv4,
|
||||
proxyInfo!.port,
|
||||
)
|
||||
],
|
||||
_host,
|
||||
port,
|
||||
SocksConnectionType.connect,
|
||||
);
|
||||
if (_socket == null) {
|
||||
Logging.instance.log(
|
||||
"JsonRPC.connect(): failed to connect to $host over tor proxy at $proxyInfo",
|
||||
level: LogLevel.Error);
|
||||
throw Exception("JsonRPC.connect(): failed to connect to tor proxy");
|
||||
} else {
|
||||
Logging.instance.log(
|
||||
"JsonRPC.connect(): connected to $host over tor proxy at $proxyInfo",
|
||||
level: LogLevel.Info);
|
||||
}
|
||||
} else {
|
||||
if (useSSL) {
|
||||
_socket = await SecureSocket.connect(
|
||||
host,
|
||||
|
@ -166,6 +228,7 @@ class JsonRPC {
|
|||
timeout: connectionTimeout,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_subscription = _socket!.listen(
|
||||
_dataHandler,
|
||||
|
|
|
@ -11,6 +11,7 @@ void main() {
|
|||
port: DefaultNodes.bitcoin.port,
|
||||
useSSL: true,
|
||||
connectionTimeout: const Duration(seconds: 40),
|
||||
proxyInfo: null, // TODO test for proxyInfo
|
||||
);
|
||||
|
||||
const jsonRequestString =
|
||||
|
@ -27,7 +28,8 @@ void main() {
|
|||
final jsonRPC = JsonRPC(
|
||||
host: "some.bad.address.thingdsfsdfsdaf",
|
||||
port: 3000,
|
||||
connectionTimeout: Duration(seconds: 10),
|
||||
connectionTimeout: const Duration(seconds: 10),
|
||||
proxyInfo: null,
|
||||
);
|
||||
|
||||
const jsonRequestString =
|
||||
|
@ -47,6 +49,7 @@ void main() {
|
|||
port: 3000,
|
||||
useSSL: false,
|
||||
connectionTimeout: const Duration(seconds: 1),
|
||||
proxyInfo: null,
|
||||
);
|
||||
|
||||
const jsonRequestString =
|
||||
|
|
Loading…
Reference in a new issue