Esempio n. 1
0
        public MainController(IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService)
        {
            _jsonRpcProcessor = jsonRpcProcessor;

            if (_serializer == null)
            {
                lock (_lockObject)
                {
                    if (_serializer == null)
                    {
                        _jsonSettings = new JsonSerializerSettings
                        {
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        };

                        foreach (var converter in jsonRpcService.Converters)
                        {
                            _jsonSettings.Converters.Add(converter);
                        }

                        _serializer = JsonSerializer.Create(_jsonSettings);
                    }
                }
            }
        }
Esempio n. 2
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor,
                              IJsonRpcService jsonRpcService)
        {
            _jsonSerializer = new EthereumJsonSerializer();
            foreach (JsonConverter converter in jsonRpcService.Converters)
            {
                _jsonSerializer.RegisterConverter(converter);
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("Cors");

            var initConfig = app.ApplicationServices.GetService <IConfigProvider>().GetConfig <IInitConfig>();

            if (initConfig.WebSocketsEnabled)
            {
                app.UseWebSockets();
                app.UseWhen(ctx =>
                            ctx.WebSockets.IsWebSocketRequest && ctx.Request.Path.HasValue &&
                            ctx.Request.Path.Value.StartsWith("/ws"), builder => builder.UseWebSocketsModules());
            }

            app.Use(async(ctx, next) =>
            {
                if (ctx.Request.Method == "GET")
                {
                    await ctx.Response.WriteAsync("Nethermind JSON RPC");
                    return;
                }

                if (ctx.Request.Method != "POST")
                {
                    return;
                }

                using var reader = new StreamReader(ctx.Request.Body, Encoding.UTF8);
                var request      = await reader.ReadToEndAsync();
                var result       = await jsonRpcProcessor.ProcessAsync(request);

                if (result.IsCollection)
                {
                    _jsonSerializer.Serialize(ctx.Response.Body, result.Responses);
                }
                else
                {
                    _jsonSerializer.Serialize(ctx.Response.Body, result.Response);
                }

                await ctx.Response.CompleteAsync();
            });
        }
Esempio n. 3
0
 public JsonRpcRunner(IConfigProvider configurationProvider, IRpcModuleProvider moduleProvider,
                      ILogManager logManager, IJsonRpcProcessor jsonRpcProcessor, IWebSocketsManager webSocketsManager)
 {
     _jsonRpcConfig         = configurationProvider.GetConfig <IJsonRpcConfig>();
     _configurationProvider = configurationProvider;
     _moduleProvider        = moduleProvider ?? throw new ArgumentNullException(nameof(moduleProvider));
     _logManager            = logManager;
     _jsonRpcProcessor      = jsonRpcProcessor;
     _webSocketsManager     = webSocketsManager;
     _logger = logManager.GetClassLogger();
 }
Esempio n. 4
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService)
        {
            _jsonSerializer = CreateJsonSerializer();

            foreach (JsonConverter converter in jsonRpcService.Converters)
            {
                _jsonSerializer.RegisterConverter(converter);
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("Cors");

            IConfigProvider configProvider = app.ApplicationServices.GetService <IConfigProvider>();
            IInitConfig     initConfig     = configProvider.GetConfig <IInitConfig>();
            IJsonRpcConfig  jsonRpcConfig  = configProvider.GetConfig <IJsonRpcConfig>();

            if (initConfig.WebSocketsEnabled)
            {
                app.UseWebSockets();
                app.UseWhen(ctx => ctx.WebSockets.IsWebSocketRequest &&
                            ctx.Connection.LocalPort == jsonRpcConfig.WebSocketsPort,
                            builder => builder.UseWebSocketsModules());
            }

            app.Use(async(ctx, next) =>
            {
                if (ctx.Request.Method == "GET")
                {
                    await ctx.Response.WriteAsync("Nethermind JSON RPC");
                }
                else if (ctx.Connection.LocalPort == jsonRpcConfig.Port && ctx.Request.Method == "POST")
                {
                    using StreamReader reader = new StreamReader(ctx.Request.Body, Encoding.UTF8);
                    string request            = await reader.ReadToEndAsync();
                    JsonRpcResult result      = await jsonRpcProcessor.ProcessAsync(request);

                    if (result.IsCollection)
                    {
                        _jsonSerializer.Serialize(ctx.Response.Body, result.Responses);
                    }
                    else
                    {
                        _jsonSerializer.Serialize(ctx.Response.Body, result.Response);
                    }

                    await ctx.Response.CompleteAsync();
                }
            });
        }
 public MainController(IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService)
 {
     _jsonRpcProcessor = jsonRpcProcessor;
     _jsonSettings     = new JsonSerializerSettings
     {
         ContractResolver = new CamelCasePropertyNamesContractResolver()
     };
     foreach (var converter in jsonRpcService.Converters)
     {
         _jsonSettings.Converters.Add(converter);
     }
 }
Esempio n. 6
0
 public JsonRpcRunner(
     IJsonRpcProcessor jsonRpcProcessor,
     IWebSocketsManager webSocketsManager,
     IConfigProvider configurationProvider,
     ILogManager logManager,
     INethermindApi api)
 {
     _jsonRpcConfig         = configurationProvider.GetConfig <IJsonRpcConfig>();
     _initConfig            = configurationProvider.GetConfig <IInitConfig>();
     _configurationProvider = configurationProvider;
     _logManager            = logManager;
     _jsonRpcProcessor      = jsonRpcProcessor;
     _webSocketsManager     = webSocketsManager;
     _logger = logManager.GetClassLogger();
     _api    = api;
 }
Esempio n. 7
0
 public JsonRpcSocketsClient(
     string clientName,
     ISocketHandler handler,
     RpcEndpoint endpointType,
     IJsonRpcProcessor jsonRpcProcessor,
     IJsonRpcService jsonRpcService,
     IJsonRpcLocalStats jsonRpcLocalStats,
     IJsonSerializer jsonSerializer,
     JsonRpcUrl?url = null)
     : base(clientName, handler, jsonSerializer)
 {
     _jsonRpcProcessor  = jsonRpcProcessor;
     _jsonRpcService    = jsonRpcService;
     _jsonRpcLocalStats = jsonRpcLocalStats;
     _jsonRpcContext    = new JsonRpcContext(endpointType, this, url);
 }
Esempio n. 8
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService, IJsonRpcLocalStats jsonRpcLocalStats)
        {
            void SerializeTimeoutException(IJsonRpcService service, Stream resultStream)
            {
                JsonRpcErrorResponse?error = service.GetErrorResponse(ErrorCodes.Timeout, "Request was canceled due to enabled timeout.");

                _jsonSerializer.Serialize(resultStream, error);
            }

            _jsonSerializer = CreateJsonSerializer();

            foreach (JsonConverter converter in jsonRpcService.Converters)
            {
                _jsonSerializer.RegisterConverter(converter);
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("Cors");

            IConfigProvider configProvider = app.ApplicationServices.GetService <IConfigProvider>();
            IInitConfig     initConfig     = configProvider.GetConfig <IInitConfig>();
            IJsonRpcConfig  jsonRpcConfig  = configProvider.GetConfig <IJsonRpcConfig>();

            if (initConfig.WebSocketsEnabled)
            {
                app.UseWebSockets();
                app.UseWhen(ctx => ctx.WebSockets.IsWebSocketRequest &&
                            ctx.Connection.LocalPort == jsonRpcConfig.WebSocketsPort,
                            builder => builder.UseWebSocketsModules());
            }

            app.Use(async(ctx, next) =>
            {
                if (ctx.Request.Method == "GET")
                {
                    await ctx.Response.WriteAsync("Nethermind JSON RPC");
                }
                else if (ctx.Connection.LocalPort == jsonRpcConfig.Port && ctx.Request.Method == "POST")
                {
                    Stopwatch stopwatch        = Stopwatch.StartNew();
                    using StreamReader reader  = new StreamReader(ctx.Request.Body, Encoding.UTF8);
                    string request             = await reader.ReadToEndAsync();
                    using JsonRpcResult result = await jsonRpcProcessor.ProcessAsync(request);

                    ctx.Response.ContentType = "application/json";

                    Stream resultStream = jsonRpcConfig.BufferResponses ? new MemoryStream() : ctx.Response.Body;

                    try
                    {
                        if (result.IsCollection)
                        {
                            _jsonSerializer.Serialize(resultStream, result.Responses);
                        }
                        else
                        {
                            _jsonSerializer.Serialize(resultStream, result.Response);
                        }

                        if (jsonRpcConfig.BufferResponses)
                        {
                            ctx.Response.ContentLength = resultStream.Length;
                            resultStream.Seek(0, SeekOrigin.Begin);
                            await resultStream.CopyToAsync(ctx.Response.Body);
                        }
                    }
                    catch (Exception e) when(e.InnerException is OperationCanceledException)
                    {
                        SerializeTimeoutException(jsonRpcService, resultStream);
                    }
                    catch (OperationCanceledException)
                    {
                        SerializeTimeoutException(jsonRpcService, resultStream);
                    }
                    finally
                    {
                        await ctx.Response.CompleteAsync();

                        if (jsonRpcConfig.BufferResponses)
                        {
                            await resultStream.DisposeAsync();
                        }
                    }

                    if (result.IsCollection)
                    {
                        jsonRpcLocalStats.ReportCalls(result.Reports);
                        jsonRpcLocalStats.ReportCall(new RpcReport("# collection serialization #", stopwatch.ElapsedMicroseconds(), true));
                    }
                    else
                    {
                        jsonRpcLocalStats.ReportCall(result.Report, stopwatch.ElapsedMicroseconds());
                    }
                }
            });
        }
Esempio n. 9
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService, IJsonRpcLocalStats jsonRpcLocalStats, IJsonSerializer jsonSerializer)
        {
            long SerializeTimeoutException(IJsonRpcService service, Stream resultStream)
            {
                JsonRpcErrorResponse?error = service.GetErrorResponse(ErrorCodes.Timeout, "Request was canceled due to enabled timeout.");

                return(jsonSerializer.Serialize(resultStream, error));
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("Cors");
            app.UseRouting();
            app.UseResponseCompression();

            IConfigProvider?   configProvider    = app.ApplicationServices.GetService <IConfigProvider>();
            IRpcAuthentication?rpcAuthentication = app.ApplicationServices.GetService <IRpcAuthentication>();

            if (configProvider == null)
            {
                throw new ApplicationException($"{nameof(IConfigProvider)} has not been loaded properly");
            }

            ILogManager?          logManager           = app.ApplicationServices.GetService <ILogManager>() ?? NullLogManager.Instance;
            ILogger               logger               = logManager.GetClassLogger();
            IInitConfig           initConfig           = configProvider.GetConfig <IInitConfig>();
            IJsonRpcConfig        jsonRpcConfig        = configProvider.GetConfig <IJsonRpcConfig>();
            IJsonRpcUrlCollection jsonRpcUrlCollection = app.ApplicationServices.GetRequiredService <IJsonRpcUrlCollection>();
            IHealthChecksConfig   healthChecksConfig   = configProvider.GetConfig <IHealthChecksConfig>();

            if (initConfig.WebSocketsEnabled)
            {
                app.UseWebSockets(new WebSocketOptions());
                app.UseWhen(ctx =>
                            ctx.WebSockets.IsWebSocketRequest &&
                            jsonRpcUrlCollection.TryGetValue(ctx.Connection.LocalPort, out JsonRpcUrl jsonRpcUrl) &&
                            jsonRpcUrl.RpcEndpoint.HasFlag(RpcEndpoint.Ws),
                            builder => builder.UseWebSocketsModules());
            }

            app.UseEndpoints(endpoints =>
            {
                if (healthChecksConfig.Enabled)
                {
                    try
                    {
                        endpoints.MapHealthChecks(healthChecksConfig.Slug, new HealthCheckOptions()
                        {
                            Predicate      = _ => true,
                            ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
                        });
                        if (healthChecksConfig.UIEnabled)
                        {
                            endpoints.MapHealthChecksUI(setup => setup.AddCustomStylesheet(Path.Combine(AppDomain.CurrentDomain.BaseDirectory !, "nethermind.css")));
                        }
                    }
                    catch (Exception e)
                    {
                        if (logger.IsError)
                        {
                            logger.Error("Unable to initialize health checks. Check if you have Nethermind.HealthChecks.dll in your plugins folder.", e);
                        }
                    }
                }
            });

            app.Run(async(ctx) =>
            {
                if (ctx.Request.Method == "GET")
                {
                    await ctx.Response.WriteAsync("Nethermind JSON RPC");
                }

                if (ctx.Request.Method == "POST" &&
                    jsonRpcUrlCollection.TryGetValue(ctx.Connection.LocalPort, out JsonRpcUrl jsonRpcUrl) &&
                    jsonRpcUrl.RpcEndpoint.HasFlag(RpcEndpoint.Http))
                {
                    if (jsonRpcUrl.IsAuthenticated && !rpcAuthentication !.Authenticate(ctx.Request.Headers["Authorization"]))
                    {
                        var response             = jsonRpcService.GetErrorResponse(ErrorCodes.ParseError, "Authentication error");
                        ctx.Response.ContentType = "application/json";
                        ctx.Response.StatusCode  = StatusCodes.Status200OK;
                        jsonSerializer.Serialize(ctx.Response.Body, response);
                        await ctx.Response.CompleteAsync();
                        return;
                    }
                    Stopwatch stopwatch = Stopwatch.StartNew();
                    using CountingTextReader request = new(new StreamReader(ctx.Request.Body, Encoding.UTF8));
                    try
                    {
                        await foreach (JsonRpcResult result in jsonRpcProcessor.ProcessAsync(request, JsonRpcContext.Http(jsonRpcUrl)))
                        {
                            using (result)
                            {
                                Stream resultStream = jsonRpcConfig.BufferResponses ? new MemoryStream() : ctx.Response.Body;

                                long responseSize;
                                try
                                {
                                    ctx.Response.ContentType = "application/json";
                                    ctx.Response.StatusCode  = GetStatusCode(result);

                                    responseSize = result.IsCollection
                                        ? jsonSerializer.Serialize(resultStream, result.Responses)
                                        : jsonSerializer.Serialize(resultStream, result.Response);

                                    if (jsonRpcConfig.BufferResponses)
                                    {
                                        ctx.Response.ContentLength = responseSize = resultStream.Length;
                                        resultStream.Seek(0, SeekOrigin.Begin);
                                        await resultStream.CopyToAsync(ctx.Response.Body);
                                    }
                                }
                                catch (Exception e) when(e.InnerException is OperationCanceledException)
                                {
                                    responseSize = SerializeTimeoutException(jsonRpcService, resultStream);
                                }
                                catch (OperationCanceledException)
                                {
                                    responseSize = SerializeTimeoutException(jsonRpcService, resultStream);
                                }
                                finally
                                {
                                    await ctx.Response.CompleteAsync();

                                    if (jsonRpcConfig.BufferResponses)
                                    {
                                        await resultStream.DisposeAsync();
                                    }
                                }

                                long handlingTimeMicroseconds = stopwatch.ElapsedMicroseconds();
                                if (result.IsCollection)
                                {
                                    jsonRpcLocalStats.ReportCalls(result.Reports);
                                    jsonRpcLocalStats.ReportCall(new RpcReport("# collection serialization #", handlingTimeMicroseconds, true), handlingTimeMicroseconds, responseSize);
                                }
                                else
                                {
                                    jsonRpcLocalStats.ReportCall(result.Report, handlingTimeMicroseconds, responseSize);
                                }

                                Interlocked.Add(ref Metrics.JsonRpcBytesSentHttp, responseSize);
                            }

                            // There should be only one response because we don't expect multiple JSON tokens in the request
                            break;
                        }
                    }
                    catch (Microsoft.AspNetCore.Http.BadHttpRequestException e)
                    {
                        if (logger.IsDebug)
                        {
                            logger.Debug($"Couldn't read request.{Environment.NewLine}{e}");
                        }
                    }
                    finally
                    {
                        Interlocked.Add(ref Metrics.JsonRpcBytesReceivedHttp, ctx.Request.ContentLength ?? request.Length);
                    }
                }
            });
        }
Esempio n. 10
0
 public HttpRequestProcessor(IJsonRpcProcessor processor)
 {
     this.processor = processor;
 }
 public static IAsyncEnumerable <JsonRpcResult> ProcessAsync(this IJsonRpcProcessor processor, string request, JsonRpcContext context) => processor.ProcessAsync(new StringReader(request), context);