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

Possible strategy to help us produce reliable JSON-RPC response #610

Open
jangko opened this issue Apr 30, 2021 · 11 comments
Open

Possible strategy to help us produce reliable JSON-RPC response #610

jangko opened this issue Apr 30, 2021 · 11 comments
Labels
EL Hive RPC JSON-RPC over HTTP/websocket

Comments

@jangko
Copy link
Contributor

jangko commented Apr 30, 2021

One of the weakness and most annoying thing when implement JSON-RPC function is the lack of response validation. The other thing is we need to craft the response shape in a non reliable way.

On the other hand, Graphql have builtin validation and execution system that greatly simplify the process of constructing response based on the defined schema while at the same time validate the response is correct for both the structure and serialization format. it is more akin to what you ask is what you get.

Graphql doesn't care how you deliver the result, you can serve it over HTTP, Websocket, RPC, etc. Graphql also doesn't dictate which serialization format you use. And fortunately, the common serialization format for Graphql is JSON. So usually a Graphql implementation already have a JSON serialization builtin.

Based on this fact, I have an idea worth exploring. The idea is we simply wrap the JSON-RPC function over a Graphql query.
And then let the Graphql engine produce a consistent response based on the Graphql-schema we defined or reuse/extend standard eth1.0 schema.

Benefits:

  • We can save much time reinventing sophisticated test for JSON-RPC. The existing modified Graphql test framework can be reused.
  • We can use the same underlying code for both JSON-RPC and Graphql, they have much overlapping response shape.
  • Shorter time to deliver reliable JSON-RPC.
  • Much of the JSON-RPC serialization code can be thrown away, they are a lump of a mess actually.
  • Everything else including JSON-RPC server is left untouched, we can localize potential bugs.
@jlokier
Copy link
Contributor

jlokier commented Apr 30, 2021

Schemas and schema validation sound great. If we can reuse the code and remove some duplication serialisation to JSON, that's good too.

However, we do need to remain compatible with JSON-RPC spec, and the direction we should be aiming with JSON-RPC support is all of the below (they can be done at the same time). Other clients are working towards this too, there's some effort to organise it.

  • JSON-RPC 1.0
  • JSON-RPC 2.0
  • The standardising-in-progress effort for Eth1 client RPC clients, https://ethereum.org/en/developers/docs/apis/json-rpc/
  • There is talk (at the standardising meetings) of settling on OpenRPC, https://open-rpc.org/beginners
    • OpenRPC builds on JSON-RPC 2.0 by adding a kind of API scheme like OpenAPI, and in some way serving an API description document to clients that ask for a list of supported APIs

Is the GraphQL code flexible enough to describe what JSON-RPC clients using the above will be looking for?

If GraphQL can't do it along, let's find a way to reuse the code, schemas and validation etc that works for both.

@jlokier
Copy link
Contributor

jlokier commented Apr 30, 2021

Side note: Due to history, Eth2 clients are standardising APIs and schemas for a REST API instead of JSON-RPC or, as far as I know, GraphQL. This doesn't affect Eth1 for now, but it might be good to give a little thought anticipating how REST could fit in. In other words, if there's a natural way for the GraphQL-derived schema and validation system in nimbus-eth1 (maybe extended to suit JSON-RPC needs) to present the same info via a REST API as well, that could be worth considering.

@jangko
Copy link
Contributor Author

jangko commented Apr 30, 2021

Is the GraphQL code flexible enough to describe what JSON-RPC clients using the above will be looking for?

very flexible, you can try our graphql toy server to find out how flexible the query language is. it can simulate Option[T] easily using @skip or @include directive combined with $variables. we can store not only the schema but also the query operation and then later call it similar to SQL stored procedure.

we do need to remain compatible with JSON-RPC spec

we only use graphql for validating and shaping the response content, the delivery mechanism still handled by JSON-RPC the same way to Graphql HTTP server. Both have their own response format, but the content is the same.

OpenRPC is looks similar enough to Graphql, but Graphql syntax is more cleaner and graphql introspection system is more sophisticated.

to present the same info via a REST API as well

From https://github.com/ethereum/eth2.0-APIs: Currently, the only supported return data type is JSON.
Talking about JSON, Graphql is perfect for shaping the response structure and format in a consistent way.

@jlokier
Copy link
Contributor

jlokier commented Apr 30, 2021

That sounds like a good direction to take it then.
I would not be surprised even there was even a fairly natural mapping from REST paths to GraphQL.

Is it difficult to add new types of ad-hoc queries / responses while developing, when you just want to get some new type of data out? With our current JSON-RPC, it may be rather basic code, but it's easy and clear how to add add-hoc RPCs in just a few lines of code.

@jangko
Copy link
Contributor Author

jangko commented May 1, 2021

Is it difficult to add new types of ad-hoc queries / responses while developing, when you just want to get some new type of data out?

It depends on how strong the validation required. our JSON-RPC may looks easy, but the content validation is weak.

I would not be surprised even there was even a fairly natural mapping from REST paths to GraphQL.

Both your question and your statement inspire a crazy idea in my mind.
Instead of wrap individual RPC call, why not map entire JSON-RPC into graphql? By taking this approach, we can abandon altogether JSON-RPC un/marshalling system and have a strong typed and strong serialization format validation for both input parameters and response output.

After that, mapping REST call to GraphQL is roughly similar.

@jangko
Copy link
Contributor Author

jangko commented May 6, 2021

Turn out, some of RPC to GraphQL already mapped in EIP1767:
https://eips.ethereum.org/EIPS/eip-1767#backwards-compatibility

when implementing nimbus-eth1 graphql, I only copy the GraphQL DSL schema, and never scroll down the page, this will save a lot of time figuring out myself the correct mapping.

@jangko jangko added the RPC JSON-RPC over HTTP/websocket label May 20, 2021
@jangko
Copy link
Contributor Author

jangko commented May 20, 2021

One major obstacle when using GraphQL as JSON-RPC backend will came from debug_xxx front.
other RPCs such as eth, net, shh can be simulated using GraphQL, but debug rpc is a bit hard.
The reason is, GraphQL is too good/strict at validating the response, both response shape and response serialization format.
On the other hand, debug rpc produce a rather freestyle json.

Of course we can make the debug response shape more rigid, but defining the GraphQL types to accomodate them is not that simple.

@jangko
Copy link
Contributor Author

jangko commented May 24, 2021

There is still a chance for GraphQL to overcome this freestyle json using Any scalar type or something similar.
see the idea from graphql/graphql-spec#688

@arnetheduck
Copy link
Member

Isn't using Nim types for the json requests/responses viable?

@jangko
Copy link
Contributor Author

jangko commented May 24, 2021

Isn't using Nim types for the json requests/responses viable?

yes, but writing test case for conventional JSON-RPC server is far from easy/convenient.
our current schemaless json rpc force us to write complicated test case -- time consuming.

if we can piggyback the json rpc using graphql, it will far easier to write test case. we can delegate much of the validation to graphql engine instead of writing complicated test case. better use our time/energy for the implementation itself.
see this for example https://status-im.github.io/nim-graphql/

@jangko
Copy link
Contributor Author

jangko commented Oct 19, 2023

A standardized test suite for RPC request and response is located in
https://github.com/ethereum/execution-apis.
We can port rpc-compat simulator from hive in similar fashion with other simulators.

@jangko jangko added the EL label Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
EL Hive RPC JSON-RPC over HTTP/websocket
Projects
None yet
Development

No branches or pull requests

3 participants