tor improvements

This commit is contained in:
Matthew Fosse 2024-03-13 09:19:38 -07:00
parent 826f69597c
commit 8387525b85
5 changed files with 64 additions and 9 deletions

View file

@ -4,6 +4,7 @@ import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/proxy_wrapper.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_connection.dart';
import 'package:cake_wallet/view_model/settings/tor_view_model.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/fiat_currency.dart';
import 'dart:convert'; import 'dart:convert';
@ -19,6 +20,8 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
final fiat = args['fiat'] as String; final fiat = args['fiat'] as String;
final mainThreadProxyPort = args['port'] as int; final mainThreadProxyPort = args['port'] as int;
final torConnectionMode = TorConnectionMode.deserialize(raw: args['torConnectionMode'] as int); final torConnectionMode = TorConnectionMode.deserialize(raw: args['torConnectionMode'] as int);
final torConnectionStatus = TorConnectionStatus.deserialize(raw: args['torConnectionStatus'] as int);
final Map<String, String> queryParams = { final Map<String, String> queryParams = {
'interval_count': '1', 'interval_count': '1',
@ -46,6 +49,7 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
clearnetUri: clearnetUri, clearnetUri: clearnetUri,
portOverride: mainThreadProxyPort, portOverride: mainThreadProxyPort,
torConnectionMode: torConnectionMode, torConnectionMode: torConnectionMode,
torConnectionStatus: torConnectionStatus,
); );
responseBody = await utf8.decodeStream(httpResponse); responseBody = await utf8.decodeStream(httpResponse);
@ -75,12 +79,14 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
Future<double> _fetchPriceAsync(CryptoCurrency crypto, FiatCurrency fiat) async { Future<double> _fetchPriceAsync(CryptoCurrency crypto, FiatCurrency fiat) async {
final settingsStore = getIt.get<SettingsStore>(); final settingsStore = getIt.get<SettingsStore>();
final mode = settingsStore.torConnectionMode; final mode = settingsStore.torConnectionMode;
final status = getIt.get<TorViewModel>().torConnectionStatus;
ProxyWrapper proxy = await getIt.get<ProxyWrapper>(); ProxyWrapper proxy = await getIt.get<ProxyWrapper>();
return compute(_fetchPrice, { return compute(_fetchPrice, {
'fiat': fiat.toString(), 'fiat': fiat.toString(),
'crypto': crypto.toString(), 'crypto': crypto.toString(),
'port': proxy.getPort(), 'port': proxy.getPort(),
'torConnectionMode': mode.raw, 'torConnectionMode': mode.raw,
'torConnectionStatus': status.raw,
}); });
} }

View file

@ -1,10 +1,9 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_indicator.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/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:cake_wallet/view_model/settings/tor_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
class TorStatus extends StandardListRow { class TorStatus extends StandardListRow {
@ -21,22 +20,21 @@ class TorStatus extends StandardListRow {
Widget buildTrailing(BuildContext context) { Widget buildTrailing(BuildContext context) {
return Observer(builder: (context) { return Observer(builder: (context) {
Color? color; Color? color;
String? text;
switch (torViewModel.torConnectionStatus) { switch (torViewModel.torConnectionStatus) {
case TorConnectionStatus.connected: case TorConnectionStatus.connected:
color = Palette.green; color = Palette.green;
text = S.current.connected;
break; break;
case TorConnectionStatus.connecting: case TorConnectionStatus.connecting:
color = Colors.amber; color = Colors.amber;
text = S.current.connecting;
break; break;
case TorConnectionStatus.disconnected: case TorConnectionStatus.disconnected:
color = Palette.red; color = Palette.red;
text = S.current.disconnected;
break; break;
} }
return NodeIndicator(color: color, text: text); return NodeIndicator(
color: color,
text: torViewModel.torConnectionStatus.toString(),
);
}); });
} }
} }

View file

@ -80,12 +80,15 @@ class ProxyWrapper {
Map<String, String>? headers, Map<String, String>? headers,
int? portOverride, int? portOverride,
TorConnectionMode? torConnectionMode, TorConnectionMode? torConnectionMode,
TorConnectionStatus? torConnectionStatus,
Uri? clearnetUri, Uri? clearnetUri,
Uri? onionUri, Uri? onionUri,
}) async { }) async {
HttpClient? torClient; HttpClient? torClient;
late bool torEnabled; late bool torEnabled;
torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled; torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled;
torConnectionStatus ??= torViewModel?.torConnectionStatus ?? TorConnectionStatus.disconnected;
if (torConnectionMode == TorConnectionMode.torOnly || if (torConnectionMode == TorConnectionMode.torOnly ||
torConnectionMode == TorConnectionMode.enabled) { torConnectionMode == TorConnectionMode.enabled) {
torEnabled = true; torEnabled = true;
@ -93,6 +96,10 @@ class ProxyWrapper {
torEnabled = false; 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 tor is enabled, try to connect to the onion url first:
if (torEnabled) { if (torEnabled) {
try { try {
@ -145,12 +152,15 @@ class ProxyWrapper {
Map<String, String>? headers, Map<String, String>? headers,
int? portOverride, int? portOverride,
TorConnectionMode? torConnectionMode, TorConnectionMode? torConnectionMode,
TorConnectionStatus? torConnectionStatus,
Uri? clearnetUri, Uri? clearnetUri,
Uri? onionUri, Uri? onionUri,
}) async { }) async {
HttpClient? torClient; HttpClient? torClient;
late bool torEnabled; late bool torEnabled;
torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled; torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled;
torConnectionStatus ??= torViewModel?.torConnectionStatus ?? TorConnectionStatus.disconnected;
if (torConnectionMode == TorConnectionMode.torOnly || if (torConnectionMode == TorConnectionMode.torOnly ||
torConnectionMode == TorConnectionMode.enabled) { torConnectionMode == TorConnectionMode.enabled) {
torEnabled = true; torEnabled = true;
@ -158,6 +168,10 @@ class ProxyWrapper {
torEnabled = false; 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 tor is enabled, try to connect to the onion url first:
if (torEnabled) { if (torEnabled) {

View file

@ -38,3 +38,42 @@ class TorConnectionMode extends EnumerableItem<int> with Serializable<int> {
} }
} }
} }
class TorConnectionStatus extends EnumerableItem<int> with Serializable<int> {
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 '';
}
}
}

View file

@ -16,8 +16,6 @@ part 'tor_view_model.g.dart';
class TorViewModel = TorViewModelBase with _$TorViewModel; class TorViewModel = TorViewModelBase with _$TorViewModel;
enum TorConnectionStatus { connecting, connected, disconnected }
abstract class TorViewModelBase with Store { abstract class TorViewModelBase with Store {
TorViewModelBase(this._settingsStore, this.nodes) { TorViewModelBase(this._settingsStore, this.nodes) {
reaction((_) => torConnectionMode, (TorConnectionMode mode) async { reaction((_) => torConnectionMode, (TorConnectionMode mode) async {