dev: more logging features to catch WalletInfo.hive getting corrupted

This commit is contained in:
Czarek Nakamoto 2025-05-20 21:48:45 +02:00
parent 9c8d22842a
commit 308a196fc6
8 changed files with 145 additions and 2 deletions

View file

@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
String? printVLogFilePath;
void printV(dynamic content) {
void printV(dynamic content, {bool separateMultiline = false}) {
CustomTrace programInfo = CustomTrace(StackTrace.current);
final logMsg = "${programInfo.fileName}#${programInfo.lineNumber}:${programInfo.columnNumber} ${programInfo.callerFunctionName}: $content";
if (printVLogFilePath != null) {
@ -14,8 +14,15 @@ void printV(dynamic content) {
print("Unable to write to log file (printV): $e");
}
}
if (separateMultiline) {
final lines = content.toString().split("\n");
for (final s in lines) {
print("${programInfo.fileName}#${programInfo.lineNumber}:${programInfo.columnNumber} ${programInfo.callerFunctionName}: $s");
}
} else {
print(logMsg);
}
}
// https://stackoverflow.com/a/59386101

View file

@ -111,6 +111,7 @@ class $BackupService {
Future<void> verifyWallets() async {
final walletInfoSource = await reloadHiveWalletInfoBox();
printV("WalletInfoSource length (backup service): ${walletInfoSource.length}");
correctWallets =
walletInfoSource.values.where((info) => availableWalletTypes.contains(info.type)).toList();

View file

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:ui';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
@ -205,8 +206,31 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
encryptionKey: transactionDescriptionsBoxKey);
final trades = await CakeHive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
final orders = await CakeHive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
var lsofProcess = await Process.start(
"/system/bin/lsof",
["walletinfo.hive", "walletinfo.lock"],
workingDirectory: (await getAppDir()).path,
runInShell: true,
);
printV("exitcode: ${await lsofProcess.exitCode}");
printV("__stderr: ${await lsofProcess.stderr.transform(utf8.decoder).join()}", separateMultiline: true);
printV("__stdout: ${await lsofProcess.stdout.transform(utf8.decoder).join()}", separateMultiline: true);
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
printV("WalletInfoSource length (initializeAppConfigs): ${walletInfoSource.length}");
lsofProcess = await Process.start(
"/system/bin/lsof",
["walletinfo.hive", "walletinfo.lock"],
workingDirectory: (await getAppDir()).path,
runInShell: true,
);
printV("exitcode: ${await lsofProcess.exitCode}");
printV("__stderr: ${await lsofProcess.stderr.transform(utf8.decoder).join()}", separateMultiline: true);
printV("__stdout: ${await lsofProcess.stdout.transform(utf8.decoder).join()}", separateMultiline: true);
final templates = await CakeHive.openBox<Template>(Template.boxName);
final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);

View file

@ -37,6 +37,7 @@ import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
import 'package:cake_wallet/src/screens/dev/hash_change_logs_page.dart';
import 'package:cake_wallet/src/screens/dev/lsof.dart';
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
import 'package:cake_wallet/src/screens/dev/print_verbose_logs_page.dart';
@ -928,6 +929,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.devPrintVerbose:
return MaterialPageRoute<void>(builder: (_) => PrintVerboseLogsPage());
case Routes.devLsof:
return MaterialPageRoute<void>(builder: (_) => DevLsof());
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

@ -120,6 +120,7 @@ class Routes {
static const devBackgroundSyncLogs = '/dev/background_sync_logs';
static const devHashChangeLogs = '/dev/hash_change_logs';
static const devPrintVerbose = '/dev/print_verbose';
static const devLsof = '/dev/lsof';
static const signPage = '/sign_page';
static const connectDevices = '/device/connect';

View file

@ -0,0 +1,63 @@
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/view_model/dev/lsof_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class DevLsof extends BasePage {
final LsofViewModel viewModel = LsofViewModel();
DevLsof() {
viewModel.refresh();
}
@override
String? get title => "[dev] lsof";
@override
Widget? trailing(BuildContext context) {
return IconButton(
icon: Icon(Icons.refresh),
onPressed: () => viewModel.refresh(),
);
}
@override
Widget body(BuildContext context) {
return Observer(
builder: (_) {
if (viewModel.logs == null) {
return Center(child: CircularProgressIndicator());
}
if (viewModel.logs == "") {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("No logs loaded"),
SizedBox(height: 16),
ElevatedButton(
onPressed: () => viewModel.refresh(),
child: Text("Load Logs"),
),
],
),
);
}
return Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SelectableText(
viewModel.logs??'',
style: TextStyle(fontSize: 8),
),
],
),
),
);
},
);
}
}

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
@ -10,6 +12,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.d
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -105,6 +108,12 @@ class OtherSettingsPage extends BasePage {
handler: (BuildContext context) =>
Navigator.of(context).pushNamed(Routes.devPrintVerbose),
),
if (kDebugMode && Platform.isAndroid)
SettingsCellWithArrow(
title: '[dev] lsof',
handler: (BuildContext context) =>
Navigator.of(context).pushNamed(Routes.devLsof),
),
Spacer(),
SettingsVersionCell(
title: S.of(context).version(_otherSettingsViewModel.currentVersion)),

View file

@ -0,0 +1,34 @@
import 'dart:convert';
import 'dart:io';
import 'package:cw_core/root_dir.dart';
import 'package:flutter_daemon/flutter_daemon.dart';
import 'package:mobx/mobx.dart';
part 'lsof_view_model.g.dart';
class LsofViewModel = LsofViewModelBase with _$LsofViewModel;
abstract class LsofViewModelBase with Store {
@observable
String? logs = null;
@action
Future<void> refresh() async {
final dir = await getAppDir();
final list = await dir.list(recursive: true);
final fList = await list.map((element) => element.path).toList();
var lsofProcess = await Process.start(
"/system/bin/lsof", fList,
// ["walletinfo.hive", "walletinfo.lock"],
workingDirectory: (await getAppDir()).path,
runInShell: true,
);
logs = '''exitcode: ${await lsofProcess.exitCode}
stderr: ${await lsofProcess.stderr.transform(utf8.decoder).join()}
stdout: ${await lsofProcess.stdout.transform(utf8.decoder).join()}
''';
}
}