This proposal has been extracted from the long discussion in Inter-Canister Query Calls (Community Consideration). We will present and discuss it in the upcoming session of Technical Working Group: Scalability & Performance on October 20.
Composite queries
Background & Problem statement
Canisters have two types of methods: updates and queries. In contrast to updates, queries are not composable. In other words, a query cannot call other queries. This limitation makes it difficult to build scalable dapps that shard data across multiple canisters. Supporting calls in query methods is one of the most requested features.
We have an experimental prototype implementation of the feature. The prototype has two limitations:
- it does not support cross-subnet calls, which means that a query can only call queries of other canisters that are on the same subnet as the original canister.
- it does not support replicated execution, which means that a query is executed on a single machine of a subnet and its result doesn’t go through consensus.
Implementing the missing parts is a large (1-2 years) engineering effort due to technical challenges outlined in this forum post.
Proposal
Our proposal is to release the prototype with the known limitations and postpone the full implementation to the future.
We expect the following work before the prototype can be released:
- Add a new query type for backwards compatibility.
- Implement protection against malicious canisters.
- Improve performance.
- Write the specification.
We need a new query type because the existing queries can be executed both in non-replicated and replicated mode. Since the prototype doesn’t support replicated execution, releasing it without a new query type would break the contract of the existing queries.
We propose to name the new query type composite_query
and propose the following changes:
- Add a new public entry-point type in the WebAssembly module of canisters:
canister_composite_query <name>
. - Add a new
composite_query
keyword in Motoko, Rust CDK, and Candid.
Composite queries will be similar to the existing regular queries except that they can call other queries and they do not support replicated execution. Note that composite queries can call both regular and composite queries. Update methods cannot call composite queries.
Future outlook
In the future it should be possible to implement support for both cross-subnet calls and replicated execution.
For cross-subnet calls we would need to solve the technical challenge related to the security of caller_id
(details) and rewrite the existing implementation of query calls to use an asynchronous/distributed algorithm.
Replicated execution support has more complexity and unknowns. Core components of the Internet Computer such as state manager, message routing, execution would need to support multiple versions of the same canister in the replicated state.
If both features are implemented, we would be able to unify composite queries and regular queries.
Alternatives
We could attempt to avoid a new query type by implementing support for replicated execution before releasing the feature. We expect this to be a significant engineering effort that would delay the feature by at least 1-2 years.