diff --git a/lib/electrumx_rpc/cached_electrumx_client.dart b/lib/electrumx_rpc/cached_electrumx_client.dart index be9f9a47c..b64e2ec7d 100644 --- a/lib/electrumx_rpc/cached_electrumx_client.dart +++ b/lib/electrumx_rpc/cached_electrumx_client.dart @@ -22,22 +22,40 @@ import 'package:string_validator/string_validator.dart'; class CachedElectrumXClient { final ElectrumXClient electrumXClient; - final ElectrumClient electrumAdapterClient; + ElectrumClient electrumAdapterClient; + final Future Function() electrumAdapterUpdateCallback; static const minCacheConfirms = 30; - const CachedElectrumXClient({ + CachedElectrumXClient({ required this.electrumXClient, required this.electrumAdapterClient, + required this.electrumAdapterUpdateCallback, }); factory CachedElectrumXClient.from({ required ElectrumXClient electrumXClient, required ElectrumClient electrumAdapterClient, + required Future Function() electrumAdapterUpdateCallback, }) => CachedElectrumXClient( - electrumXClient: electrumXClient, - electrumAdapterClient: electrumAdapterClient); + electrumXClient: electrumXClient, + electrumAdapterClient: electrumAdapterClient, + electrumAdapterUpdateCallback: electrumAdapterUpdateCallback, + ); + + /// If the client is closed, use the callback to update it. + _checkElectrumAdapterClient() async { + if (electrumAdapterClient.peer.isClosed) { + Logging.instance.log( + "ElectrumAdapterClient is closed, reopening it...", + level: LogLevel.Info, + ); + ElectrumClient? _electrumAdapterClient = + await electrumAdapterUpdateCallback.call(); + electrumAdapterClient = _electrumAdapterClient; + } + } Future> getAnonymitySet({ required String groupId, @@ -62,6 +80,8 @@ class CachedElectrumXClient { set = Map.from(cachedSet); } + await _checkElectrumAdapterClient(); + final newSet = await (electrumAdapterClient as FiroElectrumClient) .getLelantusAnonymitySet( groupId: groupId, @@ -137,6 +157,8 @@ class CachedElectrumXClient { set = Map.from(cachedSet); } + await _checkElectrumAdapterClient(); + final newSet = await (electrumAdapterClient as FiroElectrumClient) .getSparkAnonymitySet( coinGroupId: groupId, @@ -196,6 +218,8 @@ class CachedElectrumXClient { final cachedTx = box.get(txHash) as Map?; if (cachedTx == null) { + await _checkElectrumAdapterClient(); + final Map result = await electrumAdapterClient.getTransaction(txHash); @@ -239,6 +263,8 @@ class CachedElectrumXClient { cachedSerials.length - 100, // 100 being some arbitrary buffer ); + await _checkElectrumAdapterClient(); + final serials = await (electrumAdapterClient as FiroElectrumClient) .getLelantusUsedCoinSerials( startNumber: startNumber, @@ -288,6 +314,8 @@ class CachedElectrumXClient { cachedTags.length - 100, // 100 being some arbitrary buffer ); + await _checkElectrumAdapterClient(); + final tags = await (electrumAdapterClient as FiroElectrumClient).getUsedCoinsTags( startNumber: startNumber, diff --git a/lib/electrumx_rpc/electrumx_client.dart b/lib/electrumx_rpc/electrumx_client.dart index ef9586a30..db135427c 100644 --- a/lib/electrumx_rpc/electrumx_client.dart +++ b/lib/electrumx_rpc/electrumx_client.dart @@ -290,6 +290,13 @@ class ElectrumXClient { // ); // } + // If the current ElectrumAdapterClient is closed, create a new one. + if (_electrumAdapterClient != null && + _electrumAdapterClient!.peer.isClosed) { + _electrumAdapterChannel = null; + _electrumAdapterClient = null; + } + if (currentFailoverIndex == -1) { _electrumAdapterChannel ??= await electrum_adapter.connect( host, diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart index bbbec624d..42292184e 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart @@ -996,6 +996,7 @@ mixin ElectrumXInterface on Bip39HDWallet { electrumXCachedClient = CachedElectrumXClient.from( electrumXClient: electrumXClient, electrumAdapterClient: electrumAdapterClient, + electrumAdapterUpdateCallback: updateClient, ); subscribableElectrumXClient = SubscribableElectrumXClient.from( node: newNode, @@ -1307,6 +1308,13 @@ mixin ElectrumXInterface on Bip39HDWallet { await updateElectrumX(newNode: node); } + Future updateClient() async { + Logging.instance.log("Updating electrum node and ElectrumAdapterClient.", + level: LogLevel.Info); + await updateNode(); + return electrumAdapterClient; + } + FeeObject? _cachedFees; @override