-
Notifications
You must be signed in to change notification settings - Fork 254
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
Should we allow nested static calls to also benefit from a dynamic pallet/call index? #716
Comments
Absolutely we should be able to use the static API for batching calls and similar. After all the static part is about the shape of the call data (MUST be compatible with target node) and the pallet/call indices have always been assumed to be "dynamic" because usually nodes are configured differently. |
Going further, if we double down on this idea of implementing And yup, exactly; a static codegen interface leaning on this would then provide the correctness guarantee without losing out in terms of being too rigid and unable to cope with any variations in the metadata. A derived impl of I feel like it could open the door to some nice API simplifications as the dynamic and static worlds get a bit closer while still retaining their core benefits. |
So to pull back what I said in chat, I think the approach to try this all out would be: Step 1: make Step 2: impl |
This can be closed now; the EncodeAsType/DecodeAsType stuff (see #842) means that now it will Just work. While I haven't added a nice wrapper around the generated |
Currently, if you create a static transaction, the pallet and call index that the call data will be encoded with are dynamic based on the node we're talking to.
But, if you create a nested call like so (see the multisig.rs example):
then
tx
itself will be encoded with a dynamic pallet/call index, butinner_tx
will be encoded with a static index based on the codegen ofpolkadot::runtime_types::polkadot_runtime::RuntimeCall
.We have a trait called
EncodeWithMetadata
that basically takes a type ID, metadata and value and encodes to SCALE. DynamicValue
types implement it, and anything implementingEncode
also implements it via a wrapper type.Perhaps in the codegen, we could replace any reference to
some_runtime::RuntimeCall
in generated types with some type likeStaticTxPayloadEncoded
. This type might look something like:it might be that this
StaticTxPayloadEncoded
also implementsTxPayload
so that it can be directly passed into subxt as a valid transaction. Basically, it would allow the user to encode the same stuff that they would viaRuntimeCall
, but more easily.If this new
StaticTxPayloadEncoded
arg was at most just a top level arg to some transaction calls, then we can manually implementEncodeWithMetadata
on all of the call arg structs, call that viaStaticTxPayload<T>
when we need to encode and be done with it.But some calls like
utility.batch
take args likeVec<RuntimeCall>
, which we'd want to turn intoVec<StaticTxPayloadEncoded>
. Ie, the call isn't the top level arg. To cater for this, we'd need to implEncodeWithMetadata
on every type that we generate (at least all those that could be used in call args, but easier just to blat it out for everything) so that it's recursively called on all nested things, including nestedStaticTxPayloadEncoded
's.Perhaps it's worth splitting out
EncodeWithMetadata
into a separate crate with it's own derive macro so that it's trivial to implement instead ofEncode
on our generated types, and we can impl it on all core types as withEncode
eg:Long term, this would give all static types access to the relevant metadata and type info for what they are going to be encoded into. This lets things like
StaticTxPayloadEncoded
be "a little dynamic", and leaves the door open in case we need to add a sprinkling of dynamism elsewhere.The downside is that we'd lose some performance over
Encode
and introduce all of this extra machinery to give us this dynamism.The current alternative for users is to lean on the
subxt::dynamic
stuff for such cases, which, being fully dynamic in the way it encodes, will already handle this sort of case. But, it'd be nice to give people the chance to use our static codegen wherever possible, and this is currently a hole that makes static types worse for a use case they should be able to handle.Any thoughts @ascjones?
The text was updated successfully, but these errors were encountered: