Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Use Mandatory Indices for FRAME Storage API (and others) #8964

@shawntabrizi

Description

@shawntabrizi

The FRAME storage APIs use a combination of prefixes to describe the location of storage items. Something like:

hash(pallet_name) + hash(storage_name) + hash(key_value) + ...

We have seen multiple times where this has come to bite us in the butt:

  • Recent migrations from frame v1 -> v2 where we changed the string used for the hasher
  • Any changes to the name of a storage item (typos, better clarification, etc....)

Similarly, we ran into issues with Construct Runtime and the ordering of pallets, and the call enum and ordering of extrinsics.

My suggestion is that we should use indexes, not human strings / variable names, wherever there could be some breaking change caused by reorganization, renaming, refactoring, etc...

Protobuf follows a similar philosophy: https://developers.google.com/protocol-buffers/docs/overview

I believe the following FRAME objects should use explicitly defined indexes:

  1. Pallets in Construct Runtime
  2. Calls in Pallet
  3. Storage in Pallet

Items which are not breaking need not have explicit ordering, but should allow optional explicit ordering:

  • Errors in Pallet
  • Events in Pallet

When defining a storage item with the FRAME v2 macros, users should be required(?) to include an explicit index:

#[pallet::storage]
#[pallet::storage::index(0)]  <-- this
#[pallet::getter(fn auction_counter)]
pub type AuctionCounter<T> = StorageValue<_, AuctionIndex, ValueQuery>;

We already support and require indices on Pallet ordering in construct runtime. This is needed for transaction versioning.

Combining these two, the new storage pattern should be:

hash(pallet_index) + hash(storage_index) + hash(key_value) + ...

In this case, we can update the name of the storage or move the storage definition to anywhere in the source code, and not break your pallet.

We still want to hash these indices so that pallet storage is in its own trie branch.

We have also wanted to put all pallet storage into its own child trie, so maybe we should do that here too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions