Skip to content
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

Properly handle the change of data structure that shared by both the client and the runtime #2942

Open
NingLin-P opened this issue Jul 24, 2024 · 0 comments

Comments

@NingLin-P
Copy link
Member

There are some data structures passing between the client and the runtime through runtime API, the most important of these are:

  • Fraud proof: generate/submit from the client to the runtime
  • Bundle and ER: generate/submit from the client to the runtime and later extract from the runtime state to the client

Usually, after we changed the data structure in the codebase, the client release/upgrade will happen more frequent than the runtime, meaning the client will using the newer version of the data structure while the runtime use the older, as a result the client will failed at the runtime API call due to codec error which will cause the domain node shut down.

There are 2 examples of the data structure change in gemini-3h:

For fraud proof, there is only one direction from the client to the runtime and FP is expected to be rare, so it is relately easy to handled by:

  1. Keep FP encode as the old version structure (i.e. keep the removed field as it is or skip encode the new added field)
  2. Runtime upgrade to bring the new version structure to runtime
  3. Make a new client release to complately update the FP to the new version

But for bundle/ER is more tricky because the client also extract (decode) them from the consensus chain, and the consensus chain is stateful, e.g. if the runtime is upgraded at block #N to use the new version structure, before #N the client need to decode the bundle/ER as the old version and after #N decode as the new version. This is more critical for ER, because ER is stored at the local aux storage and the ER is used to detect fraud, we need to ensure all the honest domain node will derive a exact same ER for a given domain block regardless of they may running on different releases, that is better to let the domain node crach than derive a different ER (e.g. by silently skip decoding a new added field), otherwise the operator may:

  • Get slash due to submitted a different ER
  • Can't submit bundle due to parent ER not found (because different ER derive different ER hash)
  • Keep generating/submitting bad FP

The ideal solution I image is to versioning these shared data structure:

  • The client should be able to encode/decode all the older version of the data structure
  • The runtime only accept its current version of the data structure
  • The client should ensure its current version is >= the runtime's, otherwise the node should crash and the user should upgrade to a newer release with the latest version
  • The client encode/decode the data structure as the same version of the runtime (at a specific block)

cc @nazar-pc @vedhavyas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant