polkadot-js / apps

Basic Polkadot/Substrate UI for interacting with a Polkadot and Substrate node. This is the main user-facing application, allowing access to all features available on Substrate chains.
https://dotapps.io
Apache License 2.0
1.75k stars 1.55k forks source link

Cannot update assets.metadata.multi(indexes) #6874

Open MiZiet opened 2 years ago

MiZiet commented 2 years ago

Polkadot collator v5.1.0 api v7.5.1 apps v0.103.1

Hi, I'm having a problem with creating new assets on locally hosted Westmint:

After creating a new asset and adding it's ID to indexes in (api.query.assets.metadata.multi(indexes) (in useAssets hook) the new asset's metadata is not updated. After reloading the app it's there. Are there any problems with observing multi queries?
image

jacogr commented 2 years ago

All I can think of is that the multi call doesn’t correctly check for the params change?

Alternatively could be that the ids are not properly extracted - https://github.com/polkadot-js/apps/blob/master/packages/page-assets/src/useAssetIds.ts#L17

krzysztof-jelski commented 2 years ago

After playing with api a bit, my theory is:

So .multi(keys) gets keys which include the new asset id, but they don't return any data for it. Apparently, multi does not refresh data underlying the new key when it shows up in a finalized block.

I'm probably getting the block lifecycle wrong here. I guess it's more to it than "new head" => "finalized". But anyway, either we need some change of behaviour in events (please wait for block to be attached/finalized) or multi (please refresh for all ids).

jacogr commented 2 years ago

So I played a bit and on non-parachain nodes, no issues. Aka run with substate --dev and no such issues.

The fact that it doesn't work as parachains as reported here, seems very suspicious. (We had something similar that was fixed in Substrate where the subscriptions to current code was not working on parachains, but working on stand-alone nodes in the last couple of months, e.g. upgrades were not detected)

We don't want to change this to finalized.

krzysztof-jelski commented 2 years ago

To be fair, we tested it on local machine setup only (but a proper relay chain + parachain, started with polkadot-launch). We might give it a try on Westmint tomorrow.

jacogr commented 2 years ago

I only tested it on a local machine as well - but without collators. In that case the logic does work, so for some reason in the parachain case the state is not available on the hash - which, well, it not great... and if that is the case points to a non-apps issue.

jacogr commented 2 years ago

What I would suggest -

  1. log the blockHash in useAssetIds
  2. check the block in the explorer to see that the events are indeed there
  3. do a manual query for the keys as well as metadata (at the block)

See if either of those doesn't yield the expected results.

Another thing to try - add the MetadataUpdated (cannot recall the exact name) to the useAssetIds even check - it may be that the transactions are split across blocks? (although the multi should pick that up)

It is weird thinking about it - if the id does show, the multi query for the meta must update when something is found.

MiZiet commented 2 years ago

Hi @jacogr, i'm trying to create an observable that will return all assets with metadata but I don't know how to access api.events from DeriveApi. https://github.com/polkadot-js/api/pull/4509/files#:~:text=const%20checks%20%3D%20%5Bapi.events.assets.Created%2C%20api.events.assets.Destroyed%5D%3B Do you know how to create that checks array?

jacogr commented 2 years ago

Closest would be crowdloans - https://github.com/polkadot-js/api/blob/master/packages/api-derive/src/crowdloan/contributions.ts#L30

jacogr commented 2 years ago

Marking it as Substrate-related. Refer to the linked Substrate issue that links through to this one (just above this comment), basically there is an implementation issue with the way storage changes are pushed through. It needs some thinking and hands-on-a-keyboard to fix.

jacogr commented 2 years ago

Can you please give this a run-through to see if the issue persist? https://github.com/polkadot-js/apps/pull/7131

Basically it now follows the apporoach we have in crowdloans where it uses the events to add/remove ids. This basically means that any trigger on an id will update the id array, despite the block not finalized.

This basically means we work around the Substrate head/best-block item highlighted above (as a bonus it is also lighter in terms of RPCs in terms of full refreshes, which is only done right at the start)