From 8387525b85dbe9065772e674daf2eb341451ad9f Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Wed, 13 Mar 2024 09:19:38 -0700 Subject: [PATCH] tor improvements --- lib/core/fiat_conversion_service.dart | 6 +++ .../settings/widgets/settings_tor_status.dart | 12 +++--- lib/utils/proxy_wrapper.dart | 14 +++++++ lib/view_model/settings/tor_connection.dart | 39 +++++++++++++++++++ lib/view_model/settings/tor_view_model.dart | 2 - 5 files changed, 64 insertions(+), 9 deletions(-) diff --git a/lib/core/fiat_conversion_service.dart b/lib/core/fiat_conversion_service.dart index 1c5843310..6118f7de2 100644 --- a/lib/core/fiat_conversion_service.dart +++ b/lib/core/fiat_conversion_service.dart @@ -4,6 +4,7 @@ import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/utils/proxy_wrapper.dart'; import 'package:cake_wallet/view_model/settings/tor_connection.dart'; +import 'package:cake_wallet/view_model/settings/tor_view_model.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'dart:convert'; @@ -19,6 +20,8 @@ Future _fetchPrice(Map args) async { final fiat = args['fiat'] as String; final mainThreadProxyPort = args['port'] as int; final torConnectionMode = TorConnectionMode.deserialize(raw: args['torConnectionMode'] as int); + final torConnectionStatus = TorConnectionStatus.deserialize(raw: args['torConnectionStatus'] as int); + final Map queryParams = { 'interval_count': '1', @@ -46,6 +49,7 @@ Future _fetchPrice(Map args) async { clearnetUri: clearnetUri, portOverride: mainThreadProxyPort, torConnectionMode: torConnectionMode, + torConnectionStatus: torConnectionStatus, ); responseBody = await utf8.decodeStream(httpResponse); @@ -75,12 +79,14 @@ Future _fetchPrice(Map args) async { Future _fetchPriceAsync(CryptoCurrency crypto, FiatCurrency fiat) async { final settingsStore = getIt.get(); final mode = settingsStore.torConnectionMode; + final status = getIt.get().torConnectionStatus; ProxyWrapper proxy = await getIt.get(); return compute(_fetchPrice, { 'fiat': fiat.toString(), 'crypto': crypto.toString(), 'port': proxy.getPort(), 'torConnectionMode': mode.raw, + 'torConnectionStatus': status.raw, }); } diff --git a/lib/src/screens/settings/widgets/settings_tor_status.dart b/lib/src/screens/settings/widgets/settings_tor_status.dart index af90d5653..3086cd4ee 100644 --- a/lib/src/screens/settings/widgets/settings_tor_status.dart +++ b/lib/src/screens/settings/widgets/settings_tor_status.dart @@ -1,10 +1,9 @@ -import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/src/screens/nodes/widgets/node_indicator.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; +import 'package:cake_wallet/view_model/settings/tor_connection.dart'; import 'package:cake_wallet/view_model/settings/tor_view_model.dart'; import 'package:flutter/material.dart'; -import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class TorStatus extends StandardListRow { @@ -21,22 +20,21 @@ class TorStatus extends StandardListRow { Widget buildTrailing(BuildContext context) { return Observer(builder: (context) { Color? color; - String? text; switch (torViewModel.torConnectionStatus) { case TorConnectionStatus.connected: color = Palette.green; - text = S.current.connected; break; case TorConnectionStatus.connecting: color = Colors.amber; - text = S.current.connecting; break; case TorConnectionStatus.disconnected: color = Palette.red; - text = S.current.disconnected; break; } - return NodeIndicator(color: color, text: text); + return NodeIndicator( + color: color, + text: torViewModel.torConnectionStatus.toString(), + ); }); } } diff --git a/lib/utils/proxy_wrapper.dart b/lib/utils/proxy_wrapper.dart index 58b54f621..0bd17916f 100644 --- a/lib/utils/proxy_wrapper.dart +++ b/lib/utils/proxy_wrapper.dart @@ -80,12 +80,15 @@ class ProxyWrapper { Map? headers, int? portOverride, TorConnectionMode? torConnectionMode, + TorConnectionStatus? torConnectionStatus, Uri? clearnetUri, Uri? onionUri, }) async { HttpClient? torClient; late bool torEnabled; torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled; + torConnectionStatus ??= torViewModel?.torConnectionStatus ?? TorConnectionStatus.disconnected; + if (torConnectionMode == TorConnectionMode.torOnly || torConnectionMode == TorConnectionMode.enabled) { torEnabled = true; @@ -93,6 +96,10 @@ class ProxyWrapper { torEnabled = false; } + if (torEnabled && torConnectionStatus == TorConnectionStatus.connecting) { + throw Exception("Tor is still connecting"); + } + // if tor is enabled, try to connect to the onion url first: if (torEnabled) { try { @@ -145,12 +152,15 @@ class ProxyWrapper { Map? headers, int? portOverride, TorConnectionMode? torConnectionMode, + TorConnectionStatus? torConnectionStatus, Uri? clearnetUri, Uri? onionUri, }) async { HttpClient? torClient; late bool torEnabled; torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled; + torConnectionStatus ??= torViewModel?.torConnectionStatus ?? TorConnectionStatus.disconnected; + if (torConnectionMode == TorConnectionMode.torOnly || torConnectionMode == TorConnectionMode.enabled) { torEnabled = true; @@ -158,6 +168,10 @@ class ProxyWrapper { torEnabled = false; } + if (torEnabled && torConnectionStatus == TorConnectionStatus.connecting) { + throw Exception("Tor is still connecting"); + } + // if tor is enabled, try to connect to the onion url first: if (torEnabled) { diff --git a/lib/view_model/settings/tor_connection.dart b/lib/view_model/settings/tor_connection.dart index 30110895c..e20c2bec2 100644 --- a/lib/view_model/settings/tor_connection.dart +++ b/lib/view_model/settings/tor_connection.dart @@ -38,3 +38,42 @@ class TorConnectionMode extends EnumerableItem with Serializable { } } } + + + +class TorConnectionStatus extends EnumerableItem with Serializable { + const TorConnectionStatus({required String title, required int raw}) : super(title: title, raw: raw); + + static const all = [TorConnectionMode.enabled, TorConnectionMode.disabled, TorConnectionMode.torOnly]; + + static const connecting = TorConnectionStatus(raw: 0, title: 'Connecting'); + static const connected = TorConnectionStatus(raw: 1, title: 'Connected'); + static const disconnected = TorConnectionStatus(raw: 2, title: 'Disconnected'); + + static TorConnectionStatus deserialize({required int raw}) { + switch (raw) { + case 0: + return connecting; + case 1: + return connected; + case 2: + return disconnected; + default: + throw Exception('Unexpected token: $raw for TorConnectionStatus deserialize'); + } + } + + @override + String toString() { + switch (this) { + case TorConnectionStatus.connecting: + return S.current.connecting; + case TorConnectionStatus.connected: + return S.current.connected; + case TorConnectionStatus.disconnected: + return S.current.disconnected; + default: + return ''; + } + } +} \ No newline at end of file diff --git a/lib/view_model/settings/tor_view_model.dart b/lib/view_model/settings/tor_view_model.dart index e7e375935..0cfb3fdc9 100644 --- a/lib/view_model/settings/tor_view_model.dart +++ b/lib/view_model/settings/tor_view_model.dart @@ -16,8 +16,6 @@ part 'tor_view_model.g.dart'; class TorViewModel = TorViewModelBase with _$TorViewModel; -enum TorConnectionStatus { connecting, connected, disconnected } - abstract class TorViewModelBase with Store { TorViewModelBase(this._settingsStore, this.nodes) { reaction((_) => torConnectionMode, (TorConnectionMode mode) async {