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

Tendermint RPC Batch Requests #1298

Closed
codehans opened this issue Oct 20, 2022 · 10 comments · Fixed by #1303
Closed

Tendermint RPC Batch Requests #1298

codehans opened this issue Oct 20, 2022 · 10 comments · Fixed by #1303
Milestone

Comments

@codehans
Copy link
Contributor

We (Kujira) are facing some infrastructure challenges when building UIs containing requests to multiple contracts (eg our users are looking for an overview dashboard of all 25 pairs on https://fin.kujira.app/). This causes issues managing our rate limiting and request volume when loading each one individually.

Tendermint has supported batch requests for some time now https://github.com/tendermint/tendermint/pull/3534/files#diff-6f806667d644e5723e506395dff9139df8a61d3a5f47cd2d95f9f143482a036c, which is as simple as sending an array of requests instead of a single object.

I'll be looking to extend the RPC components of cosmjs to support batch requests over the next few days so we can support this in our own apps.

I wanted to open a discussion to see if there had been any prior chat (couldn't find anything in search), if there was anything ongoing that I would be better off contributing to, and also to get a sanity check on whether this would be an acceptable thing to PR?

Thanks!

@webmaster128
Copy link
Member

Oh, very interesting. I never came across the batching in Tendermint or the JSON-RPC spec.

Thanks for bringing that up. I'd love to integrate this here when it is working well. Some hints for implementation:

  • Start with HACKING.md
  • You only need to worry about the tendermint-rpc package for now, not the blockchain clients. There are Tendermint 0.34 and 0.35 test systems available in scripts/tendermint (see CI config for details how they are used).
  • The export interface RpcClient { needs an additional API to send multiple RPC requests. Since this also has a different return type (a list), I'd add readonly executeMultiple: (request: JsonRpcRequest[]) => Promise</*...*/>;
  • Feel free to only implement the functionality in the HttpClient if you don't need websocket support. The websocket connection will eventually die so we don't need to put resources in it.

@codehans
Copy link
Contributor Author

Thanks for the rapid response @webmaster128. Very useful to know about the future of the websocket client, I was getting a little tempted by that one.

Have been exploring some ergonomics of the API design in our apps, and the way that the HttpClient integrates with the QueryClient and extensions. The issue is that the standard interfaces, eg queryClient.bank.balance doesn't expose the underlying RPC request. Equally, I don't really want to be concerned with how any individual request is batched with others inside my app components. I'm leaning towards a custom HttpBatchClient that you use with Tendermint34Client.create.

This would have some generic behaviour which batches and dispatches RPC requests, perhaps on some user-defined timeout - 50/100ms or something. Potentially with further batching logic that could take into account request paths etc.

This way you can create some singleton instance of your client with whatever store your FE framework uses, and continue to use the standard query interface, without having to worry about how requests are batched.

Thoughts?

@webmaster128
Copy link
Member

webmaster128 commented Oct 20, 2022

I'm leaning towards a custom HttpBatchClient that you use with Tendermint34Client.create.

Ah, so you implement the existing RpcClient interface. Then the HttpBatchClient would internally collect requests (i.e. delay the network request for let's say 10ms), send them in batch and then fulfil or reject all the promises?

That would be cool and fit well with the existing infrastructure.

@webmaster128
Copy link
Member

Very useful to know about the future of the websocket client, I was getting a little tempted by that one.

See tendermint/tendermint#7677 and linked discussions for more info.

@codehans
Copy link
Contributor Author

I'm leaning towards a custom HttpBatchClient that you use with Tendermint34Client.create.

Ah, so you implement the existing RpcClient interface. Then the HttpBatchClient would internally collect requests (i.e. delay the network request for let's say 10ms), send them in batch and then fulfil or reject all the promises?

That would be cool and fit well with the existing infrastructure.

Yup that's exactly it. Will hopefully have a prototype some time tomorrow

@webmaster128
Copy link
Member

FYI: here is a related discussion for a server-side implementation for CosmWasm queries: CosmWasm/wasmd#72. But it would not help for other Cosmos SDK queries.

@webmaster128
Copy link
Member

Yup that's exactly it.

Man, this is genius. It will fit so nicely in the current stack and can easily become the default client as it does not change a single higher level API.

@codehans
Copy link
Contributor Author

Yup that's exactly it.

Man, this is genius. It will fit so nicely in the current stack and can easily become the default client as it does not change a single higher level API.

Turns out it wasn't all that much of a lift. Got it batching all 25 FIN pairs into a single request locally. Also batching eg gov tally responses on proposal lists too.

#1300

@webmaster128
Copy link
Member

webmaster128 commented Oct 25, 2022

The HttpBatchClient was release in 0.29.0. It seems to work great, thanks again!

In https://github.com/cosmos/cosmjs/milestone/18 you find a few follow up tickets for the class. If you are in the mood to grab some of them, that would be appreciated.

@webmaster128
Copy link
Member

#1323 contains a bunch of updates and improvements to the HttpBatchClient implementation. @codehans could you have a look into the PR?

aelesbao added a commit to archway-network/arch3.js that referenced this issue Jun 27, 2023
This change introduces a new factory method on the `ArchwayClient` that
uses an `HttpBatchClient` for batching multiple requests, reducing
round-trips to the RPC endpoint.

More details on how the batch client works can be found [in the original
issue](cosmos/cosmjs#1298) or [in this usage
tutorial](https://vimeo.com/771505975).
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 a pull request may close this issue.

2 participants