I modified the template pallet from the substrate node template 681a9d8e3e8becf99aabf1cc76e1c08016db2e1a to contain a storage version:

const STORAGE_VERSION: StorageVersion = StorageVersion::new(123);

// -- snip --

#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);

Then I wrote the following test:

fn storage_version_is_correct() {
    new_test_ext().execute_with(|| {
        assert_eq!(<Pallet<Test> as GetStorageVersion>::current_storage_version(), 123);
        assert_eq!(<Pallet<Test> as GetStorageVersion>::on_chain_storage_version(), 123);
        assert_eq!(StorageVersion::get::<Pallet<Test>>(), 123);

The first assert_eq! succeeds, the other two fail. Is this expected behavior? I would have expected the storage version of the pallet to be written to storage at genesis. If this is expected behavior, why is this the case?

I expanded lib.rs and found the following snippet:

impl<T: Config> frame_support::traits::OnGenesis for Pallet<T> {
    fn on_genesis() {
        let storage_version = STORAGE_VERSION;

So it appears that the storage version is supposed to be written to the on-chain storage on genesis, right? Why didn't it happen in this case?


2 Answers 2


The following patch will make it work:

diff --git a/pallets/template/src/tests.rs b/pallets/template/src/tests.rs
index 550ffad..6ca03f1 100644
--- a/pallets/template/src/tests.rs
+++ b/pallets/template/src/tests.rs
@@ -3,7 +3,7 @@ use frame_support::{
        assert_noop, assert_ok,
-       traits::{GetStorageVersion, StorageVersion},
+       traits::{GetStorageVersion, StorageVersion, OnGenesis},
@@ -27,6 +27,7 @@ fn correct_error_for_none_value() {
 fn storage_version_is_correct() {
        new_test_ext().execute_with(|| {
+        Pallet::<Test>::on_genesis();
                        storage_prefix(<Pallet<Test>>::name().as_bytes(), b":__STORAGE_VERSION__:")

The problem here being that on_genesis is not being called magically and you don't call it in your code anywhere. StorageVersion defaults to 0 when it is not present in the storage.

Normally on_genesis being called as part of the runtime GenesisConfig. Here you see the code that is being generated that will then call this method.

When you want to test migrations, I would just put the expected StorageVersion into the storage, before calling the migration code.

  • Thanks! So even when I'm using a dev node, on_genesis is not called?
    – mkl
    Commented Jun 15, 2022 at 14:22
  • On a dev node it is called. If you mean by dev node that you have run a node with --dev
    – bkchr
    Commented Jun 15, 2022 at 18:10
  • Yeah, that's what I meant. Got it, thanks!
    – mkl
    Commented Jun 16, 2022 at 9:59
  1. on_chain_storage_version is the version number saved in the DB.
  2. And the current_storage_version's real meaning is the number which is annotated in the pallet's pallet::storage_version macro.
  • Yeah, I know both of these things. Sorry to be so blunt, but this doesn't answer my question at all: "Is this expected behavior? I would have expected the storage version of the pallet to be written to storage at genesis. If this is expected behavior, why is this the case?"
    – mkl
    Commented Jun 10, 2022 at 6:26
  • "I would have expected the storage version of the pallet to be written to storage at genesis. " --- It's not work that way, storage version number in pallet::storage_version macro is just a mark, won't affect the real storage version in DB. Commented Jun 10, 2022 at 8:28
  • Okay, but why? If I start a development node after my chain has had a couple of storage migrations, this means that the development node that the incorrect storage version. This makes testing future storage migrations rather annoying. I don't see the reason for this.
    – mkl
    Commented Jun 10, 2022 at 9:52
  • Also, I've edited the question. It seems like specified storage version does get put into on-chain storage at genesis.
    – mkl
    Commented Jun 10, 2022 at 9:53
  • 1
    I think your assumption is not proper. You can check this test case: github.com/paritytech/substrate/blob/… Commented Jun 13, 2022 at 2:39

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.