Slot duration up to now is more a constant variable that should not be changed after genesis. However, there
are requests to change this, because it was for example configured incorrectly or the chain wants to build
blocks faster or slower. To achieve this, we will need to write some custom migration to support this. At
time of writing this "guide", it will assume we are talking about a Parachain that uses AURA as block
authoring implementation.
When migrating the slot duration we change the way the slot is calculated. A slot is basically caculated
by taking the current time and dividing it by the slot duration. Let's assume the time is 10
and our
slot duration is 5
, so we are at slot 2
. If you change the slot duration to 2
(aka decreasing the time between)
blocks, the slot is 5
. When increasing the slot duration to 10
, the slot will be 1
.
When a node imports blocks, it checks that the slot in the header to import block is not too far in the future.
This is simply done by checking that current_slot + 1 <= header_slot
. As long as the node can handle the
switch between two different slot durations transparently, the client side shouldn't be any problem. On the runtime
side there are also checks that ensure that the slots are always increasing. If we take our example from above
with switching from 5s
to 10s
, the slot would actually not be increased (2
-> 1
). This would lead to the runtime
rejecting blocks that are being build with the new slot duration.
To make the migration possible, it will require some changes on the node side and some on the runtime side.
Let's start with the node side. These changes should be fairly straight forward. In the service instantiation
there is somewhere the following relative similar code:
Here we have this raw_slot_duration
. We would need to change this when we enact the change of the slot duration.
This can be achieved by checking the spec_version
for example of the block we will be building on to see if this
is the block that enacted the change of the slot duration. This should look similar to:
This should ensure that we use the correct slot duration, depending on spec_version
.
On the runtime side we are checking that the slot are increasing, so we need to ensure that
when we switch the slot duration and the slot decreases, we still can build blocks. This check can
be found here: https://github.com/paritytech/substrate/blob/22ed351d86b3b04ca1df82fb0036c6376bf1fea0/frame/aura/src/lib.rs#L92
So, we would need a migration on the runtime that sets CurrentSlot
to the correct value.
The migration could look like:
As runtime migrations are executed before any other logic is executed, we can ensure that
the moment we hit the mentioned check above the slot is already corrected.