fix: clean up and fix some churning stuff

This commit is contained in:
julian 2024-11-08 14:21:34 -06:00
parent cfc5e88c2a
commit 732e919658
5 changed files with 97 additions and 8 deletions

View file

@ -186,8 +186,11 @@ class _ChurningProgressViewState extends ConsumerState<ChurningProgressView> {
height: 20, height: 20,
), ),
ProgressItem( ProgressItem(
iconAsset: Assets.svg.peers, iconAsset: Assets.svg.alertCircle,
label: "Waiting for balance to unlock", label: "Waiting for balance to unlock ${ref.watch(
pChurningService(widget.walletId)
.select((s) => s.confirmsInfo),
) ?? ""}",
status: ref.watch( status: ref.watch(
pChurningService(widget.walletId) pChurningService(widget.walletId)
.select((s) => s.waitingForUnlockedBalance), .select((s) => s.waitingForUnlockedBalance),
@ -197,7 +200,7 @@ class _ChurningProgressViewState extends ConsumerState<ChurningProgressView> {
height: 12, height: 12,
), ),
ProgressItem( ProgressItem(
iconAsset: Assets.svg.fusing, iconAsset: Assets.svg.churn,
label: "Creating churn transaction", label: "Creating churn transaction",
status: ref.watch( status: ref.watch(
pChurningService(widget.walletId) pChurningService(widget.walletId)

View file

@ -17,6 +17,7 @@ import '../../widgets/custom_buttons/checkbox_text_button.dart';
import '../../widgets/desktop/primary_button.dart'; import '../../widgets/desktop/primary_button.dart';
import '../../widgets/rounded_container.dart'; import '../../widgets/rounded_container.dart';
import '../../widgets/rounded_white_container.dart'; import '../../widgets/rounded_white_container.dart';
import '../../widgets/stack_dialog.dart';
import '../../widgets/stack_text_field.dart'; import '../../widgets/stack_text_field.dart';
import 'churning_progress_view.dart'; import 'churning_progress_view.dart';
import 'churning_rounds_selection_sheet.dart'; import 'churning_rounds_selection_sheet.dart';
@ -111,7 +112,23 @@ class _ChurnViewState extends ConsumerState<ChurningView> {
.topNavIconPrimary, .topNavIconPrimary,
), ),
onPressed: () async { onPressed: () async {
//' TODO show about? await showDialog<void>(
context: context,
builder: (context) => const StackOkDialog(
title: "What is churning?",
message: "Churning in a Monero wallet involves"
" sending Monero to oneself in multiple"
" transactions, which can enhance privacy"
" by making it harder for observers to "
"link your transactions. This process"
" re-mixes the funds within the network,"
" helping obscure transaction history. "
"Churning is optional and mainly beneficial"
" in scenarios where maximum privacy is"
" desired or if you received the Monero from"
" a source from which you'd like to disassociate.",
),
);
}, },
), ),
), ),

View file

@ -134,6 +134,9 @@ class _DesktopChurning extends ConsumerState<DesktopChurningView> {
Assets.svg.churn, Assets.svg.churn,
width: 32, width: 32,
height: 32, height: 32,
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
), ),
const SizedBox( const SizedBox(
width: 12, width: 12,
@ -206,7 +209,17 @@ class _DesktopChurning extends ConsumerState<DesktopChurningView> {
height: 16, height: 16,
), ),
Text( Text(
"Churning info text", "Churning in a Monero wallet involves"
" sending Monero to oneself in multiple"
" transactions, which can enhance privacy"
" by making it harder for observers to "
"link your transactions. This process"
" re-mixes the funds within the network,"
" helping obscure transaction history. "
"Churning is optional and mainly beneficial"
" in scenarios where maximum privacy is"
" desired or if you received the Monero from"
" a source from which you'd like to disassociate.",
style: style:
STextStyles.desktopTextMedium( STextStyles.desktopTextMedium(
context, context,

View file

@ -236,8 +236,11 @@ class _ChurnDialogViewState extends ConsumerState<ChurnDialogView> {
height: 20, height: 20,
), ),
ProgressItem( ProgressItem(
iconAsset: Assets.svg.peers, iconAsset: Assets.svg.alertCircle,
label: "Waiting for balance to unlock", label: "Waiting for balance to unlock ${ref.watch(
pChurningService(widget.walletId)
.select((s) => s.confirmsInfo),
) ?? ""}",
status: ref.watch( status: ref.watch(
pChurningService(widget.walletId) pChurningService(widget.walletId)
.select((s) => s.waitingForUnlockedBalance), .select((s) => s.waitingForUnlockedBalance),
@ -247,7 +250,7 @@ class _ChurnDialogViewState extends ConsumerState<ChurnDialogView> {
height: 12, height: 12,
), ),
ProgressItem( ProgressItem(
iconAsset: Assets.svg.fusing, iconAsset: Assets.svg.churn,
label: "Creating churn transaction", label: "Creating churn transaction",
status: ref.watch( status: ref.watch(
pChurningService(widget.walletId) pChurningService(widget.walletId)

View file

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:math';
import 'package:cs_monero/cs_monero.dart'; import 'package:cs_monero/cs_monero.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -42,6 +43,56 @@ class ChurningService extends ChangeNotifier {
} }
} }
String? confirmsInfo;
Future<void> _updateConfirmsInfo() async {
final currentHeight = wallet.currentKnownChainHeight;
if (currentHeight < 1) {
return;
}
final outputs = await csWallet.getOutputs(refresh: true);
final required = wallet.cryptoCurrency.minConfirms;
int lowestNumberOfConfirms = required;
for (final output in outputs.where((e) => !e.isFrozen && !e.spent)) {
final confirms = currentHeight - output.height;
lowestNumberOfConfirms = min(lowestNumberOfConfirms, confirms);
}
final bool shouldNotify;
if (lowestNumberOfConfirms == required) {
shouldNotify = confirmsInfo != null;
confirmsInfo = null;
} else {
final prev = confirmsInfo;
confirmsInfo = "($lowestNumberOfConfirms/$required)";
shouldNotify = confirmsInfo != prev;
}
if (_running && _timerRunning && shouldNotify) {
notifyListeners();
}
}
Timer? _confirmsTimer;
bool _timerRunning = false;
void _stopConfirmsTimer() {
_timerRunning = false;
_confirmsTimer?.cancel();
confirmsInfo = null;
_confirmsTimer = null;
}
void _startConfirmsTimer() {
_confirmsTimer?.cancel();
_confirmsTimer = Timer.periodic(
const Duration(seconds: 5),
(_) => _updateConfirmsInfo(),
);
}
final _pause = Mutex(); final _pause = Mutex();
bool get isPaused => _pause.isLocked; bool get isPaused => _pause.isLocked;
void unpause() { void unpause() {
@ -75,6 +126,7 @@ class ChurningService extends ChangeNotifier {
notifyListeners(); notifyListeners();
try { try {
_stopConfirmsTimer();
Logging.log?.i("Doing churn #${roundsCompleted + 1}"); Logging.log?.i("Doing churn #${roundsCompleted + 1}");
await _churnTxSimple(); await _churnTxSimple();
waitingForUnlockedBalance = ChurnStatus.success; waitingForUnlockedBalance = ChurnStatus.success;
@ -106,6 +158,7 @@ class ChurningService extends ChangeNotifier {
} }
if (!complete() && _running) { if (!complete() && _running) {
_startConfirmsTimer();
waitingForUnlockedBalance = ChurnStatus.running; waitingForUnlockedBalance = ChurnStatus.running;
makingChurnTransaction = ChurnStatus.waiting; makingChurnTransaction = ChurnStatus.waiting;
completedStatus = ChurnStatus.waiting; completedStatus = ChurnStatus.waiting;