Skip to content

Parse incoming Jsons in chunks#10207

Merged
LukaszRozmej merged 21 commits intomasterfrom
feature/parse_json_in_chunks
Feb 1, 2026
Merged

Parse incoming Jsons in chunks#10207
LukaszRozmej merged 21 commits intomasterfrom
feature/parse_json_in_chunks

Conversation

@LukaszRozmej
Copy link
Member

@LukaszRozmej LukaszRozmej commented Jan 13, 2026

Should replace #10191

Changes

  • Parse incoming JSON in chunks
  • Save state in JsonReaderState

Types of changes

What types of changes does your code introduce?

  • New feature (a non-breaking change that adds functionality)
  • Optimization

Testing

Requires testing

  • Yes

If yes, did you write tests?

  • Yes

Notes on testing

RPC traffic.

Remarks

One thing which is kind of wrong is that we ignore trailing garbage:

curl localhost:8545 --data '{"method":"eth_getTransactionByHash","params":["0xb8a9a1c10fe776c76fa30b36206cf5adf0b6e1c417c556c22f802c8eca010426"],"id":1,"jsonrpc":"2.0"} GARBAGE GOES HERE' -H "Content-Type: application/json" -X POST `

Will result in parsing error in Geth and correct response from us.
I tried to make it work with looking into how to handle it.
But it also depends on the channel - through sockets we can get multiple JSON documents one by one. Which is not happening by http.
If they got chunked in any way we would need to try to wait for next chunk.
It all got very complicated.

What we could do:

  • reject if anything is trailing
  • reject if next non-whitespace isn;t { or [ - which at least haves a chance to be proper json
  • leave as is
  • Try to parse what we have left - if it doesn't error out - we are fine. This could lead to double-parsing though, reducing performance.
  • Have different behavior on http vs sockets

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements chunk-based JSON parsing for incoming JSON-RPC requests to improve performance and handle large payloads that arrive in multiple network packets. Instead of reading all data at once with ReadToEndAsync, the code now processes data incrementally using ReadAsync in a loop, maintaining parser state between chunks.

Changes:

  • Replaced ReadToEndAsync with chunked ReadAsync loop for incremental JSON parsing
  • Introduced JsonReaderState to preserve parser state across chunk boundaries
  • Refactored ProcessAsync method to handle partial JSON documents and resume parsing when more data arrives

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs Implements chunk-based JSON parsing with state management, replaces synchronous full-read pattern with asynchronous incremental processing
src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcProcessorTests.cs Adds test for processing multiple large requests arriving in chunks to verify the new parsing behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@benaadams benaadams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didnt know STJ supported this; I love it :)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs:134

  • This early exit check does not prevent the subsequent code from executing. When ProcessExit.IsCancellationRequested is true, the method yields an error response but continues to execute the rest of the method. This should either return after yielding or be wrapped in an else clause to prevent the reader from being processed unnecessarily.
    public async IAsyncEnumerable<JsonRpcResult> ProcessAsync(PipeReader reader, JsonRpcContext context)
    {
        if (ProcessExit.IsCancellationRequested)
        {
            JsonRpcErrorResponse response = _jsonRpcService.GetErrorResponse(ErrorCodes.ResourceUnavailable, "Shutting down");
            yield return JsonRpcResult.Single(RecordResponse(response, new RpcReport("Shutdown", 0, false)));
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

LukaszRozmej and others added 2 commits January 14, 2026 14:54
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/Nethermind/Nethermind.Core/Extensions/ReadOnlySequenceExtensions.cs:45

  • There’s an extra closing brace here, which will break compilation (method/class braces become unbalanced). Remove the stray } so the method and class close correctly.
        // The entire sequence was trimmed chars
        return sequence.Slice(sequence.End);
    }
}


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI commented Jan 30, 2026

@LukaszRozmej I've opened a new pull request, #10356, to work on those changes. Once the pull request is ready, I'll request review from you.

…ests (#10356)

* Initial plan

* Change test endpoint from Http to Ws for multiple requests test

Co-authored-by: LukaszRozmej <12445221+LukaszRozmej@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: LukaszRozmej <12445221+LukaszRozmej@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

LukaszRozmej and others added 2 commits January 30, 2026 21:38
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

private ArrayPoolList<JsonRpcRequest> DeserializeArray(JsonElement element) =>
new(element.GetArrayLength(), element.EnumerateArray().Select(DeserializeObject));

private static readonly JsonReaderOptions _jsonReaderOptions = new() { AllowMultipleValues = true };
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allowing multiple top-level JSON values in the reader (AllowMultipleValues=true) combined with the HTTP pipeline only consuming the first JsonRpcResult (Startup.cs breaks after the first response) means trailing non-whitespace bytes (or even a second JSON document) can be silently ignored for HTTP requests. If HTTP is intended to accept exactly one JSON-RPC request (object or batch array), consider making this behavior endpoint-specific: for Http contexts, validate that the remaining bytes after the first parsed value are only whitespace once the body is complete, and return a single ParseError/InvalidRequest instead of yielding a successful response for the first value.

Suggested change
private static readonly JsonReaderOptions _jsonReaderOptions = new() { AllowMultipleValues = true };
private static readonly JsonReaderOptions _jsonReaderOptions = new() { AllowMultipleValues = false };

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@LukaszRozmej LukaszRozmej merged commit 1c2c5cf into master Feb 1, 2026
89 checks passed
@LukaszRozmej LukaszRozmej deleted the feature/parse_json_in_chunks branch February 1, 2026 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants