Background
As the number of runtime upgrades keeps stacking up on mainnet, and there is an evolution in the metaprotocol layers itself, it will become an increasingly complex exercise to synching a fresh QN from gensis to current tip. This happens every time someone new joins the ecosystem with their own QN instance. Likewise, there is also a need for people currently running a QN to keep it up to date with the most recent runtime upgrade. This means one needs
- A way for QNs to gracefully stop when someone is running a node while an upgrade happens where runtime has changes that QN is not compatible.
- A way to synch a QN across a large number of runtime upgrades, possibly applying bespoke migrations on each upgrade.
Ideally, this should happen in a way that also would work when we start using Subsquid, and it does not require forking Subsquid, or making substantial changes that are either unlikely to me accepted, or maintained. It is also very valuable to keep the complexity of the QN itself relatively managable, so it does not require even complex context in order to maintain.
Proposal
Find some way to address 1 & 2.
Checking what the Subsquid team does natively in terms of upgrades is also probably wise.
One idea
I will suggest one approach to 2 here, but there are probably other ideas worth considering also. Introduce a new harness that sits around the QN, which is able to know how to properly synch the QN across these upgrades, in a way similar to how we were already doing it manually for a single upgrade on testnet. So this harness would be the primary entry point for actually running the QN, and it would read a synch specification file, which would describe the following: a sequence of disjoint block intervals, the last of which having no ending block, which covered the full block space, which for each interval would have a distinct manifest+mapping+schema file+migration script that would be executed during synching. So something like this
- [0, end_block_1]: manifest+mapping+schema file+migration script
- [end_block_1 + 1, end_block_2]: manifest+mapping+schema file+migration script
...
N. [/* rest of time block /*]: manifest+mapping+schema file
The harness would start and stop the processor in accordance with this sequence of specifications, and run the associated migration script between each segment.
If someone now is running a node with this setup, and there is an upgrade, the harness would stop the QN (unless explicitly told not), and then operator would just need to update QN, which would include a new synch specification that would describe what to do with the upcoming upgrade.
The simplest solution
If there is no great solution, or the best solution depends on using Subsquid or some other fix which is further into the future, we could do as follows: ship all QN versions with an initial db state, and then have it only synch from some non-gensis block which aligns with its current mappings. Worst case, just doing that would work for the forseeable future, it just causes some unfortunate barrier for someone to verify the truth about current system state from scratch if they wanted to.
┆Issue is synchronized with this Asana task by Unito
Background
As the number of runtime upgrades keeps stacking up on mainnet, and there is an evolution in the metaprotocol layers itself, it will become an increasingly complex exercise to synching a fresh QN from gensis to current tip. This happens every time someone new joins the ecosystem with their own QN instance. Likewise, there is also a need for people currently running a QN to keep it up to date with the most recent runtime upgrade. This means one needs
Ideally, this should happen in a way that also would work when we start using Subsquid, and it does not require forking Subsquid, or making substantial changes that are either unlikely to me accepted, or maintained. It is also very valuable to keep the complexity of the QN itself relatively managable, so it does not require even complex context in order to maintain.
Proposal
Find some way to address 1 & 2.
Checking what the Subsquid team does natively in terms of upgrades is also probably wise.
One idea
I will suggest one approach to 2 here, but there are probably other ideas worth considering also. Introduce a new harness that sits around the QN, which is able to know how to properly synch the QN across these upgrades, in a way similar to how we were already doing it manually for a single upgrade on testnet. So this harness would be the primary entry point for actually running the QN, and it would read a synch specification file, which would describe the following: a sequence of disjoint block intervals, the last of which having no ending block, which covered the full block space, which for each interval would have a distinct manifest+mapping+schema file+migration script that would be executed during synching. So something like this
...
N. [/* rest of time block /*]: manifest+mapping+schema file
The harness would start and stop the processor in accordance with this sequence of specifications, and run the associated migration script between each segment.
If someone now is running a node with this setup, and there is an upgrade, the harness would stop the QN (unless explicitly told not), and then operator would just need to update QN, which would include a new synch specification that would describe what to do with the upcoming upgrade.
The simplest solution
If there is no great solution, or the best solution depends on using Subsquid or some other fix which is further into the future, we could do as follows: ship all QN versions with an initial db state, and then have it only synch from some non-gensis block which aligns with its current mappings. Worst case, just doing that would work for the forseeable future, it just causes some unfortunate barrier for someone to verify the truth about current system state from scratch if they wanted to.
┆Issue is synchronized with this Asana task by Unito