listen to Tor status changes and update node accordingly

This commit is contained in:
sneurlax 2024-05-03 19:56:27 -05:00
parent 86bd8f93c8
commit 0221841ee3
2 changed files with 138 additions and 20 deletions

View file

@ -19,9 +19,13 @@ import 'package:flutter_libmonero/core/wallet_creation_service.dart';
import 'package:flutter_libmonero/monero/monero.dart' as xmr_dart; import 'package:flutter_libmonero/monero/monero.dart' as xmr_dart;
import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output; import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output;
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/db/hive/db.dart'; import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/services/tor_service.dart';
import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
@ -35,7 +39,38 @@ import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cw_based_inte
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class MoneroWallet extends CryptonoteWallet with CwBasedInterface { class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
MoneroWallet(CryptoCurrencyNetwork network) : super(Monero(network)); MoneroWallet(CryptoCurrencyNetwork network) : super(Monero(network)) {
final bus = GlobalEventBus.instance;
// Listen for tor status changes.
_torStatusListener = bus.on<TorConnectionStatusChangedEvent>().listen(
(event) async {
switch (event.newStatus) {
case TorConnectionStatus.connecting:
if (!_torConnectingLock.isLocked) {
await _torConnectingLock.acquire();
}
_requireMutex = true;
break;
case TorConnectionStatus.connected:
case TorConnectionStatus.disconnected:
if (_torConnectingLock.isLocked) {
_torConnectingLock.release();
}
_requireMutex = false;
break;
}
},
);
// Listen for tor preference changes.
_torPreferenceListener = bus.on<TorPreferenceChangedEvent>().listen(
(event) async {
await updateNode();
},
);
}
@override @override
Address addressFor({required int index, int account = 0}) { Address addressFor({required int index, int account = 0}) {
@ -159,15 +194,31 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
if (prefs.useTor) { if (prefs.useTor) {
proxy = TorService.sharedInstance.getProxyInfo(); proxy = TorService.sharedInstance.getProxyInfo();
} }
await CwBasedInterface.cwWalletBase?.connectToNode( if (_requireMutex) {
node: Node( await _torConnectingLock.protect(() async {
uri: "$host:${node.port}", await CwBasedInterface.cwWalletBase?.connectToNode(
type: WalletType.monero, node: Node(
trusted: node.trusted ?? false, uri: "$host:${node.port}",
), type: WalletType.monero,
socksProxyAddress: trusted: node.trusted ?? false,
proxy == null ? null : "${proxy.host.address}:${proxy.port}", ),
); socksProxyAddress:
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
);
});
} else {
await CwBasedInterface.cwWalletBase?.connectToNode(
node: Node(
uri: "$host:${node.port}",
type: WalletType.monero,
trusted: node.trusted ?? false,
),
socksProxyAddress:
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
);
}
return;
} }
@override @override
@ -655,4 +706,12 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
return info.cachedBalance.total; return info.cachedBalance.total;
} }
} }
// ============== Private ====================================================
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
final Mutex _torConnectingLock = Mutex();
bool _requireMutex = false;
} }

View file

@ -20,9 +20,13 @@ import 'package:flutter_libmonero/view_model/send/output.dart'
as wownero_output; as wownero_output;
import 'package:flutter_libmonero/wownero/wownero.dart' as wow_dart; import 'package:flutter_libmonero/wownero/wownero.dart' as wow_dart;
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/db/hive/db.dart'; import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/services/tor_service.dart';
import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
@ -36,7 +40,38 @@ import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cw_based_inte
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class WowneroWallet extends CryptonoteWallet with CwBasedInterface { class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
WowneroWallet(CryptoCurrencyNetwork network) : super(Wownero(network)); WowneroWallet(CryptoCurrencyNetwork network) : super(Wownero(network)) {
final bus = GlobalEventBus.instance;
// Listen for tor status changes.
_torStatusListener = bus.on<TorConnectionStatusChangedEvent>().listen(
(event) async {
switch (event.newStatus) {
case TorConnectionStatus.connecting:
if (!_torConnectingLock.isLocked) {
await _torConnectingLock.acquire();
}
_requireMutex = true;
break;
case TorConnectionStatus.connected:
case TorConnectionStatus.disconnected:
if (_torConnectingLock.isLocked) {
_torConnectingLock.release();
}
_requireMutex = false;
break;
}
},
);
// Listen for tor preference changes.
_torPreferenceListener = bus.on<TorPreferenceChangedEvent>().listen(
(event) async {
await updateNode();
},
);
}
@override @override
Address addressFor({required int index, int account = 0}) { Address addressFor({required int index, int account = 0}) {
@ -148,15 +183,31 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
if (prefs.useTor) { if (prefs.useTor) {
proxy = TorService.sharedInstance.getProxyInfo(); proxy = TorService.sharedInstance.getProxyInfo();
} }
await CwBasedInterface.cwWalletBase?.connectToNode( if (_requireMutex) {
node: Node( await _torConnectingLock.protect(() async {
uri: "$host:${node.port}", await CwBasedInterface.cwWalletBase?.connectToNode(
type: WalletType.wownero, node: Node(
trusted: node.trusted ?? false, uri: "$host:${node.port}",
), type: WalletType.wownero,
socksProxyAddress: trusted: node.trusted ?? false,
proxy == null ? null : "${proxy.host.address}:${proxy.port}", ),
); socksProxyAddress:
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
);
});
} else {
await CwBasedInterface.cwWalletBase?.connectToNode(
node: Node(
uri: "$host:${node.port}",
type: WalletType.wownero,
trusted: node.trusted ?? false,
),
socksProxyAddress:
proxy == null ? null : "${proxy.host.address}:${proxy.port}",
);
}
return;
} }
@override @override
@ -703,4 +754,12 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
return info.cachedBalance.total; return info.cachedBalance.total;
} }
} }
// ============== Private ====================================================
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
final Mutex _torConnectingLock = Mutex();
bool _requireMutex = false;
} }