paritytech / json-rpc-interface-spec

30 stars 3 forks source link

How to get `RuntimeVersion` at a specific block height via `archive`-prefixed rpc group? #155

Closed sinzii closed 7 months ago

sinzii commented 7 months ago

I believe RuntimeVersion is something we should obtain first to:

With the chainHead-prefixed group, we can get the runtime version upon receiving initialized & newBlock event after calling chainHead_follow(true). But I didn't see any instruction to obtain the RuntimeVersion in the archive-prefixed group.

Off the top of my head, there is a way to get the runtime version I can think of:

  1. Assume that the runtime supports api Metadata_metadata, and try to make a call: archive_call(hash, 'Metadata_metadata', '0x') to obtain to get the raw metadata.
  2. Decode the raw metadata and get the runtime version from contant: System.Version.

There is a problem with this approach is that the Metadata_metadata always return Metadata V14, and we're gonna need to refetch the metadata again if V15 is supported. And to me, it's kinda hacky and take round-trip to achieve what we want.

I'm not sure if there's other way to obtain the RuntimeVersion first without going through a round-trip. Please shed some light here or let me know if you have any thoughts, thanks!

josepot commented 7 months ago

I think that this is what you are after: https://github.com/paritytech/json-rpc-interface-spec/issues/119 and https://github.com/paritytech/json-rpc-interface-spec/issues/108

sinzii commented 7 months ago

@josepot Thank you for the suggestion, I still need to digest this.

What I after is a straight forward way to obtain RuntimeVersion at a specific block hash/height, or somewhat similar to what we achieve it via the chainHead-prefixed OR with the legacy JSON RPC, we can call state_getRuntimeVersion(hash) to get it.

From what you suggest, we can certainly detect if there's runtime upgrade between 2 blocks, but the question stil persists as how do we get the runtime version in the past if we know there's changes. I didn't see the runtime version is storing somewhere in the chain storage. There is a way we can get it via the Metadata_metadata api, but if at that specific block hash, the runtime supports V15, then we're gonna need to refetch the metadata again via Metadata_metadata_at_version(15).

This is what I understand so far, I might total miss understand something here. Could you elaborate more on that? I'd appreciate it. 🙏🏻

sinzii commented 7 months ago

Oh, I just found a different way to get the RuntimeVersion at a specific block hash is to call: archive_call(hash, 'Core_version', '0x'). We're gonna get the scale-coded runtime version at the particular block hash, what left to do is to decode it to plain values.

If this what we intend to do it in the first place, I'm fine with it! Though there a small issue is that we need to assume that all runtime version within a chain or in other chains can be encode/decode in the same way defined here. So in the future, if there any changes in its structure could potentially break it.

sinzii commented 7 months ago

I'm closing this for now as I found what I need, but if you have any other thoughts, please share it. Thanks!