mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 11:59:30 +00:00
reconnect if needed in _checkRpcClient
with failovers
This commit is contained in:
parent
3ec6e2a008
commit
66354e8ecd
3 changed files with 71 additions and 9 deletions
|
@ -202,7 +202,7 @@ class ElectrumXClient {
|
||||||
// ... But if the killswitch is set, then we throw an exception.
|
// ... But if the killswitch is set, then we throw an exception.
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Tor preference and killswitch set but Tor is not enabled, not connecting to ElectrumX");
|
"Tor preference and killswitch set but Tor is not enabled, not connecting to ElectrumX");
|
||||||
// TODO [prio=low]: Restart Tor. Update Tor package for restart feature.
|
// TODO [prio=low]: Try to start Tor.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Get the proxy info from the TorService.
|
// Get the proxy info from the TorService.
|
||||||
|
|
|
@ -69,9 +69,13 @@ class SubscribableElectrumXClient {
|
||||||
final Mutex _torConnectingLock = Mutex();
|
final Mutex _torConnectingLock = Mutex();
|
||||||
bool _requireMutex = false;
|
bool _requireMutex = false;
|
||||||
|
|
||||||
|
List<ElectrumXNode>? failovers;
|
||||||
|
int currentFailoverIndex = -1;
|
||||||
|
|
||||||
SubscribableElectrumXClient({
|
SubscribableElectrumXClient({
|
||||||
required bool useSSL,
|
required bool useSSL,
|
||||||
required Prefs prefs,
|
required Prefs prefs,
|
||||||
|
required List<ElectrumXNode> failovers,
|
||||||
TorService? torService,
|
TorService? torService,
|
||||||
this.onConnectionStatusChanged,
|
this.onConnectionStatusChanged,
|
||||||
Duration connectionTimeout = const Duration(seconds: 5),
|
Duration connectionTimeout = const Duration(seconds: 5),
|
||||||
|
@ -138,11 +142,13 @@ class SubscribableElectrumXClient {
|
||||||
factory SubscribableElectrumXClient.from({
|
factory SubscribableElectrumXClient.from({
|
||||||
required ElectrumXNode node,
|
required ElectrumXNode node,
|
||||||
required Prefs prefs,
|
required Prefs prefs,
|
||||||
|
required List<ElectrumXNode> failovers,
|
||||||
TorService? torService,
|
TorService? torService,
|
||||||
}) {
|
}) {
|
||||||
return SubscribableElectrumXClient(
|
return SubscribableElectrumXClient(
|
||||||
useSSL: node.useSSL,
|
useSSL: node.useSSL,
|
||||||
prefs: prefs,
|
prefs: prefs,
|
||||||
|
failovers: failovers,
|
||||||
torService: torService ?? TorService.sharedInstance,
|
torService: torService ?? TorService.sharedInstance,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -161,6 +167,57 @@ class SubscribableElectrumXClient {
|
||||||
// return client;
|
// return client;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/// Check if the RPC client is connected and connect if needed.
|
||||||
|
///
|
||||||
|
/// If Tor is enabled but not running, it will attempt to start Tor.
|
||||||
|
Future<void> _checkRpcClient() async {
|
||||||
|
if (_prefs.useTor) {
|
||||||
|
// If we're supposed to use Tor...
|
||||||
|
if (_torService.status != TorConnectionStatus.connected) {
|
||||||
|
// ... but Tor isn't running...
|
||||||
|
if (!_prefs.torKillSwitch) {
|
||||||
|
// ... and the killswitch isn't set, then we'll just return below.
|
||||||
|
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 let's try to start Tor.
|
||||||
|
await _torService.start();
|
||||||
|
// TODO [prio=low]: Attempt to restart Tor if needed. Update Tor package for restart feature.
|
||||||
|
|
||||||
|
// Double-check that Tor is running.
|
||||||
|
if (_torService.status != TorConnectionStatus.connected) {
|
||||||
|
// If Tor still isn't running, then we'll throw an exception.
|
||||||
|
throw Exception("SubscribableElectrumXClient._checkRpcClient: "
|
||||||
|
"Tor preference and killswitch set but Tor not enabled and could not start, not connecting to ElectrumX.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect if needed.
|
||||||
|
if ((!_prefs.useTor && _socket == null) ||
|
||||||
|
(_prefs.useTor && _socksSocket == null)) {
|
||||||
|
if (currentFailoverIndex == -1) {
|
||||||
|
// Check if we have cached node information
|
||||||
|
if (_host == null && _port == null) {
|
||||||
|
throw Exception("SubscribableElectrumXClient._checkRpcClient: "
|
||||||
|
"No host or port provided and no cached node information.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to the server.
|
||||||
|
await connect(host: _host!, port: _port!);
|
||||||
|
} else {
|
||||||
|
// Attempt to connect to the next failover server.
|
||||||
|
await connect(
|
||||||
|
host: failovers![currentFailoverIndex].address,
|
||||||
|
port: failovers![currentFailoverIndex].port,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Connect to the server.
|
/// Connect to the server.
|
||||||
///
|
///
|
||||||
/// If Tor is enabled, it will attempt to connect through Tor.
|
/// If Tor is enabled, it will attempt to connect through Tor.
|
||||||
|
@ -179,8 +236,9 @@ class SubscribableElectrumXClient {
|
||||||
|
|
||||||
// If we're connecting to Tor, wait.
|
// If we're connecting to Tor, wait.
|
||||||
if (_requireMutex) {
|
if (_requireMutex) {
|
||||||
// Just use a dummy function that waits for the lock to be released.
|
await _torConnectingLock.protect(() async => await _checkRpcClient());
|
||||||
await _torConnectingLock.protect(() async {});
|
} else {
|
||||||
|
await _checkRpcClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Prefs.instance.useTor) {
|
if (!Prefs.instance.useTor) {
|
||||||
|
@ -509,8 +567,9 @@ class SubscribableElectrumXClient {
|
||||||
}) async {
|
}) async {
|
||||||
// If we're connecting to Tor, wait.
|
// If we're connecting to Tor, wait.
|
||||||
if (_requireMutex) {
|
if (_requireMutex) {
|
||||||
// Just use a dummy function that waits for the lock to be released.
|
await _torConnectingLock.protect(() async => await _checkRpcClient());
|
||||||
await _torConnectingLock.protect(() async {});
|
} else {
|
||||||
|
await _checkRpcClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check socket is connected.
|
// Check socket is connected.
|
||||||
|
@ -574,8 +633,9 @@ class SubscribableElectrumXClient {
|
||||||
}) async {
|
}) async {
|
||||||
// If we're connecting to Tor, wait.
|
// If we're connecting to Tor, wait.
|
||||||
if (_requireMutex) {
|
if (_requireMutex) {
|
||||||
// Just use a dummy function that waits for the lock to be released.
|
await _torConnectingLock.protect(() async => await _checkRpcClient());
|
||||||
await _torConnectingLock.protect(() async {});
|
} else {
|
||||||
|
await _checkRpcClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check socket is connected.
|
// Check socket is connected.
|
||||||
|
@ -728,8 +788,9 @@ class SubscribableElectrumXClient {
|
||||||
Future<bool> ping() async {
|
Future<bool> ping() async {
|
||||||
// If we're connecting to Tor, wait.
|
// If we're connecting to Tor, wait.
|
||||||
if (_requireMutex) {
|
if (_requireMutex) {
|
||||||
// Just use a dummy function that waits for the lock to be released.
|
await _torConnectingLock.protect(() async => await _checkRpcClient());
|
||||||
await _torConnectingLock.protect(() async {});
|
} else {
|
||||||
|
await _checkRpcClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to the socket.
|
// Write to the socket.
|
||||||
|
|
|
@ -948,6 +948,7 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
|
||||||
subscribableElectrumXClient = SubscribableElectrumXClient.from(
|
subscribableElectrumXClient = SubscribableElectrumXClient.from(
|
||||||
node: newNode,
|
node: newNode,
|
||||||
prefs: prefs,
|
prefs: prefs,
|
||||||
|
failovers: failovers,
|
||||||
);
|
);
|
||||||
await subscribableElectrumXClient.connect(
|
await subscribableElectrumXClient.connect(
|
||||||
host: newNode.address, port: newNode.port);
|
host: newNode.address, port: newNode.port);
|
||||||
|
|
Loading…
Reference in a new issue