mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-02-02 03:06:29 +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/electrumx_rpc/cached_electrumx.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/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
|
||||
|
@ -28,7 +28,7 @@ mixin FusionWalletInterface {
|
|||
late final Coin _coin;
|
||||
late final MainDB _db;
|
||||
late final CachedElectrumX _cachedElectrumX;
|
||||
late final TorService _torService;
|
||||
late final FusionTorService _torService;
|
||||
|
||||
// Passed in wallet functions.
|
||||
late final Future<Address> Function(
|
||||
|
@ -58,25 +58,8 @@ mixin FusionWalletInterface {
|
|||
_coin = coin;
|
||||
_db = db;
|
||||
_generateAddressForChain = generateAddressForChain;
|
||||
_torService = TorService.sharedInstance;
|
||||
_torService = FusionTorService.sharedInstance;
|
||||
_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.
|
||||
|
@ -198,20 +181,38 @@ mixin FusionWalletInterface {
|
|||
return unusedAddresses;
|
||||
}
|
||||
|
||||
int _torStartCount = 0;
|
||||
|
||||
/// Returns the current Tor proxy address.
|
||||
Future<({InternetAddress host, int port})> getSocksProxyAddress() async {
|
||||
/*
|
||||
// Start the Tor service if it's not already running.
|
||||
if (_torService.proxyInfo.port == -1) { // -1 indicates that the proxy is not running.
|
||||
await _torService.start(); // We already unawaited this in initFusionInterface...
|
||||
if (_torStartCount > 5) {
|
||||
// something is quite broken so stop trying to recursively fetch
|
||||
// start up tor and fetch proxy info
|
||||
throw Exception(
|
||||
"Fusion interface attempted to start tor $_torStartCount times and failed!",
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO make sure we've properly awaited the Tor service starting before
|
||||
// returning the proxy address.
|
||||
try {
|
||||
final info = _torService.getProxyInfo();
|
||||
|
||||
// Return the proxy address.
|
||||
return _torService.getProxyInfo();
|
||||
// reset counter before return info;
|
||||
_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.
|
||||
|
|
Loading…
Reference in a new issue