2

This question is somewhat similar to this question about configuring for testing but it is for an already live chain.

In this scenario a new pallet will be added to an existing chain's runtime. The storage would need to be pre-filled with values - for example a list of AccountIds so that when the chain is upgraded the storage will already be populated.

Prior to genesis, this would be carried out by setting the storage:

    #[pallet::genesis_config]
    pub struct GenesisConfig<T: Config> {
        pub some_accounts: Vec<T::AccountId>,
    }

This would then in turn allow you to configure the chain-spec.json to include a list of those accounts and when the chain launches for the first time it includes this information.

"pallet": {
        "someAccounts": [
            "5DscB8vToteyG9w3KPpmVti6SrsDttd9MjDFqWA8kGoicPpi",
            "5CAmNGhvuFcyL2fUpewQR8PJ3LSmhcarkPntyR77zCGTQoMN",
            "5GZ9KwDiFGgnVAVThYpHwtttzKZefxb74TMsc19qrAATU55A",
        ]
      }

However, once the chain has already launched, the chain spec file can no longer be updated without in effect creating a new chain, I think.

If this is the case what is the method for creating a new pallet with pre-filled storage, without changing the original spec file?

Perhaps this is a misunderstand about the spec file, but it would be helpful to clarify this case.

1 Answer 1

1

The chainspec cannot be updated, that's right. The storage in the chainspec only specifies the contents of the block 0, the genesis block. That in turns, gives the common starting point for all clients to sync the chain. Anyone working (syncing/block producing) with a different genesis block will be on a different chain.

There is no canonical way to solve this problem. You will have to get the new storage into the state machine somehow.

One option is to do it through extrinsics: you engineer your upgrade to be performed in stages. The first stage would be updating the runtime code. The second stage would be getting the storage in via the extrinsics.

The second option, is to embed the data into the new runtime wasm code and perform the storage population in the first block. This approach is similar to a runtime storage migration. The limitation is that there is not so much storage you can pass into the state machine like that. An upgrade should go through a block in one or another, and the limit is ≈ 4 MiB by default for a standalone Substrate chain. For Cumulus/Polkadot it will be even smaller due to the overhead that comes with PoV.

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.