mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 11:59:30 +00:00
Merge pull request #357 from cypherstack/epicbox-failover
Epicbox failover - When epicbox server is down default to EU server
This commit is contained in:
commit
6ac856d31b
4 changed files with 606 additions and 326 deletions
|
@ -6,7 +6,6 @@ import 'dart:isolate';
|
|||
import 'package:decimal/decimal.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_libepiccash/epic_cash.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mutex/mutex.dart';
|
||||
import 'package:stack_wallet_backup/generate_password.dart';
|
||||
|
@ -37,6 +36,7 @@ import 'package:stackwallet/utilities/prefs.dart';
|
|||
import 'package:stackwallet/utilities/stack_file_system.dart';
|
||||
import 'package:stackwallet/utilities/test_epic_box_connection.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:websocket_universal/websocket_universal.dart';
|
||||
|
||||
const int MINIMUM_CONFIRMATIONS = 10;
|
||||
|
||||
|
@ -462,6 +462,18 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
dynamic message;
|
||||
|
||||
String receiverAddress = txData['addresss'] as String;
|
||||
|
||||
if (!receiverAddress.startsWith("http://") ||
|
||||
!receiverAddress.startsWith("https://")) {
|
||||
final decoded = json.decode(epicboxConfig);
|
||||
bool isEpicboxConnected = await testEpicboxServer(
|
||||
decoded["epicbox_domain"] as String,
|
||||
decoded["epicbox_port"] as int);
|
||||
if (!isEpicboxConnected) {
|
||||
throw Exception("Failed to send TX : Unable to reach epicbox server");
|
||||
}
|
||||
}
|
||||
|
||||
await m.protect(() async {
|
||||
if (receiverAddress.startsWith("http://") ||
|
||||
receiverAddress.startsWith("https://")) {
|
||||
|
@ -980,22 +992,75 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
return stringConfig;
|
||||
}
|
||||
|
||||
Future<bool> testEpicboxServer(String host, int port) async {
|
||||
final websocketConnectionUri = 'wss://$host:$port';
|
||||
const connectionOptions = SocketConnectionOptions(
|
||||
pingIntervalMs: 3000,
|
||||
timeoutConnectionMs: 4000,
|
||||
|
||||
/// see ping/pong messages in [logEventStream] stream
|
||||
skipPingMessages: true,
|
||||
|
||||
/// Set this attribute to `true` if do not need any ping/pong
|
||||
/// messages and ping measurement. Default is `false`
|
||||
pingRestrictionForce: false,
|
||||
);
|
||||
|
||||
final IMessageProcessor<String, String> textSocketProcessor =
|
||||
SocketSimpleTextProcessor();
|
||||
final textSocketHandler = IWebSocketHandler<String, String>.createClient(
|
||||
websocketConnectionUri,
|
||||
textSocketProcessor,
|
||||
connectionOptions: connectionOptions,
|
||||
);
|
||||
|
||||
// Listening to server responses:
|
||||
bool isConnected = true;
|
||||
textSocketHandler.incomingMessagesStream.listen((inMsg) {
|
||||
Logging.instance.log(
|
||||
'> webSocket got text message from server: "$inMsg" '
|
||||
'[ping: ${textSocketHandler.pingDelayMs}]',
|
||||
level: LogLevel.Info);
|
||||
});
|
||||
|
||||
// Connecting to server:
|
||||
final isTextSocketConnected = await textSocketHandler.connect();
|
||||
if (!isTextSocketConnected) {
|
||||
// ignore: avoid_print
|
||||
Logging.instance.log(
|
||||
'Connection to [$websocketConnectionUri] failed for some reason!',
|
||||
level: LogLevel.Error);
|
||||
isConnected = false;
|
||||
}
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
Future<String> getEpicBoxConfig() async {
|
||||
final storedConfig =
|
||||
String? storedConfig =
|
||||
await _secureStore.read(key: '${_walletId}_epicboxConfig');
|
||||
if (storedConfig != null) {
|
||||
final decoded = json.decode(storedConfig!);
|
||||
if (storedConfig == null) {
|
||||
return json.encode(DefaultNodes.defaultEpicBoxConfig);
|
||||
} else {
|
||||
dynamic decoded = json.decode(storedConfig!);
|
||||
final domain = decoded["domain"] ?? "empty";
|
||||
if (domain != "empty") {
|
||||
//If we have the old invalid config - update
|
||||
await _secureStore.write(
|
||||
key: '${_walletId}_epicboxConfig',
|
||||
value: DefaultNodes.defaultEpicBoxConfig);
|
||||
//If we have the old invalid config, use the new default one
|
||||
// new storage format stores domain under "epicbox_domain", old storage format used "domain"
|
||||
storedConfig = DefaultNodes.defaultEpicBoxConfig;
|
||||
decoded = json.decode(storedConfig);
|
||||
}
|
||||
return await _secureStore.read(key: '${_walletId}_epicboxConfig') ??
|
||||
DefaultNodes.defaultEpicBoxConfig;
|
||||
//Check Epicbox is up before returning it
|
||||
bool isEpicboxConnected = await testEpicboxServer(
|
||||
decoded["epicbox_domain"] as String, decoded["epicbox_port"] as int);
|
||||
|
||||
if (!isEpicboxConnected) {
|
||||
//Default Epicbox is not connected, Defaulting to Europe
|
||||
storedConfig = json.encode(DefaultNodes.epicBoxConfigEUR);
|
||||
// TODO test this connection before returning it, iterating through the list of default Epic Box servers
|
||||
}
|
||||
|
||||
return storedConfig;
|
||||
}
|
||||
return DefaultNodes.defaultEpicBoxConfig;
|
||||
}
|
||||
|
||||
Future<String> getRealConfig() async {
|
||||
|
|
|
@ -262,4 +262,11 @@ abstract class DefaultNodes {
|
|||
"epicbox_protocol_unsecure": false,
|
||||
"epicbox_address_index": 0,
|
||||
});
|
||||
|
||||
static final String epicBoxConfigEUR = jsonEncode({
|
||||
"epicbox_domain": "epicbox.fastepic.eu",
|
||||
"epicbox_port": 443,
|
||||
"epicbox_protocol_unsecure": false,
|
||||
"epicbox_address_index": 0,
|
||||
});
|
||||
}
|
||||
|
|
837
pubspec.lock
837
pubspec.lock
File diff suppressed because it is too large
Load diff
|
@ -21,6 +21,7 @@ dependencies:
|
|||
sdk: flutter
|
||||
ffi: ^2.0.1
|
||||
mutex: ^3.0.0
|
||||
websocket_universal: ^0.5.1
|
||||
|
||||
lelantus:
|
||||
path: ./crypto_plugins/flutter_liblelantus
|
||||
|
|
Loading…
Reference in a new issue