add 10s timeout

This commit is contained in:
sneurlax 2024-02-14 11:19:55 -06:00
parent fc0d9639b8
commit 98c095b568
2 changed files with 36 additions and 2 deletions
lib
electrumx_rpc
wallets/wallet/wallet_mixin_interfaces

View file

@ -4,11 +4,15 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
/// Store chain height subscriptions for each coin.
abstract class ElectrumxChainHeightService {
static Map<Coin, StreamSubscription<dynamic>?> subscriptions = {};
// Used to hold chain height subscriptions for each coin as in:
// ElectrumxChainHeightService.subscriptions[cryptoCurrency.coin] = sub;
static Map<Coin, StreamSubscription<dynamic>?> subscriptions = {};
static Map<Coin, Completer<int>?> completers = {};
// Used to hold chain height completers for each coin as in:
// ElectrumxChainHeightService.completers[cryptoCurrency.coin] = completer;
static Map<Coin, Completer<int>?> completers = {};
// Used to hold the time each coin started waiting for chain height as in:
// ElectrumxChainHeightService.timeStarted[cryptoCurrency.coin] = time;
static Map<Coin, DateTime?> timeStarted = {};
}

View file

@ -825,6 +825,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
}
Future<void> _manageChainHeightSubscription() async {
// Set the timeout period for the chain height subscription.
const timeout = Duration(seconds: 10);
if (ElectrumxChainHeightService.subscriptions[cryptoCurrency.coin] ==
null) {
// No subscription exists for this coin yet, so create one.
@ -840,6 +843,11 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
final subscription =
subscribableElectrumXClient.subscribeToBlockHeaders();
// Set the time the subscription was created.
final subscriptionCreationTime = DateTime.now();
ElectrumxChainHeightService.timeStarted[cryptoCurrency.coin] =
subscriptionCreationTime;
// Set stream subscription.
ElectrumxChainHeightService.subscriptions[cryptoCurrency.coin] =
subscription.responseStream.asBroadcastStream().listen((event) {
@ -902,7 +910,29 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
.cancel();
ElectrumxChainHeightService.subscriptions[cryptoCurrency.coin] = null;
// Retry/recurse.
return await _manageChainHeightSubscription();
}
}
// Check if the subscription has been running for too long.
if (ElectrumxChainHeightService.timeStarted[cryptoCurrency.coin] != null) {
final timeRunning = DateTime.now().difference(
ElectrumxChainHeightService.timeStarted[cryptoCurrency.coin]!);
// Cancel and retry if we've been waiting too long.
if (timeRunning > timeout) {
// Clear this coin's subscription.
await ElectrumxChainHeightService.subscriptions[cryptoCurrency.coin]!
.cancel();
ElectrumxChainHeightService.subscriptions[cryptoCurrency.coin] = null;
// Clear this coin's completer.
ElectrumxChainHeightService.completers[cryptoCurrency.coin]
?.completeError(
Exception(
"Subscription to block headers has been running for too long",
),
);
ElectrumxChainHeightService.completers[cryptoCurrency.coin] = null;
// Retry/recurse.