Skip to content

Commit ff319df

Browse files
committed
feat: dev screen for file manager, snapshot and fuzzing
This commit adds tooling to find potential issues with code that are difficult to notice during debugging (especially on builds from the CI which lack debugging capabilities). File manager supports basic operations like browsing files, renaming, copying and removing Snapshots allow to take a snapshot of current app data, and compare to it later on with basic hexdump view - useful to notice anomalies or modifications to files that shouldn't be accessed. File watcher checks for file modifications in real time, which is used to see what actions are happening to the fs in real time. Fuzzing can be used to load/create wallets randomly to see if any of them will get corrupted (can be used in addition with wallet_fuzzer.sh script that kills the app and restarts the process at random intervals to simulate unexpected action that can happen for example in the background). In addition I've added toString method to {bitcoin,monero,nano ,zano}_wallet_keys.dart so I can easily compare the results when fuzzing without accessing wallet-specific code.
1 parent 7798049 commit ff319df

File tree

17 files changed

+3649
-0
lines changed

17 files changed

+3649
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,6 @@ flatpak-build/
227227
**/linux/flutter/generated_plugin_registrant.cc
228228
**/linux/flutter/generated_plugin_registrant.h
229229
**/linux/flutter/generated_plugins.cmake
230+
231+
232+
wallet_fuzzer_data/

cw_bitcoin/lib/bitcoin_wallet_keys.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,9 @@ class BitcoinWalletKeys {
44
final String wif;
55
final String privateKey;
66
final String publicKey;
7+
8+
@override
9+
String toString() {
10+
return 'BitcoinWalletKeys(wif: $wif, privateKey: $privateKey, publicKey: $publicKey)';
11+
}
712
}

cw_core/lib/monero_wallet_keys.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,9 @@ class MoneroWalletKeys {
1313
final String publicSpendKey;
1414
final String privateSpendKey;
1515
final String passphrase;
16+
17+
@override
18+
String toString() {
19+
return 'MoneroWalletKeys(primaryAddress: $primaryAddress, publicViewKey: $publicViewKey, privateViewKey: $privateViewKey, publicSpendKey: $publicSpendKey, privateSpendKey: $privateSpendKey, passphrase: $passphrase)';
20+
}
1621
}

cw_nano/lib/nano_wallet_keys.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ class NanoWalletKeys {
22
const NanoWalletKeys({required this.seedKey});
33

44
final String seedKey;
5+
6+
@override
7+
String toString() {
8+
return 'NanoWalletKeys(seedKey: $seedKey)';
9+
}
510
}

cw_zano/lib/model/zano_wallet_keys.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@ class ZanoWalletKeys {
99
final String privateViewKey;
1010
final String publicSpendKey;
1111
final String privateSpendKey;
12+
13+
@override
14+
String toString() {
15+
return 'ZanoWalletKeys(publicViewKey: $publicViewKey, privateViewKey: $privateViewKey, publicSpendKey: $publicSpendKey, privateSpendKey: $privateSpendKey)';
16+
}
1217
}

lib/di.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
3333
import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart';
3434
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
3535
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
36+
import 'package:cake_wallet/src/screens/dev/file_explorer.dart';
3637
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
3738
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
39+
import 'package:cake_wallet/src/screens/dev/wallet_fuzzer.dart';
3840
import 'package:cake_wallet/src/screens/settings/background_sync_page.dart';
3941
import 'package:cake_wallet/view_model/dev/monero_background_sync.dart';
4042
import 'package:cake_wallet/view_model/link_view_model.dart';
@@ -1450,5 +1452,9 @@ Future<void> setup({
14501452

14511453
getIt.registerFactory(() => DevMoneroBackgroundSyncPage(getIt.get<DevMoneroBackgroundSync>()));
14521454
getIt.registerFactory(() => DevMoneroCallProfilerPage());
1455+
1456+
getIt.registerFactory(() => FileExplorerPage());
1457+
getIt.registerFactory(() => WalletFuzzerPage());
1458+
14531459
_isSetupFinished = true;
14541460
}

lib/main.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ import 'package:cake_wallet/store/authentication_store.dart';
2828
import 'package:cake_wallet/themes/theme_base.dart';
2929
import 'package:cake_wallet/utils/device_info.dart';
3030
import 'package:cake_wallet/utils/exception_handler.dart';
31+
import 'package:cake_wallet/utils/feature_flag.dart';
3132
import 'package:cake_wallet/view_model/link_view_model.dart';
3233
import 'package:cake_wallet/utils/responsive_layout_util.dart';
34+
import 'package:cake_wallet/view_model/dev/file_explorer.dart';
3335
import 'package:cw_core/address_info.dart';
3436
import 'package:cw_core/cake_hive.dart';
3537
import 'package:cw_core/hive_type_ids.dart';
@@ -63,6 +65,9 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
6365

6466
await runZonedGuarded(() async {
6567
WidgetsFlutterBinding.ensureInitialized();
68+
if (FeatureFlag.hasDevOptions) {
69+
await checkAndStartFileMonitoring();
70+
}
6671
FlutterError.onError = ExceptionHandler.onError;
6772

6873
/// A callback that is invoked when an unhandled error occurs in the root
@@ -428,3 +433,15 @@ Future<void> backgroundSync() async {
428433
}
429434
}
430435
}
436+
437+
Future<void> checkAndStartFileMonitoring() async {
438+
try {
439+
final shouldMonitor = await FileExplorerViewModelBase.checkDevMonitorFileExists();
440+
if (shouldMonitor) {
441+
printV('Dev file monitoring enabled, starting file system watcher...');
442+
await FileExplorerViewModelBase.startMonitoring();
443+
}
444+
} catch (e) {
445+
printV('Failed to initialize file monitoring: $e');
446+
}
447+
}

lib/router.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
3535
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
3636
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
3737
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
38+
import 'package:cake_wallet/src/screens/dev/file_explorer.dart';
3839
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
3940
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
41+
import 'package:cake_wallet/src/screens/dev/wallet_fuzzer.dart';
4042
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
4143
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
4244
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
@@ -842,6 +844,16 @@ Route<dynamic> createRoute(RouteSettings settings) {
842844
builder: (_) => getIt.get<DevMoneroCallProfilerPage>(),
843845
);
844846

847+
case Routes.devFileExplorer:
848+
return MaterialPageRoute<void>(
849+
builder: (_) => getIt.get<FileExplorerPage>(),
850+
);
851+
852+
case Routes.devWalletFuzzer:
853+
return MaterialPageRoute<void>(
854+
builder: (_) => getIt.get<WalletFuzzerPage>(),
855+
);
856+
845857
default:
846858
return MaterialPageRoute<void>(
847859
builder: (_) => Scaffold(

lib/routes.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class Routes {
113113
static const backgroundSync = '/background_sync';
114114
static const devMoneroBackgroundSync = '/dev/monero_background_sync';
115115
static const devMoneroCallProfiler = '/dev/monero_call_profiler';
116+
static const devFileExplorer = '/dev/file_explorer';
117+
static const devWalletFuzzer = '/dev/wallet_fuzzer';
116118
static const signPage = '/sign_page';
117119
static const connectDevices = '/device/connect';
118120
static const urqrAnimatedPage = '/urqr/animated_page';

0 commit comments

Comments
 (0)