-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Allow Dispatchable
to return data
#13642
Comments
The problem is that people will expect that this also works for dispatchables included in a block. Then we expect people to send events and return values? Or we just add a lot of dummy runtime calls for returning values to contracts? I'm not convinced that this is a good way forward. Your only problem with chain extensions is the benchmarking? |
This makes no sense to me. Runtime APIs are getters. Dispatchables are setters. Why do I want my setters to be able to replace getters? |
I noticed that many chain extensions are just forwarding to dispatchables or public pallet functions. The main problem is requiring users to write this glue code. Benchmarking is just one (but the biggest part) of it. Essentially I am looking for a way to completely get rid of glue code and just give users a way of defining getters within a pallet. The glue code is completely dumb in this case. Users just want to interact with a pallets public interface. They can do that for dispatchables but not for functions returning data.
Yeah this is a problem. But to be fair those "dummy functions" for other runtime code to be consume already exists. Those are usually just public functions on a pallet. The way of making those accessible to users outside of the runtime is defining a runtime API that then calls this function. I am wondering whether it would be better to define getters not as Runtime API but much more similar to a
Dispatchables are not pure setters even right now. They just use a side channel for returning data (events).
Because runtime APIs don't have weight annotations. Hence they can't be called from contracts without adding annoying glue code. Unifying with dispatchables in one way or another would solve this problem. Alternate SolutionsLet me list all the alternate approaches that come to mind that would allow a contract to read data from a pallet without having to add glue code:
|
Could go hand in hand with: paritytech/polkadot-sdk#216
The same applies to the |
or we can weight annotate runtime API, which is actually a requirement because they are all public by default on RPC nodes and could be a DoS vector #12698 |
Yes. It is similar. But the way you proposed it in the linked issue it is more similar to a RuntimeAPI than a I don't think we want to call those getters in a separate Wasm instance when calling from a contract. We are already inside the runtime. So we probably want to design it more like a Of course the getters would need weight annotations.
Yeah. Theoretically. But in practice we really rally try hard not to break it. Mostly for the fact that a I think storage is in a different class. It is reorganized on purpose and it is not seen as a bad thing. We can't replace a changed or removed "storage" item with some compatibility function. It will just return wrong data. We can do that for a removed
I think this alone wouldn't make it viable to be called from contracts. Reason is that RuntimeAPIs are meant to be called from outside the runtime. While a contract wants to call the code directly. |
This sounds like a reasonable and good idea! |
Good :). Reposted into paritytech/polkadot-sdk#216. So we can probably close here then. |
We want to improve the user experience of calling into the runtime from a contract (#13641). While a contract can already call a
Dispatchable
only a subset of interactions can be crafted because aDispatchable
cannot return any data on success.This is because a dispatchable is required to return a
DispatchResult
which is defined asResult<(), DispatchError>
. In order to allow for a proper interaction which includes querying data from the runtime we need to allow aDispatchable
to return any type that implementsEncode + TypeInfo
.I think it is viable to support this in backwards compatible matter without causing disruption: Whenever the
Dispatchable
is called by an extrinsic or from another place that doesn't need or want the output it is just discarded. This is not only useful for contracts but could also reduce the amount of runtime APIs that are basically getters: Instead of adding a new API to query data we could call aDispatchable
that returns data usingsystem_dryRun
. This potentially also allows RPC nodes to argue about the weight of operations they are performing for users.Of course this change should be non breaking: Existing
Dispatchables
returning()
should work as-is.Result<T, DispatchError> where T: Encode + TypeInfo
from a dispatchable.The text was updated successfully, but these errors were encountered: