Merge branch 'staging' into dev

This commit is contained in:
sneurlax 2024-02-19 10:44:55 -06:00
commit 80005221b2
3 changed files with 48 additions and 74 deletions

View file

@ -114,7 +114,6 @@ class ElectrumXClient {
required Prefs prefs,
required List<ElectrumXNode> failovers,
Coin? coin,
JsonRPC? client,
this.connectionTimeoutForSpecialCaseJsonRPCClients =
const Duration(seconds: 60),
TorService? torService,
@ -125,7 +124,6 @@ class ElectrumXClient {
_host = host;
_port = port;
_useSSL = useSSL;
_rpcClient = client;
_coin = coin;
final bus = globalEventBusForTesting ?? GlobalEventBus.instance;
@ -155,23 +153,10 @@ class ElectrumXClient {
// case TorStatus.disabled:
// }
// might be ok to just reset/kill the current _jsonRpcClient
// since disconnecting is async and we want to ensure instant change over
// we will keep temp reference to current rpc client to call disconnect
// on before awaiting the disconnection future
final temp = _rpcClient;
// setting to null should force the creation of a new json rpc client
// on the next request sent through this electrumx instance
_rpcClient = null;
_electrumAdapterChannel = null;
_electrumAdapterClient = null;
await temp?.disconnect(
reason: "Tor status changed to \"${event.status}\"",
);
},
);
}
@ -204,58 +189,6 @@ class ElectrumXClient {
return true;
}
void _checkRpcClient() {
// If we're supposed to use Tor...
if (_prefs.useTor) {
// But Tor isn't running...
if (_torService.status != TorConnectionStatus.connected) {
// And the killswitch isn't set...
if (!_prefs.torKillSwitch) {
// Then we'll just proceed and connect to ElectrumX through clearnet at the bottom of this function.
Logging.instance.log(
"Tor preference set but Tor is not enabled, killswitch not set, connecting to ElectrumX through clearnet",
level: LogLevel.Warning,
);
} else {
// ... But if the killswitch is set, then we throw an exception.
throw Exception(
"Tor preference and killswitch set but Tor is not enabled, not connecting to ElectrumX");
// TODO [prio=low]: Try to start Tor.
}
} else {
// Get the proxy info from the TorService.
final proxyInfo = _torService.getProxyInfo();
if (currentFailoverIndex == -1) {
_rpcClient ??= JsonRPC(
host: host,
port: port,
useSSL: useSSL,
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
proxyInfo: proxyInfo,
);
} else {
_rpcClient ??= JsonRPC(
host: failovers![currentFailoverIndex].address,
port: failovers![currentFailoverIndex].port,
useSSL: failovers![currentFailoverIndex].useSSL,
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
proxyInfo: proxyInfo,
);
}
if (_rpcClient!.proxyInfo != proxyInfo) {
_rpcClient!.proxyInfo = proxyInfo;
_rpcClient!.disconnect(
reason: "Tor proxyInfo does not match current info",
);
}
return;
}
}
}
Future<void> checkElectrumAdapter() async {
({InternetAddress host, int port})? proxyInfo;
@ -402,6 +335,12 @@ class ElectrumXClient {
}
currentFailoverIndex = -1;
// If the command is a ping, a good return should always be null.
if (command.contains("ping")) {
return true;
}
return response;
} on WifiOnlyException {
rethrow;
@ -525,13 +464,23 @@ class ElectrumXClient {
/// Returns true if ping succeeded
Future<bool> ping({String? requestID, int retryCount = 1}) async {
try {
final response = await request(
// This doesn't work because electrum_adapter only returns the result:
// (which is always `null`).
// await checkElectrumAdapter();
// final response = await electrumAdapterClient!
// .ping()
// .timeout(const Duration(seconds: 2));
// return (response as Map<String, dynamic>).isNotEmpty;
// Because request() has been updated to use electrum_adapter, and because
// electrum_adapter returns the result of the request, request() has been
// updated to return a bool on a server.ping command as a special case.
return await request(
requestID: requestID,
command: 'server.ping',
requestTimeout: const Duration(seconds: 2),
retries: retryCount,
).timeout(const Duration(seconds: 2)) as Map<String, dynamic>;
return response.isNotEmpty; // TODO [prio=extreme]: Fix this.
).timeout(const Duration(seconds: 2)) as bool;
} catch (e) {
rethrow;
}

View file

@ -7,6 +7,7 @@ import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
import 'package:electrum_adapter/electrum_adapter.dart' as electrum_adapter;
import 'package:electrum_adapter/electrum_adapter.dart';
import 'package:isar/isar.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/electrumx_rpc/cached_electrumx_client.dart';
import 'package:stackwallet/electrumx_rpc/electrumx_chain_height_service.dart';
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
@ -16,6 +17,9 @@ import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2
import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/models/paymint/fee_object_model.dart';
import 'package:stackwallet/models/signing_data.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/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -32,9 +36,6 @@ import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart';
import 'package:stream_channel/stream_channel.dart';
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
import '../../../services/event_bus/events/global/tor_status_changed_event.dart';
mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
late ElectrumXClient electrumXClient;
late StreamChannel electrumAdapterChannel;
@ -46,6 +47,11 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
final Mutex _torConnectingLock = Mutex();
bool _requireMutex = false;
Timer? _aliveTimer;
static const Duration _keepAlive = Duration(minutes: 1);
bool _isConnected = false;
static const _kServerBatchCutoffVersion = [1, 6];
List<int>? _serverVersion;
@ -893,6 +899,16 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
.toList();
final newNode = await getCurrentElectrumXNode();
try {
await electrumXClient.electrumAdapterClient?.close();
} catch (e, s) {
if (e.toString().contains("initialized")) {
// Ignore. This should happen every first time the wallet is opened.
} else {
Logging.instance
.log("Error closing electrumXClient: $e", level: LogLevel.Error);
}
}
electrumXClient = ElectrumXClient.from(
node: newNode,
prefs: prefs,
@ -943,6 +959,15 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
// host: newNode.address, port: newNode.port);
}
/// Update the connection status and call the onConnectionStatusChanged callback if it exists.
void _updateConnectionStatus(bool connectionStatus) {
// TODO [prio=low]: Set onConnectionStatusChanged callback.
// if (_isConnected != connectionStatus && onConnectionStatusChanged != null) {
// onConnectionStatusChanged!(connectionStatus);
// }
_isConnected = connectionStatus;
}
//============================================================================
Future<({List<Address> addresses, int index})> checkGapsBatched(

View file

@ -11,7 +11,7 @@ description: Stack Wallet
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.9.3+204
version: 1.10.0+206
environment:
sdk: ">=3.0.2 <4.0.0"