public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { IEthModule ethModule = (IEthModule)await _rpcModuleProvider.Rent("eth_syncing", false); INetModule netModule = (INetModule)await _rpcModuleProvider.Rent("net_peerCount", false); try { long netPeerCount = (long)netModule.net_peerCount().GetData(); SyncingResult ethSyncing = (SyncingResult)ethModule.eth_syncing().GetData(); if (ethSyncing.IsSyncing == false && netPeerCount > 0) { return(HealthCheckResult.Healthy(description: $"The node is now fully synced with a network, number of peers: {netPeerCount}")); } else if (ethSyncing.IsSyncing == false && netPeerCount == 0) { return(HealthCheckResult.Unhealthy(description: $"The node has 0 peers connected")); } return(HealthCheckResult.Unhealthy(description: $"The node is still syncing, CurrentBlock: {ethSyncing.CurrentBlock}, HighestBlock: {ethSyncing.HighestBlock}, Peers: {netPeerCount}")); } catch (Exception ex) { return(new HealthCheckResult(context.Registration.FailureStatus, exception: ex)); } finally { _rpcModuleProvider.Return("eth_syncing", ethModule); _rpcModuleProvider.Return("net_peerCount", netModule); } }
private async Task <JsonRpcResponse> ExecuteAsync(JsonRpcRequest request, string methodName, MethodInfo method) { var expectedParameters = method.GetParameters(); var providedParameters = request.Params; if (_logger.IsInfo) { _logger.Info($"Executing JSON RPC call {methodName} with params {string.Join(',', providedParameters)}"); } int missingParamsCount = expectedParameters.Length - (providedParameters?.Length ?? 0) + providedParameters?.Count(string.IsNullOrWhiteSpace) ?? 0; if (missingParamsCount != 0) { bool incorrectParametersCount = missingParamsCount != 0; if (missingParamsCount > 0) { incorrectParametersCount = false; for (int i = 0; i < missingParamsCount; i++) { if (!expectedParameters[expectedParameters.Length - missingParamsCount + i].IsOptional) { incorrectParametersCount = true; break; } } } if (incorrectParametersCount) { return(GetErrorResponse(ErrorType.InvalidParams, $"Incorrect parameters count, expected: {expectedParameters.Length}, actual: {expectedParameters.Length - missingParamsCount}", request.Id, methodName)); } } //prepare parameters object[] parameters = null; if (expectedParameters.Length > 0) { parameters = DeserializeParameters(expectedParameters, providedParameters, missingParamsCount); if (parameters == null) { if (_logger.IsError) { _logger.Error($"Incorrect JSON RPC parameters when calling {methodName}: {string.Join(", ", providedParameters)}"); } return(GetErrorResponse(ErrorType.InvalidParams, "Incorrect parameters", request.Id, methodName)); } } //execute method IResultWrapper resultWrapper = null; IModule module = _rpcModuleProvider.Rent(methodName); try { var invocationResult = method.Invoke(module, parameters); if (invocationResult is IResultWrapper wrapper) { resultWrapper = wrapper; } else if (invocationResult is Task task) { await task; resultWrapper = task.GetType().GetProperty("Result").GetValue(task) as IResultWrapper; } } finally { _rpcModuleProvider.Return(methodName, module); } if (resultWrapper is null) { string errorMessage = $"Method {methodName} execution result does not implement IResultWrapper"; if (_logger.IsError) { _logger.Error(errorMessage); } return(GetErrorResponse(ErrorType.InternalError, errorMessage, request.Id, methodName)); } Result result = resultWrapper.GetResult(); if (result == null || result.ResultType == ResultType.Failure) { if (_logger.IsError) { _logger.Error($"Error during method: {methodName} execution: {result?.Error ?? "no result"}"); } return(GetErrorResponse(resultWrapper.GetErrorType(), resultWrapper.GetResult().Error, request.Id, methodName, resultWrapper.GetData())); } return(GetSuccessResponse(resultWrapper.GetData(), request.Id)); }