Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for batch requests #86

Closed
wants to merge 3 commits into from

Conversation

alvin-reyes
Copy link

Context

Batched requests are an optional feature in the JSON-RPC 2.0 specification. However, Ethereum clients offer this feature and downstream users like block explorers (e.g. Blockscout) depend on it.

Change

This adds support for batch request as per specs here Batched requests

Related Issue

filecoin-project/ref-fvm#1047

Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

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

Thank you! Can we add some more test scenarios? A single-item batch, a batch with successes and failures, a batch with one unrecognised method, etc.

@@ -168,14 +167,36 @@ func (s *RPCServer) handleReader(ctx context.Context, r io.Reader, w io.Writer,
s.maxRequestSize))
return
}
// check if bufferedRequest is array or not.
if bufferedRequest.Bytes()[0] != '[' {
Copy link
Member

Choose a reason for hiding this comment

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

Are we sure there's no way to send a request with an empty body? We probably need to check if the request is empty before continuing.

Comment on lines +180 to +183
if err := json.Unmarshal(bufferedRequest.Bytes(), &reqs); err != nil {
rpcError(wf, &req, rpcParseError, xerrors.Errorf("unmarshaling requests: %w", err))
return
}
Copy link
Member

Choose a reason for hiding this comment

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

A single malformed request would make the whole batch fail. Is this what the JSON-RPC 2.0 spec mandates? If not, we would need to unmarshal requests individually, and record individual failures in the buffered response.

return
}
for _, req := range reqs {
s.doHandleRequest(ctx, wf, req, *bufferedRequest, rpcError)
Copy link
Member

Choose a reason for hiding this comment

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

Will a single failing request make the whole batch fail? Pretty sure the JSON-RPC 2.0 doesn't expect atomicity here, but rather individiual reporting of failures. We need to test a variety of failure scenarios:

  1. Two out of four requests carry invalid ID.
  2. Two out of four requests fail functionally (generate an error in their handlers).
  3. Two out of four requests carry the same ID.
  4. Two out of four requests fail to deserialize.

I suspect that in all these cases, the JSON-RPC 2.0 spec would mandate that those failures don't prevent the other two successful requests from being processed successfully.

@itsdevbear
Copy link

Any updates here? Can help contribute if needed 🙏 using for go MIT licensed eth node.

@raulk
Copy link
Member

raulk commented Feb 1, 2023

@itsdevbear that would be great. I believe @alvin-reyes was supposed to get to this last week, but I guess we can consider this PR stale and have another soul claim it.

@itsdevbear
Copy link

Will take a look, we are currently using the geth server but LGPL.....

Anything major need to be done still? Or just address the above comments?

@itsdevbear
Copy link

@raulk unrelated but is this lib used in prod on filecoin nodes?

@tarassh
Copy link
Contributor

tarassh commented May 2, 2023

Any updates on this PR? highly anticipated feature.

@Stebalien
Copy link
Member

fixed in #99

@Stebalien Stebalien closed this May 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants