api icon indicating copy to clipboard operation
api copied to clipboard

Question: identifying pallets in a runtime

Open kianenigma opened this issue 2 years ago • 8 comments

The challenge at hand is t identify if pallet-balances is in a runtime or not. My elementary way of solving this problem is testing something like api.query.balances !== undefined.

This works in 99% of the cases, but it is fundamentally flawed, as it depends on the name given to pallet-balances by contruct_runtime!.

Question is: is there a better, safer way to do this? I see efforts in substrate that expose the crate name in a Rust context. Seems like all we have to do is to expose the same thing over metadata. See: https://github.com/paritytech/substrate/pull/10053

kianenigma avatar Jul 11 '22 10:07 kianenigma

There is no way atm. For chains with renamed instances (or multiples), we have been using a non-standard additional field in API instances to identify the mappings.

I believe this is used in Acala (treasury, etc.), InterBTC (balances, etc), and some others. (Could be wrong on this list, it really has been ages...)

EDIT: Found an example - https://github.com/AcalaNetwork/acala.js/blob/62f04e53ddcac0d25bb89023d96ea8673b7b98b8/packages/type-definitions/src/index.ts#L73-L75

EDIT2: This is how for instance balances are used in the API itself to extract all matching pallets based on the name - https://github.com/polkadot-js/api/blob/ea9cd6981d59710605e17855173cdd37ca8bd66d/packages/api-derive/src/balances/all.ts#L214 (Same would apply to eg. council as linked by Acala)

jacogr avatar Jul 11 '22 10:07 jacogr

example from derive.balances.all seems be quite close to what I want, but I am afraid it is itself outdated. If you try any of

console.log(api.registry.getModuleInstances(api.runtimeVersion.specName.toString(), "Balances"))
console.log(api.registry.getModuleInstances(api.runtimeVersion.specName.toString(), "balances"))
console.log(api.registry.getModuleInstances(api.runtimeVersion.specName.toString(), "system"))

they are return undefined.

kianenigma avatar Jul 16 '22 12:07 kianenigma

It is as-used. And yes, that return value would be correct. It would return an array of the different instances if anything is found, alternatively undefined when no overrides are present.

This means the caller needs to apply their own defaults, e.g. in the case you mentioned it applies ['balances'] when nothing is found - https://github.com/polkadot-js/api/blob/12750bc83d8d7f01957896a80a7ba948ba3690b7/packages/api-derive/src/balances/all.ts#L153

(In this case balanceInstances: string[] = ['balances'] - this would be for the vast majority of the cases, like mentioned above, I can think of 2 chains off-hand that I know has overrides, although it is quite possible I lost track somewhere along the way)

jacogr avatar Jul 16 '22 12:07 jacogr

So getModuleInstances only returns something other than undefined if there has been overrides?

If such, the general question is still open.

I haven't inspected the metadata exactly, but each pallet should ideally return both an instance name, and something more meta like "module name", so that the api can understand the relation between the two, e.g. api.query.balancesOther and api.query.balances both should have "module name": "balances", coming NOT from what the name of the instance is, but rather from the fact that it is coming from pallet-**balances**.

Do you know if this data already exists in metadata? if so, let's keep this open as a TODO for you, else we first fix it in substrate.

kianenigma avatar Jul 17 '22 15:07 kianenigma

There is the path on the Error, Event & Call types, and it is sane/simple to use it. (PR merged in to extend matching on path as well)

However, this still doesn't solve it completely - so if we have pallet_balances::pallet::Call as a (prettified) path in most cases, we still have holes and the combo of API definitions & best-effort-extract is the only sane approach.

  • the current instances can point e.g. generalCouncil -> council - just using collective here is not quite what we are after (so the per-config is the best approach if you need exact knowledge)
  • obviously the balances one works... however some chains do rename stuff, so in the past we had issues where pallet_democracy::* doesn't exist, but darwinia_democracy::* does. (In this specific case a recent runtime upgrade did move it to "standard paths", so it may be an issue now that might exist and has in the past, but cannot actually be found in real deployments as of right now)

So have the match does move it closer, but it cannot get to 100%. So it will work... mostly.

jacogr avatar Jul 18 '22 08:07 jacogr

I don't think we are talking about the same approach.

I don't think this path (e.g. pallet_balances::pallet::Call) will be helpful in solving this. Or if it helps, it will still be hacky for all the reasons you mentioned.

What I think is the scalable approach is "including the name of the rust crate of every pallet instance in its metadata".

For example, api.qeury.balances.crateName() would return pallet-balances. If you have multiple instances, rename them or anything else, they all still return pallet-balances.

As noted, it seems to me like this information is already in the metadata as of https://github.com/paritytech/substrate/pull/10053, but I have to double check this. Either way, it is technically possible.

Once this exists, it should be trivial to build the reverse map: give me all the instances of pallet-balances, which returns [x, y, z] and then you can do api.query.x and api.query.y and so on..

kianenigma avatar Jul 25 '22 16:07 kianenigma

The name of the crate is where the above matches, the full path.

Over and above that, nothing more that will be done on the API. So it t stays as-is.

jacogr avatar Jul 25 '22 16:07 jacogr

The name of the crate is where the above matches, the full path.

Where can I get this path for each pallet instance, e.g. for api.query.generalCouncil?

kianenigma avatar Jul 26 '22 09:07 kianenigma

This issue has been open for 21 days with no activity and is not labelled as an enhancement. It will be closed in 7 days.

polkadot-js-bot avatar Aug 16 '22 11:08 polkadot-js-bot

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.

polkadot-js-bot avatar Aug 30 '22 16:08 polkadot-js-bot