mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
fix request timeout bug
This commit is contained in:
parent
085895fb4d
commit
7765ed2465
2 changed files with 54 additions and 34 deletions
|
@ -69,13 +69,18 @@ class ElectrumX {
|
|||
List<ElectrumXNode>? failovers;
|
||||
int currentFailoverIndex = -1;
|
||||
|
||||
ElectrumX(
|
||||
{required String host,
|
||||
required int port,
|
||||
required bool useSSL,
|
||||
required Prefs prefs,
|
||||
required List<ElectrumXNode> failovers,
|
||||
JsonRPC? client}) {
|
||||
final Duration connectionTimeoutForSpecialCaseJsonRPCClients;
|
||||
|
||||
ElectrumX({
|
||||
required String host,
|
||||
required int port,
|
||||
required bool useSSL,
|
||||
required Prefs prefs,
|
||||
required List<ElectrumXNode> failovers,
|
||||
JsonRPC? client,
|
||||
this.connectionTimeoutForSpecialCaseJsonRPCClients =
|
||||
const Duration(seconds: 60),
|
||||
}) {
|
||||
_prefs = prefs;
|
||||
_host = host;
|
||||
_port = port;
|
||||
|
@ -108,9 +113,9 @@ class ElectrumX {
|
|||
Future<dynamic> request({
|
||||
required String command,
|
||||
List<dynamic> args = const [],
|
||||
Duration connectionTimeout = const Duration(seconds: 60),
|
||||
String? requestID,
|
||||
int retries = 2,
|
||||
Duration requestTimeout = const Duration(seconds: 60),
|
||||
}) async {
|
||||
if (!(await _allow())) {
|
||||
throw WifiOnlyException();
|
||||
|
@ -121,26 +126,31 @@ class ElectrumX {
|
|||
host: host,
|
||||
port: port,
|
||||
useSSL: useSSL,
|
||||
connectionTimeout: connectionTimeout,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
);
|
||||
} else {
|
||||
_rpcClient = JsonRPC(
|
||||
host: failovers![currentFailoverIndex].address,
|
||||
port: failovers![currentFailoverIndex].port,
|
||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
||||
connectionTimeout: connectionTimeout,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
final requestId = requestID ?? const Uuid().v1();
|
||||
final jsonArgs = json.encode(args);
|
||||
final jsonRequestString =
|
||||
'{"jsonrpc": "2.0", "id": "$requestId","method": "$command","params": $jsonArgs}';
|
||||
final jsonRequestString = '{"jsonrpc": "2.0", '
|
||||
'"id": "$requestId",'
|
||||
'"method": "$command",'
|
||||
'"params": $jsonArgs}';
|
||||
|
||||
// Logging.instance.log("ElectrumX jsonRequestString: $jsonRequestString");
|
||||
|
||||
final response = await _rpcClient!.request(jsonRequestString);
|
||||
final response = await _rpcClient!.request(
|
||||
jsonRequestString,
|
||||
requestTimeout,
|
||||
);
|
||||
|
||||
if (response.exception != null) {
|
||||
throw response.exception!;
|
||||
|
@ -174,7 +184,7 @@ class ElectrumX {
|
|||
return request(
|
||||
command: command,
|
||||
args: args,
|
||||
connectionTimeout: connectionTimeout,
|
||||
requestTimeout: requestTimeout,
|
||||
requestID: requestID,
|
||||
retries: retries - 1,
|
||||
);
|
||||
|
@ -187,7 +197,7 @@ class ElectrumX {
|
|||
return request(
|
||||
command: command,
|
||||
args: args,
|
||||
connectionTimeout: connectionTimeout,
|
||||
requestTimeout: requestTimeout,
|
||||
requestID: requestID,
|
||||
);
|
||||
} else {
|
||||
|
@ -204,7 +214,7 @@ class ElectrumX {
|
|||
Future<List<Map<String, dynamic>>> batchRequest({
|
||||
required String command,
|
||||
required Map<String, List<dynamic>> args,
|
||||
Duration connectionTimeout = const Duration(seconds: 60),
|
||||
Duration requestTimeout = const Duration(seconds: 60),
|
||||
int retries = 2,
|
||||
}) async {
|
||||
if (!(await _allow())) {
|
||||
|
@ -216,14 +226,14 @@ class ElectrumX {
|
|||
host: host,
|
||||
port: port,
|
||||
useSSL: useSSL,
|
||||
connectionTimeout: connectionTimeout,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
);
|
||||
} else {
|
||||
_rpcClient = JsonRPC(
|
||||
host: failovers![currentFailoverIndex].address,
|
||||
port: failovers![currentFailoverIndex].port,
|
||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
||||
connectionTimeout: connectionTimeout,
|
||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -246,7 +256,8 @@ class ElectrumX {
|
|||
// Logging.instance.log("batch request: $request");
|
||||
|
||||
// send batch request
|
||||
final jsonRpcResponse = (await _rpcClient!.request(request));
|
||||
final jsonRpcResponse =
|
||||
(await _rpcClient!.request(request, requestTimeout));
|
||||
|
||||
if (jsonRpcResponse.exception != null) {
|
||||
throw jsonRpcResponse.exception!;
|
||||
|
@ -281,7 +292,7 @@ class ElectrumX {
|
|||
return batchRequest(
|
||||
command: command,
|
||||
args: args,
|
||||
connectionTimeout: connectionTimeout,
|
||||
requestTimeout: requestTimeout,
|
||||
retries: retries - 1,
|
||||
);
|
||||
} else {
|
||||
|
@ -293,7 +304,7 @@ class ElectrumX {
|
|||
return batchRequest(
|
||||
command: command,
|
||||
args: args,
|
||||
connectionTimeout: connectionTimeout,
|
||||
requestTimeout: requestTimeout,
|
||||
);
|
||||
} else {
|
||||
currentFailoverIndex = -1;
|
||||
|
@ -310,7 +321,7 @@ class ElectrumX {
|
|||
final response = await request(
|
||||
requestID: requestID,
|
||||
command: 'server.ping',
|
||||
connectionTimeout: const Duration(seconds: 2),
|
||||
requestTimeout: const Duration(seconds: 2),
|
||||
retries: retryCount,
|
||||
).timeout(const Duration(seconds: 2)) as Map<String, dynamic>;
|
||||
return response.keys.contains("result") && response["result"] == null;
|
||||
|
@ -442,7 +453,7 @@ class ElectrumX {
|
|||
final response = await request(
|
||||
requestID: requestID,
|
||||
command: 'blockchain.scripthash.get_history',
|
||||
connectionTimeout: const Duration(minutes: 5),
|
||||
requestTimeout: const Duration(minutes: 5),
|
||||
args: [
|
||||
scripthash,
|
||||
],
|
||||
|
@ -666,11 +677,13 @@ class ElectrumX {
|
|||
}) async {
|
||||
try {
|
||||
final response = await request(
|
||||
requestID: requestID,
|
||||
command: 'lelantus.getusedcoinserials',
|
||||
args: [
|
||||
"$startNumber",
|
||||
]);
|
||||
requestID: requestID,
|
||||
command: 'lelantus.getusedcoinserials',
|
||||
args: [
|
||||
"$startNumber",
|
||||
],
|
||||
requestTimeout: const Duration(minutes: 2),
|
||||
);
|
||||
return Map<String, dynamic>.from(response["result"] as Map);
|
||||
} catch (e) {
|
||||
Logging.instance.log(e, level: LogLevel.Error);
|
||||
|
|
|
@ -79,7 +79,6 @@ class JsonRPC {
|
|||
|
||||
// TODO different timeout length?
|
||||
req.initiateTimeout(
|
||||
Duration(seconds: connectionTimeout.inSeconds ~/ 2),
|
||||
onTimedOut: () {
|
||||
_requestQueue.remove(req);
|
||||
},
|
||||
|
@ -88,7 +87,10 @@ class JsonRPC {
|
|||
});
|
||||
}
|
||||
|
||||
Future<JsonRPCResponse> request(String jsonRpcRequest) async {
|
||||
Future<JsonRPCResponse> request(
|
||||
String jsonRpcRequest,
|
||||
Duration requestTimeout,
|
||||
) async {
|
||||
await _requestMutex.protect(() async {
|
||||
if (_socket == null) {
|
||||
Logging.instance.log(
|
||||
|
@ -101,6 +103,7 @@ class JsonRPC {
|
|||
|
||||
final req = _JsonRPCRequest(
|
||||
jsonRequest: jsonRpcRequest,
|
||||
requestTimeout: requestTimeout,
|
||||
completer: Completer<JsonRPCResponse>(),
|
||||
);
|
||||
|
||||
|
@ -243,9 +246,14 @@ class _JsonRPCRequest {
|
|||
|
||||
final String jsonRequest;
|
||||
final Completer<JsonRPCResponse> completer;
|
||||
final Duration requestTimeout;
|
||||
final List<int> _responseData = [];
|
||||
|
||||
_JsonRPCRequest({required this.jsonRequest, required this.completer});
|
||||
_JsonRPCRequest({
|
||||
required this.jsonRequest,
|
||||
required this.completer,
|
||||
required this.requestTimeout,
|
||||
});
|
||||
|
||||
void appendDataAndCheckIfComplete(List<int> data) {
|
||||
_responseData.addAll(data);
|
||||
|
@ -263,11 +271,10 @@ class _JsonRPCRequest {
|
|||
}
|
||||
}
|
||||
|
||||
void initiateTimeout(
|
||||
Duration timeout, {
|
||||
void initiateTimeout({
|
||||
VoidCallback? onTimedOut,
|
||||
}) {
|
||||
Future<void>.delayed(timeout).then((_) {
|
||||
Future<void>.delayed(requestTimeout).then((_) {
|
||||
if (!isComplete) {
|
||||
try {
|
||||
throw Exception("_JsonRPCRequest timed out: $jsonRequest");
|
||||
|
|
Loading…
Reference in a new issue