# On what block levels within a cycle can roll snapshots happen?

According to this documentation:

Roll snapshots represent the state of rolls for a given block. Roll snapshots are taken every BLOCKS_PER_ROLL_SNAPSHOT = 256 blocks, which is 16 times per cycle. There is a tradeoff between memory consumption and economic efficiency. If roll snapshots are too frequent, they will consume a lot of memory. If they are too rare, strategic participants could purchase many tokens in anticipation of a snapshot and resell them right after.

But this does not say on which levels the snapshots are taken. It's likely that the answer is either `0, 256, ..., 3840` or `256, 512, ..., 4096` but it's not specified which one it is.

It is done at the levels corresponding to the cycle positions `255, 511, ..., 4095`. Given that `cycle_position == (level - 1) % 4096` (the first cycle has started at level 1, genesis being special), the levels are `256, 512, ...`

The relevant code is here:

``````let may_snapshot_roll ctxt =
let level = Alpha_context.Level.current ctxt in
let blocks_per_roll_snapshot = Constants.blocks_per_roll_snapshot ctxt in
if
Compare.Int32.equal
(Int32.rem level.cycle_position blocks_per_roll_snapshot)
(Int32.pred blocks_per_roll_snapshot)
then Alpha_context.Roll.snapshot_rolls ctxt
else return ctxt
``````

So the relevant cycle_position are those `cp` such that `cp % 256 == 255`.

• Don't confuse `level` and `cycle_position` ;) The code actually says `cycle_position % 256 == 255` which is equal to `(level - 1) % 256 == 255` which is equal to `level % 256 == 0`. Nov 27, 2020 at 13:49
• That's because level didn't start at 0 with the first block of a cycle right? Nov 28, 2020 at 16:25
• Oh, I had in mind "relative" levels, relative to the start of the protocol... Indeed, `cycle_position == (level - 1) % 4096` is true for mainnet. I'll update my answer. @ArthurB: right. Nov 28, 2020 at 20:10