Am I fundamentally misunderstanding how staking handles election timings, please? I've been trying to change the number of eras in a session, to increase the number of elections for testing.

I expected that we get a validator election every era, so reducing the sessions per era should increase the frequency of elections. I found and modified this constant, which was originally 6:

pub const SessionsPerEra: sp_staking::SessionIndex = 2; in bin/node/runtime/src/lib.rs

It's showing as changed in storage according to Polkadot.js, but I'm still getting 6 sessions per era anyway? (Chain started from genesis with this setting.)

Image showing staking.sessionsPerEra = 2, staking.currentEra = 5 and session.currentIndex = 28

I've also managed to create another example, where I have 6 sessionsPerEra defined in the code, but the chain is hanging after 2 sessions, with Babe complaining that there is an unexpected change of era. I've been trying 1, 2 or 6 sessions per era, trying to work out what's wrong.

  • Did you fixed it?
    – bkchr
    Feb 23, 2022 at 11:09
  • Yes - I'd built the chainspec when staking.sessionsPerEra was set to 6, and then changed the parameters in the code base and recompiled the substrate binary. The mismatch was causing the error, I think. (It was worse the other way - sessionsPerEra = 2 in the chainspec code block but 6 in the binary seems to cause the chain to hang.) I'm not sure if this is github issue worthy - it might just be covered by the "don't change this on a live chain" comment already in the codebase? Either way, I'll try to update / answer this and/or my other related bug with something helpful for future errors. Feb 23, 2022 at 17:30
  • sessionsPerEra in the chain spec code block? What you mean by this?
    – bkchr
    Feb 23, 2022 at 19:29
  • Well, it might mean that I'm still not fully understanding things. I assumed that constants like stacking.sessionsPerEra are included in the code blob in the "genesis": { "runtime": { "system": { "code: {}}}} in the chainspec that gets encoded as genesis --> runtime --> top when you process the chainspec to raw. However, I guess that doesn't actually make sense - the whole point of them being constant is that they don't need don't need to be read from storage. Feb 23, 2022 at 19:44
  • I'm sure that the problem was a mismatch between the code bloc in the chainspec and the values compiled into the binary though - when I replaced the code blob with an updated one, everything started to work reliably. I'll have to dig into it a bit more - I have the broken files in version control still, I think. Feb 23, 2022 at 19:46

1 Answer 1


If you are updating your runtime, currently you compile it twice for native and for wasm. When both are exactly the same you should use the same spec_version. In your case here, you updated the native runtime, but did not bumped the spec_version. So, the node was thinking that both are compatible, but as this was wrong your chain was running into errors.

These kind of values like SessionsPerEra are also not easily changeable after your chain was launched. So, ensure that you rebuild everything and also have recreated your chain spec.

  • Thanks. I'm building test case chain specs, so they always restart from nothing, rather than building on an existing chain. The process I'm now following when I update something in the runtime is: recompile with cargo build; generate a new empty chain spec with chain-spec-builder generate -c sampleChainSpec.json -a 1 -n 1 -e 1; copy the "code" blob from the empty chainspec to my existing one; raw encode it again with substrate build-spec --chain=chainspec_plain.json --raw > chainspec_raw.json. Does that look sufficient? Is there an easier/better way? Feb 23, 2022 at 21:41

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.