mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
tor fusion service
This commit is contained in:
parent
59ac1563bc
commit
5527678b94
2 changed files with 101 additions and 29 deletions
71
lib/services/fusion_tor_service.dart
Normal file
71
lib/services/fusion_tor_service.dart
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
import 'package:tor_ffi_plugin/tor_ffi_plugin.dart';
|
||||||
|
|
||||||
|
class FusionTorService {
|
||||||
|
Tor? _tor;
|
||||||
|
String? _torDataDirPath;
|
||||||
|
|
||||||
|
TorStatus get status => _tor!.status;
|
||||||
|
|
||||||
|
/// Singleton instance of the TorService.
|
||||||
|
///
|
||||||
|
/// Use this to access the TorService and its properties.
|
||||||
|
static final sharedInstance = FusionTorService._();
|
||||||
|
|
||||||
|
// private constructor for singleton
|
||||||
|
FusionTorService._();
|
||||||
|
|
||||||
|
/// Getter for the proxyInfo.
|
||||||
|
///
|
||||||
|
/// Throws if Tor is not connected.
|
||||||
|
({
|
||||||
|
InternetAddress host,
|
||||||
|
int port,
|
||||||
|
}) getProxyInfo() {
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
host: InternetAddress.loopbackIPv4,
|
||||||
|
port: _tor!.port,
|
||||||
|
);
|
||||||
|
} catch (_) {
|
||||||
|
throw Exception("Tor proxy info fetched while not connected!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize the tor ffi lib instance if it hasn't already been set. Nothing
|
||||||
|
/// changes if _tor is already been set.
|
||||||
|
void init({
|
||||||
|
required String torDataDirPath,
|
||||||
|
Tor? mockableOverride,
|
||||||
|
}) {
|
||||||
|
_tor ??= mockableOverride ?? Tor.instance;
|
||||||
|
_torDataDirPath ??= torDataDirPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start the Tor service.
|
||||||
|
///
|
||||||
|
/// This will start the Tor service and establish a Tor circuit.
|
||||||
|
///
|
||||||
|
/// Throws an exception if the Tor library was not inited or if the Tor
|
||||||
|
/// service fails to start.
|
||||||
|
///
|
||||||
|
/// Returns a Future that completes when the Tor service has started.
|
||||||
|
Future<void> start() async {
|
||||||
|
if (_tor == null || _torDataDirPath == null) {
|
||||||
|
throw Exception("FusionTorService.init has not been called!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the Tor service.
|
||||||
|
try {
|
||||||
|
await _tor!.start(torDataDirPath: _torDataDirPath!);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"FusionTorService.start failed: $e\n$s",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
|
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/services/tor_service.dart';
|
import 'package:stackwallet/services/fusion_tor_service.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
|
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
|
||||||
|
@ -28,7 +28,7 @@ mixin FusionWalletInterface {
|
||||||
late final Coin _coin;
|
late final Coin _coin;
|
||||||
late final MainDB _db;
|
late final MainDB _db;
|
||||||
late final CachedElectrumX _cachedElectrumX;
|
late final CachedElectrumX _cachedElectrumX;
|
||||||
late final TorService _torService;
|
late final FusionTorService _torService;
|
||||||
|
|
||||||
// Passed in wallet functions.
|
// Passed in wallet functions.
|
||||||
late final Future<Address> Function(
|
late final Future<Address> Function(
|
||||||
|
@ -58,25 +58,8 @@ mixin FusionWalletInterface {
|
||||||
_coin = coin;
|
_coin = coin;
|
||||||
_db = db;
|
_db = db;
|
||||||
_generateAddressForChain = generateAddressForChain;
|
_generateAddressForChain = generateAddressForChain;
|
||||||
_torService = TorService.sharedInstance;
|
_torService = FusionTorService.sharedInstance;
|
||||||
_cachedElectrumX = cachedElectrumX;
|
_cachedElectrumX = cachedElectrumX;
|
||||||
|
|
||||||
// Try getting the proxy info.
|
|
||||||
//
|
|
||||||
// Start the Tor service if it's not already running. Returns if Tor is already
|
|
||||||
// connected or else after Tor returns from start().
|
|
||||||
try {
|
|
||||||
_torService.getProxyInfo();
|
|
||||||
// Proxy info successfully retrieved, Tor is connected.
|
|
||||||
return;
|
|
||||||
} catch (e) {
|
|
||||||
// Init the Tor service if it hasn't already been.
|
|
||||||
final torDir = await StackFileSystem.applicationTorDirectory();
|
|
||||||
_torService.init(torDataDirPath: torDir.path);
|
|
||||||
|
|
||||||
// Start the Tor service.
|
|
||||||
return await _torService.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all addresses in the wallet.
|
/// Returns a list of all addresses in the wallet.
|
||||||
|
@ -198,20 +181,38 @@ mixin FusionWalletInterface {
|
||||||
return unusedAddresses;
|
return unusedAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _torStartCount = 0;
|
||||||
|
|
||||||
/// Returns the current Tor proxy address.
|
/// Returns the current Tor proxy address.
|
||||||
Future<({InternetAddress host, int port})> getSocksProxyAddress() async {
|
Future<({InternetAddress host, int port})> getSocksProxyAddress() async {
|
||||||
/*
|
if (_torStartCount > 5) {
|
||||||
// Start the Tor service if it's not already running.
|
// something is quite broken so stop trying to recursively fetch
|
||||||
if (_torService.proxyInfo.port == -1) { // -1 indicates that the proxy is not running.
|
// start up tor and fetch proxy info
|
||||||
await _torService.start(); // We already unawaited this in initFusionInterface...
|
throw Exception(
|
||||||
|
"Fusion interface attempted to start tor $_torStartCount times and failed!",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO make sure we've properly awaited the Tor service starting before
|
try {
|
||||||
// returning the proxy address.
|
final info = _torService.getProxyInfo();
|
||||||
|
|
||||||
// Return the proxy address.
|
// reset counter before return info;
|
||||||
return _torService.getProxyInfo();
|
_torStartCount = 0;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
} catch (_) {
|
||||||
|
// tor is probably not running so lets fix that
|
||||||
|
final torDir = await StackFileSystem.applicationTorDirectory();
|
||||||
|
_torService.init(torDataDirPath: torDir.path);
|
||||||
|
|
||||||
|
// increment start attempt count
|
||||||
|
_torStartCount++;
|
||||||
|
|
||||||
|
await _torService.start();
|
||||||
|
|
||||||
|
// try again to fetch proxy info
|
||||||
|
return await getSocksProxyAddress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial attempt for CashFusion integration goes here.
|
// Initial attempt for CashFusion integration goes here.
|
||||||
|
|
Loading…
Reference in a new issue