2

Goal

To use a full snapshot at some block height of one chain and selectively pull in select parts of this state.

Use cases

  1. Migrating state from another chain. Example:

    • A snapshot of only assets pallet on some other chain
  2. Partial or complete snapshot recovery. Example:

    • A sudo state change bricked a chain, and a new one is started that wants to restart (with a new genesis) with much the same state overall, but not the corrupt parts.

Known tools

Question

How would one perform a selective state "upload" of parts of some full chain state data?

I think fork-off-substrate may have parts of the solution, but the selectivity and how to go about actually identifying the state to use is unclear. Also this would not necessarily be performed at genesis, and may need to be piece-wise for the limitations on parachains (as outlined here in the parachain runtime upgrade How-to Guides)

1 Answer 1

1

If you read the code for fork-off-substrate, you will see that it ultimately collects a list of "module prefixes", and then queries storage using that list.

Right now it collects a list of prefixes to skip:

/**
 * All module prefixes except those mentioned in the skippedModulesPrefix will be added to this by the script.
 * If you want to add any past module or part of a skipped module, add the prefix here manually.
 *
 * Any storage value’s hex can be logged via console.log(api.query.<module>.<call>.key([...opt params])),
 * e.g. console.log(api.query.timestamp.now.key()).
 *
 * If you want a map/doublemap key prefix, you can do it via .keyPrefix(),
 * e.g. console.log(api.query.system.account.keyPrefix()).
 *
 * For module hashing, do it via xxhashAsHex,
 * e.g. console.log(xxhashAsHex('System', 128)).
 */
let prefixes = ['0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9' /* System.Account */];
const skippedModulesPrefix = ['System', 'Session', 'Babe', 'Grandpa', 'GrandpaFinality', 'FinalityTracker', 'Authorship'];

But your question seems to want the opposite, which is just the storage specific pallet, ignoring the rest.

For that, you just need to query the keys which start with the prefix you expect.

Starting from first principles, do something like:

let prefix = xxhashAsHex(module.name, 128)
let allStorageKeys = api.rpc.state.getKeys(prefix);
let allStorage = api.rpc.state.queryStorageAt(allStorageKeys);

And then you insert these keys / values into your new chain.

Your Answer

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

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