Skip to content

Commit 095083d

Browse files
authored
Merge pull request #2584 from SatoshiPortal/feat/tor-persistence
feat(tor): persist transport preferences
2 parents 5809b3f + 6c5dd70 commit 095083d

26 files changed

Lines changed: 14162 additions & 24 deletions

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
lib/core/storage/schemas/**/drift_schema_v*.json linguist-generated
2+
lib/core/storage/*.steps.dart linguist-generated
3+
test/migrations_test/**/generated/*.dart linguist-generated

lib/core/core_locator.dart

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import 'package:bb_mobile/core/ledger/ledger_locator.dart';
99
import 'package:bb_mobile/core/mempool/mempool_locator.dart';
1010
import 'package:bb_mobile/core/recoverbull/recoverbull_locator.dart';
1111
import 'package:bb_mobile/core/seed/seed_locator.dart';
12+
import 'package:bb_mobile/core/settings/domain/repositories/settings_repository.dart'
13+
as settings;
1214
import 'package:bb_mobile/core/settings/settings_locator.dart';
1315
import 'package:bb_mobile/core/storage/sqlite_database.dart';
1416
import 'package:bb_mobile/core/storage/storage_locator.dart';
@@ -55,7 +57,25 @@ class CoreLocator {
5557
}
5658

5759
static Future<void> registerRepositories(GetIt locator) async {
58-
bull_tor.TorLocator.registerRepositories(locator);
60+
await SettingsLocator.registerRepositories(locator);
61+
final settingsRepository = locator<settings.SettingsRepository>();
62+
final appSettings = await settingsRepository.fetch();
63+
bull_tor.TorLocator.registerRepositories(
64+
locator,
65+
initialMode: appSettings.torTransportMode,
66+
lastSuccessfulTransport: appSettings.lastSuccessfulTorTransport,
67+
onSuccessfulTransport: (transport) async {
68+
try {
69+
await settingsRepository.setLastSuccessfulTorTransport(transport);
70+
} catch (error, stackTrace) {
71+
log.warning(
72+
'Could not persist the successful Tor transport',
73+
error: error,
74+
trace: stackTrace,
75+
);
76+
}
77+
},
78+
);
5979
BlockchainLocator.registerRepositories(locator);
6080
ElectrumLocator.registerRepositories(locator);
6181
ExchangeLocator.registerRepositories(locator);

lib/core/settings/data/settings_datasource.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:bb_mobile/core/settings/data/settings_model.dart';
22
import 'package:bb_mobile/core/settings/domain/settings_entity.dart';
33
import 'package:bb_mobile/core/storage/sqlite_database.dart';
44
import 'package:drift/drift.dart';
5+
import 'package:bull_tor/tor.dart';
56

67
class SettingsDatasource {
78
final SqliteDatabase _sqlite;
@@ -73,6 +74,21 @@ class SettingsDatasource {
7374
);
7475
}
7576

77+
Future<void> setTorTransportMode(TorTransportMode mode) async {
78+
await _sqlite.managers.settings.update(
79+
(f) => f(id: const Value(1), torTransportMode: Value(mode.name)),
80+
);
81+
}
82+
83+
Future<void> setLastSuccessfulTorTransport(TorTransport transport) async {
84+
await _sqlite.managers.settings.update(
85+
(f) => f(
86+
id: const Value(1),
87+
lastSuccessfulTorTransport: Value(transport.name),
88+
),
89+
);
90+
}
91+
7692
Future<void> setThemeMode(AppThemeMode themeMode) async {
7793
await _sqlite.managers.settings.update(
7894
(f) => f(id: const Value(1), themeMode: Value(themeMode.name)),

lib/core/settings/data/settings_model.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:bb_mobile/core/settings/domain/settings_entity.dart';
22
import 'package:bb_mobile/core/storage/sqlite_database.dart';
3+
import 'package:bull_tor/tor.dart';
34

45
class SettingsModel {
56
final int id;
@@ -12,6 +13,8 @@ class SettingsModel {
1213
final bool isDevModeEnabled;
1314
final bool useTorProxy;
1415
final int torProxyPort;
16+
final TorTransportMode torTransportMode;
17+
final TorTransport? lastSuccessfulTorTransport;
1518
final AppThemeMode themeMode;
1619
final bool isErrorReportingEnabled;
1720
final String? exchangeTestnetBasicAuthUsername;
@@ -28,6 +31,8 @@ class SettingsModel {
2831
required this.isDevModeEnabled,
2932
required this.useTorProxy,
3033
required this.torProxyPort,
34+
required this.torTransportMode,
35+
this.lastSuccessfulTorTransport,
3136
required this.themeMode,
3237
required this.isErrorReportingEnabled,
3338
this.exchangeTestnetBasicAuthUsername,
@@ -46,6 +51,8 @@ class SettingsModel {
4651
isDevModeEnabled: isDevModeEnabled,
4752
useTorProxy: useTorProxy,
4853
torProxyPort: torProxyPort,
54+
torTransportMode: torTransportMode.name,
55+
lastSuccessfulTorTransport: lastSuccessfulTorTransport?.name,
4956
themeMode: themeMode.name,
5057
isErrorReportingEnabled: isErrorReportingEnabled,
5158
exchangeTestnetBasicAuthUsername: exchangeTestnetBasicAuthUsername,
@@ -65,6 +72,15 @@ class SettingsModel {
6572
isDevModeEnabled: row.isDevModeEnabled,
6673
useTorProxy: row.useTorProxy,
6774
torProxyPort: row.torProxyPort,
75+
torTransportMode: TorTransportMode.values.firstWhere(
76+
(mode) => mode.name == row.torTransportMode,
77+
orElse: () => TorTransportMode.automatic,
78+
),
79+
lastSuccessfulTorTransport: switch (row.lastSuccessfulTorTransport) {
80+
'direct' => TorTransport.direct,
81+
'snowflake' => TorTransport.snowflake,
82+
_ => null,
83+
},
6884
themeMode: AppThemeMode.fromName(row.themeMode),
6985
isErrorReportingEnabled: row.isErrorReportingEnabled,
7086
exchangeTestnetBasicAuthUsername: row.exchangeTestnetBasicAuthUsername,

lib/core/settings/data/settings_repository.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:bb_mobile/core/settings/domain/repositories/settings_repository.
66
as domain;
77
import 'package:bb_mobile/core/settings/domain/settings_entity.dart';
88
import 'package:bb_mobile/core/utils/report.dart';
9+
import 'package:bull_tor/tor.dart';
910

1011
class SettingsRepository implements domain.SettingsRepository {
1112
final SettingsDatasource _settingsDatasource;
@@ -34,6 +35,8 @@ class SettingsRepository implements domain.SettingsRepository {
3435
required bool isDevModeEnabled,
3536
required bool useTorProxy,
3637
required int torProxyPort,
38+
TorTransportMode torTransportMode = TorTransportMode.automatic,
39+
TorTransport? lastSuccessfulTorTransport,
3740
AppThemeMode themeMode = AppThemeMode.system,
3841
bool isErrorReportingEnabled = false,
3942
String? exchangeTestnetBasicAuthUsername,
@@ -51,6 +54,8 @@ class SettingsRepository implements domain.SettingsRepository {
5154
isDevModeEnabled: isDevModeEnabled,
5255
useTorProxy: useTorProxy,
5356
torProxyPort: torProxyPort,
57+
torTransportMode: torTransportMode,
58+
lastSuccessfulTorTransport: lastSuccessfulTorTransport,
5459
themeMode: themeMode,
5560
isErrorReportingEnabled: isErrorReportingEnabled,
5661
exchangeTestnetBasicAuthUsername: exchangeTestnetBasicAuthUsername,
@@ -73,6 +78,8 @@ class SettingsRepository implements domain.SettingsRepository {
7378
isDevModeEnabled: s.isDevModeEnabled,
7479
useTorProxy: s.useTorProxy,
7580
torProxyPort: s.torProxyPort,
81+
torTransportMode: s.torTransportMode,
82+
lastSuccessfulTorTransport: s.lastSuccessfulTorTransport,
7683
themeMode: s.themeMode,
7784
isErrorReportingEnabled: s.isErrorReportingEnabled,
7885
exchangeTestnetBasicAuthUsername: s.exchangeTestnetBasicAuthUsername,
@@ -126,6 +133,16 @@ class SettingsRepository implements domain.SettingsRepository {
126133
await _settingsDatasource.setTorProxyPort(port);
127134
}
128135

136+
@override
137+
Future<void> setTorTransportMode(TorTransportMode mode) async {
138+
await _settingsDatasource.setTorTransportMode(mode);
139+
}
140+
141+
@override
142+
Future<void> setLastSuccessfulTorTransport(TorTransport transport) async {
143+
await _settingsDatasource.setLastSuccessfulTorTransport(transport);
144+
}
145+
129146
@override
130147
Future<void> setThemeMode(AppThemeMode themeMode) async {
131148
await _settingsDatasource.setThemeMode(themeMode);

lib/core/settings/domain/repositories/settings_repository.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22

33
import 'package:bb_mobile/core/settings/domain/settings_entity.dart';
4+
import 'package:bull_tor/tor.dart';
45

56
abstract class SettingsRepository {
67
Stream<String> get currencyChangeStream;
@@ -18,6 +19,8 @@ abstract class SettingsRepository {
1819
required bool isDevModeEnabled,
1920
required bool useTorProxy,
2021
required int torProxyPort,
22+
TorTransportMode torTransportMode = TorTransportMode.automatic,
23+
TorTransport? lastSuccessfulTorTransport,
2124
AppThemeMode themeMode = AppThemeMode.system,
2225
bool isErrorReportingEnabled = false,
2326
String? exchangeTestnetBasicAuthUsername,
@@ -44,6 +47,10 @@ abstract class SettingsRepository {
4447

4548
Future<void> setTorProxyPort(int port);
4649

50+
Future<void> setTorTransportMode(TorTransportMode mode);
51+
52+
Future<void> setLastSuccessfulTorTransport(TorTransport transport);
53+
4754
Future<void> setThemeMode(AppThemeMode themeMode);
4855

4956
Future<void> setErrorReportingEnabled(bool enabled);

lib/core/settings/domain/settings_entity.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:ui';
33
import 'package:bb_mobile/core/utils/logger.dart';
44
import 'package:flutter/material.dart';
55
import 'package:freezed_annotation/freezed_annotation.dart';
6+
import 'package:bull_tor/tor.dart';
67

78
part 'settings_entity.freezed.dart';
89

@@ -141,6 +142,8 @@ abstract class SettingsEntity with _$SettingsEntity {
141142
bool? isDevModeEnabled,
142143
@Default(false) bool useTorProxy,
143144
@Default(9050) int torProxyPort,
145+
@Default(TorTransportMode.automatic) TorTransportMode torTransportMode,
146+
TorTransport? lastSuccessfulTorTransport,
144147
@Default(AppThemeMode.system) AppThemeMode themeMode,
145148
@Default(false) bool isErrorReportingEnabled,
146149
String? exchangeTestnetBasicAuthUsername,

lib/core/storage/database_seeds.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class DatabaseSeeds {
2121
isDevModeEnabled: false,
2222
useTorProxy: false,
2323
torProxyPort: 9050,
24+
torTransportMode: 'automatic',
2425
themeMode: 'system',
2526
isErrorReportingEnabled: false,
2627
),

lib/core/storage/migrations/migrations.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export 'package:bb_mobile/core/storage/migrations/schema_10_to_11.dart';
33
export 'package:bb_mobile/core/storage/migrations/schema_11_to_12.dart';
44
export 'package:bb_mobile/core/storage/migrations/schema_12_to_13.dart';
55
export 'package:bb_mobile/core/storage/migrations/schema_13_to_14.dart';
6+
export 'package:bb_mobile/core/storage/migrations/schema_14_to_15.dart';
67
export 'package:bb_mobile/core/storage/migrations/schema_1_to_2.dart';
78
export 'package:bb_mobile/core/storage/migrations/schema_2_to_3.dart';
89
export 'package:bb_mobile/core/storage/migrations/schema_3_to_4.dart';

lib/core/storage/migrations/schema_13_to_14.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import 'package:drift/drift.dart';
88
/// - Records which home announcements the user has dismissed (announcement id
99
/// + dismissal timestamp). New table, created empty.
1010
///
11-
/// Schema 14 also briefly carried the Payjoin policy columns on `settings` and
12-
/// an `is_aborted` flag on the payjoin tables. Payjoin now owns its own
13-
/// database (payjoin.sqlite, see the bull_payjoin package), and 14 was never
14-
/// released — every tag up to v6.12.5 ships schema 13 — so those columns were
15-
/// folded out of this step rather than added and then migrated away.
11+
/// During development, schema 14 briefly carried the Payjoin policy columns on
12+
/// `settings` and an `is_aborted` flag on the payjoin tables. Payjoin now owns
13+
/// its own database (payjoin.sqlite, see the bull_payjoin package), so those
14+
/// columns were folded out before schema 14 shipped in v6.13.0 rather than
15+
/// added and then migrated away.
1616
///
1717
/// Adds the order_swaps table and indexes for crash-safe Exchange transfers.
1818
/// The table includes the nullable quoted_amount_sat column used to validate

0 commit comments

Comments
 (0)