add mutex around _confirmForm to prevent the wallets from breaking (#1602)
Some checks are pending
Cache Dependencies / test (push) Waiting to run

* add mutex around _confirmForm to prevent the wallets from breaking

* add async

* drop mutex for a boolean

* don't make the variable global
This commit is contained in:
cyan 2024-08-13 15:47:37 +02:00 committed by GitHub
parent 2949299821
commit 4b69277858
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 106 additions and 82 deletions

View file

@ -25,6 +25,7 @@ import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart'; import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/entities/seed_type.dart'; import 'package:cake_wallet/entities/seed_type.dart';
class NewWalletPage extends BasePage { class NewWalletPage extends BasePage {
NewWalletPage(this._walletNewVM, this._seedTypeViewModel); NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
@ -74,6 +75,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
_walletNewVM.hasWalletPassword ? TextEditingController() : null; _walletNewVM.hasWalletPassword ? TextEditingController() : null;
static const aspectRatioImage = 1.22; static const aspectRatioImage = 1.22;
static bool formProcessing = false;
final GlobalKey<FormState> _formKey; final GlobalKey<FormState> _formKey;
final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey; final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
@ -347,26 +349,35 @@ class _WalletNameFormState extends State<WalletNameForm> {
); );
} }
void _confirmForm() { void _confirmForm() async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) { if (formProcessing) return;
return; formProcessing = true;
} try {
if (_walletNewVM.nameExists(_walletNewVM.name)) { if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
showPopUp<void>( formProcessing = false;
context: context, return;
builder: (_) { }
return AlertWithOneAction( if (_walletNewVM.nameExists(_walletNewVM.name)) {
alertTitle: '', await showPopUp<void>(
alertContent: S.of(context).wallet_name_exists, context: context,
buttonText: S.of(context).ok, builder: (_) {
buttonAction: () => Navigator.of(context).pop()); return AlertWithOneAction(
}); alertTitle: '',
} else { alertContent: S.of(context).wallet_name_exists,
_walletNewVM.create( buttonText: S.of(context).ok,
options: _walletNewVM.hasLanguageSelector buttonAction: () => Navigator.of(context).pop());
? [_languageSelectorKey.currentState!.selected, isPolyseed] });
: null); } else {
await _walletNewVM.create(
options: _walletNewVM.hasLanguageSelector
? [_languageSelectorKey.currentState!.selected, isPolyseed]
: null);
}
} catch (e) {
formProcessing = false;
rethrow;
} }
formProcessing = false;
} }
bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed; bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;

View file

@ -2,6 +2,7 @@ import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart'; import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart'; import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@ -80,6 +81,8 @@ class WalletRestorePage extends BasePage {
}); });
} }
static bool formProcessing = false;
@override @override
Widget middle(BuildContext context) => Observer( Widget middle(BuildContext context) => Observer(
builder: (_) => Text( builder: (_) => Text(
@ -350,75 +353,85 @@ class WalletRestorePage extends BasePage {
} }
Future<void> _confirmForm(BuildContext context) async { Future<void> _confirmForm(BuildContext context) async {
// Dismissing all visible keyboard to provide context for navigation if (formProcessing) return;
FocusManager.instance.primaryFocus?.unfocus(); formProcessing = true;
try {
// Dismissing all visible keyboard to provide context for navigation
FocusManager.instance.primaryFocus?.unfocus();
late BuildContext? formContext; late BuildContext? formContext;
late GlobalKey<FormState>? formKey; late GlobalKey<FormState>? formKey;
late String name; late String name;
if (walletRestoreViewModel.mode == WalletRestoreMode.seed) { if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
formContext = walletRestoreFromSeedFormKey.currentContext; formContext = walletRestoreFromSeedFormKey.currentContext;
formKey = walletRestoreFromSeedFormKey.currentState!.formKey; formKey = walletRestoreFromSeedFormKey.currentState!.formKey;
name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text; name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text;
} else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) { } else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
formContext = walletRestoreFromKeysFormKey.currentContext; formContext = walletRestoreFromKeysFormKey.currentContext;
formKey = walletRestoreFromKeysFormKey.currentState!.formKey; formKey = walletRestoreFromKeysFormKey.currentState!.formKey;
name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text; name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text;
}
if (!formKey!.currentState!.validate()) {
return;
}
if (walletRestoreViewModel.nameExists(name)) {
showNameExistsAlert(formContext!);
return;
}
walletRestoreViewModel.state = IsExecutingState();
DerivationInfo? dInfo;
// get info about the different derivations:
List<DerivationInfo> derivations =
await walletRestoreViewModel.getDerivationInfo(_credentials());
int derivationsWithHistory = 0;
int derivationWithHistoryIndex = 0;
for (int i = 0; i < derivations.length; i++) {
if (derivations[i].transactionsCount > 0) {
derivationsWithHistory++;
derivationWithHistoryIndex = i;
} }
}
if (derivationsWithHistory > 1) { if (!formKey!.currentState!.validate()) {
dInfo = await Navigator.of(context).pushNamed( formProcessing = false;
Routes.restoreWalletChooseDerivation, return;
arguments: derivations,
) as DerivationInfo?;
} else if (derivationsWithHistory == 1) {
dInfo = derivations[derivationWithHistoryIndex];
}
// get the default derivation for this wallet type:
if (dInfo == null) {
// we only return 1 derivation if we're pretty sure we know which one to use:
if (derivations.length == 1) {
dInfo = derivations.first;
} else {
// if we have multiple possible derivations, and none have histories
// we just default to the most common one:
dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
} }
}
this.derivationInfo = dInfo; if (walletRestoreViewModel.nameExists(name)) {
if (this.derivationInfo == null) { showNameExistsAlert(formContext!);
this.derivationInfo = walletRestoreViewModel.getDefaultDerivation(); formProcessing = false;
} return;
}
walletRestoreViewModel.create(options: _credentials()); walletRestoreViewModel.state = IsExecutingState();
DerivationInfo? dInfo;
// get info about the different derivations:
List<DerivationInfo> derivations =
await walletRestoreViewModel.getDerivationInfo(_credentials());
int derivationsWithHistory = 0;
int derivationWithHistoryIndex = 0;
for (int i = 0; i < derivations.length; i++) {
if (derivations[i].transactionsCount > 0) {
derivationsWithHistory++;
derivationWithHistoryIndex = i;
}
}
if (derivationsWithHistory > 1) {
dInfo = await Navigator.of(context).pushNamed(
Routes.restoreWalletChooseDerivation,
arguments: derivations,
) as DerivationInfo?;
} else if (derivationsWithHistory == 1) {
dInfo = derivations[derivationWithHistoryIndex];
}
// get the default derivation for this wallet type:
if (dInfo == null) {
// we only return 1 derivation if we're pretty sure we know which one to use:
if (derivations.length == 1) {
dInfo = derivations.first;
} else {
// if we have multiple possible derivations, and none have histories
// we just default to the most common one:
dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
}
}
this.derivationInfo = dInfo;
if (this.derivationInfo == null) {
this.derivationInfo = walletRestoreViewModel.getDefaultDerivation();
}
await walletRestoreViewModel.create(options: _credentials());
} catch (e) {
formProcessing = false;
rethrow;
}
formProcessing = false;
} }
Future<void> showNameExistsAlert(BuildContext context) { Future<void> showNameExistsAlert(BuildContext context) {