Version pallet-revive storage types#11990
Open
0xOmarA wants to merge 29 commits into
Open
Conversation
Added a wrapper for all storage keys and values which will be used to have separation between the storage types and the execution types while trying our best to keep the "illusion" that what's stored in storage is the execution type. We try to balance this out to make sure that this illusion is maintained so long as it's not hurtful for it to be maintained and revealed only when its needed.
Previously, there was no way for us, in the type-system, to determine what types were being used in storage. This commit introduces simple traits and some simple "type-system functions" which answer questions like "given this StorageValue type, what's the actual value being used here".
This commit adds the very first usage of versioned storage for the `DebugSettings` type.
This commit adds an `encode_like` attribute to the define_versioned_type macro which allows us to automatically derive `EncodeLike` for the types we define. This is useful to get us to minimize some of the changes we're making as we version the storage types so that some call-sites do not need to be modified.
This commit adds tests to ensure that the new storage types added in #11956 do encode and decode in the same way as the previous types which we used to use for storage.
Contributor
Author
|
/cmd prdoc --audience runtime_dev --bump minor |
This is a change which is motivated by the fact that the various macros used by pallets create a `storage_types` module whose name conflicted with the existing `storage_types` alias we had been using. This commit just makes a simple rename from `storage_types` into `revive_storage_types`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This pull request is part of the pallet-revive versioning effort described in #11923 and closes #11943.
This PR builds on top of the versioned-types work. It does not introduce the
pallet-revive-typescrate or the versioning proc macros. Instead, it starts using that infrastructure to separate pallet-revive execution types from the types encoded into storage.The main change is the introduction and adoption of
StorageCodecWrapper<ExecutionType, StorageType>. The wrapper lets pallet-revive continue operating on execution-facing types while delegating SCALE encoding, decoding, metadata, and encoded-size behavior to explicit storage-facing types.This PR also:
#[versioned_type(encode_like = "...")]helper to the existing versioned type macro.The goal is to make the storage boundary explicit without changing the existing storage wire layout.
Integration
Downstream projects should not need a storage migration for existing pallet-revive data as a result of this PR. The storage declarations now use wrapped versioned storage models, but the encoded bytes are intended to remain compatible with the pre-versioning layout.
Code that directly imports pallet-revive internals may need to account for
StorageCodecWrapperat storage boundaries. Most pallet execution code should continue to work with the execution-facing values exposed by the wrapper throughDeref,as_inner,into_inner, conversions, and mutation helpers.Important
The intended integration behavior is that storage bytes do not change. The added tests compare the new versioned storage models against pre-versioning metadata and also compare full current
Revivestorage metadata against the old metadata fixture.Note
This PR is one step toward the final versioning model. Some execution-facing types still need codec implementations because they are still used at runtime API or other boundary surfaces. The direction is to keep moving those codec responsibilities to explicit boundary types.
Review Notes
StorageCodecWrapper<ExecutionType, StorageType>is the storage-boundary adapter added by this PR. It stores both representations:inneris the value pallet code works with.codableis the cached storage representation used for SCALE encoding,MaxEncodedLen, andTypeInfo. This type sits exactly at the boundary seen in the diagram below:The wrapper keeps both values synchronized by requiring mutations to go through
mutateortry_mutate. Those methods update the execution value and then refresh the cached storage value by converting the execution type into the storage type.Warning
StorageCodecWrapperis intended for storage boundaries only. It should not become a general-purpose execution wrapper; its job is specifically to make one type encode and decode as another type.The storage declarations in pallet-revive now use the wrapper for storage items that need explicit storage models. For example, execution code can still work with types like
CodeInfo<T>, while storage metadata and encoding are driven bystorage_types::CodeInfoV2<...>.The
encode_likemacro addition exists because several new storage models intentionally preserve the old byte representation of existing source types. The macro emitscodec::EncodeLike<Target>impls for the listed source types, so existing FRAME storage APIs can continue accepting byte-compatible values without forcing call sites to manually construct the storage model first.Tip
Review
StorageCodecWrapperfirst, then review how each pallet storage declaration uses it. That is the core mechanism for separating execution-facing and storage-facing types.Tests
The tests in this PR protect against accidentally changing the SCALE bytes used for existing pallet-revive storage while introducing versioned storage models and storage wrappers. If these tests pass, they prove that the new storage-facing types and the current runtime storage metadata remain compatible with the pre-storage-versioning layout that existing chains and off-chain clients expect.
pallet-revive-typestests compare individual new storage types against old metadata-generated types and assert cross-decode/identical encoding behavior.revive-dev-runtimetests compare the full currentRevivestorage metadata against a checked-in pre-storage-versioning fixture by SCALE wire layout.Tip
The storage compatibility tests are the main guardrail for this PR. They are intended to make wrapper adoption safe by proving that the new storage models still match the old SCALE layout.