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

Idea: do multiple queries in one API call #72

Closed
webmaster128 opened this issue Feb 10, 2020 · 16 comments
Closed

Idea: do multiple queries in one API call #72

webmaster128 opened this issue Feb 10, 2020 · 16 comments
Labels
API Fixes to the external client api discussion help wanted Extra attention is needed

Comments

@webmaster128
Copy link
Member

When querying a bunch of contracts (like multiple ERC 20 balances), we have a lot of overhead for the network roundtrip for a small execution. I think it would be cool to be able to batch such queries to reduce the number of roundtrips. This way applications with many cheap queries can be more performant. I think a reasonable gas strategy would be to apply the same limit on a single query as well as the sum of the batch, i.e. a global limit per request.

@ethanfrey
Copy link
Member

Interesting idea. It definitely would need another endpoint and some testing.

I like to do it, but in a later release, like 0.6.1

@ethanfrey ethanfrey added the API Fixes to the external client api label Feb 25, 2020
@ethanfrey ethanfrey added this to the v1.0.0 milestone Aug 19, 2020
@ethanfrey
Copy link
Member

This would be a nice one in the wasm module.

Not a general purpose "multiple query" endpoint. Just one more query endpoint that is like querySmartMultiple and it takes a list of smartQueries, probably with some limit (10?) and combined gasLimit.

This will help make UIs more responsive, when eg. querying balances from 20 different cw20 contracts

@ethanfrey ethanfrey modified the milestones: v1.0.0, v1.1.0 Aug 19, 2020
@webmaster128
Copy link
Member Author

Looking at this 6 months old ticket now, I wonder why I thought we need it. Sounds like premature optimization to me now.

@ethanfrey
Copy link
Member

Fair enough. You wanted it for wasm glass. Happy to push this to later

@webmaster128
Copy link
Member Author

If I recall correctly, this was more for the Neuma integration that regularly polled account balances for multiple contracts. wasm glass only does one query at a time initiated by the user.

@alpe
Copy link
Contributor

alpe commented Nov 20, 2020

This use case is not uncommon in microservice architecture and lead to the backend for frontends pattern. If we built this as a general purpose endpoint into the server then we open the doors for DoS attacks.
I would propose to close this now

@webmaster128
Copy link
Member Author

Even if we do want something like this at some point in the far future, it is not a priority now and poorly defined. Closing.

@webmaster128
Copy link
Member Author

One more thought that comes to my mind: Such a feature could also live in a (to be built) query proxy server, which takes a bunch of queries, sends them to multiple nodes in parallel and returns the combined result to the client.

@webmaster128
Copy link
Member Author

This was recently discussed in https://twitter.com/larry0x/status/1517228756800262147. Larry built a contract that serves as a proxy to perform multiple queries at once. It shows a market demand for such a thing. We could implement it nicer and more efficiently in wasmd.

@alpe alpe reopened this Sep 30, 2022
@alpe alpe moved this to 🆕 New in wasmd backlog Sep 30, 2022
@alpe alpe moved this from 🆕 New to ❓ Needs more info in wasmd backlog Sep 30, 2022
@alpe
Copy link
Contributor

alpe commented Sep 30, 2022

People always find a workaround :-)
I have reopened it again for further discussions and ideas

@webmaster128
Copy link
Member Author

webmaster128 commented Oct 20, 2022

I have a refinement thought here. wasmd may or may not be responsible for batching network requests. It's still a bit unclear to me if this is in scope or priority. However, what wasmd can do for sure is send multiple queries to the same contract (at a fixed height). So a

message QuerySmartContractStateRequest {
  // address is the address of the contract
  string address = 1;
  // QueryData contains the query data passed to the contract
  bytes query_data = 2 [ (gogoproto.casttype) = "RawContractMessage" ];
}

but with repeated query_data. Then a version of func (k Keeper) QuerySmart( that takes multiple requests and executes k.wasmVM.Query multiple times on one instance.

This way you get an efficient way to query the same contract for multiple things using the same Wasm instance.

@webmaster128
Copy link
Member Author

Okay that might be a questionable idea because a contract's memory is not cleared between queries. The contract can then store data to memory that still sits there for the second query. So it has an element of unsafety, at least for permissionless contracts. But the worst that can happen is a contract manipulates its own query result in a way that sending the same query twice to the same instance returns different results. Not sure if there is anything you can gain from writing such login in your contract.

@ethanfrey
Copy link
Member

The batch request is often querying eg. user balance on 20 different cw20 tokens.

It would be important to allow both address and bytes to be specified for both queries in most cases. (Basically, I would only attempt to fix this if the solution covers that case).

@alpe alpe added the help wanted Extra attention is needed label Nov 14, 2022
@webmaster128
Copy link
Member Author

In https://twitter.com/CosmWasm/status/1592853559602991106 you see a demo how to do RPC request batching on the Tendermint level with CosmJS. This can save a lot of network roundtrips when an application does many requests at the same time. Since it is implemented at the Tendermint RPC level, it works for CosmWasm and all other queries the same way out of the box. It is an advanced op-in feature for now but I can see than being the default behaviour in a couple of months if the batching client turns out to be stable.

Given that, I wonder to what degree wasmd should implement batching for only one query type (smart queries). Is there anything wasmd can do significantly better internally than the RPC batching we now have? Are there other transport layers than Tendermint RPC of significant importance in the foreseeable future?

@ethanfrey
Copy link
Member

That twitter post is amazing.
I think that should be the canonical solution and we don't try to hack something in x/wasm which isn't even what we really want.

@alpe alpe removed this from wasmd backlog Mar 3, 2023
@alpe
Copy link
Contributor

alpe commented Mar 3, 2023

I watched the video again today and was wondering why the issue is still open :-)
I think the batch client solves the problem very well with Tendermint RPC. Let's go for this. @webmaster128 thanks for bringing this solution up!

@alpe alpe closed this as completed Mar 3, 2023
loloicci pushed a commit to loloicci/wasmd that referenced this issue Feb 8, 2024
* test: add next pagination key test in ContractHistory

Signed-off-by: 170210 <j170210@icloud.com>

* chore: add this PR to CHANGELOG

Signed-off-by: 170210 <j170210@icloud.com>

* fixup: fix for comment

Signed-off-by: 170210 <j170210@icloud.com>

* fixup: set expPaginationTotal

Signed-off-by: 170210 <j170210@icloud.com>

---------

Signed-off-by: 170210 <j170210@icloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Fixes to the external client api discussion help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants