KiChain: How to perform a chain upgrade with genesis parameter update.
Welcome to the Ki-steps series, a sequence of how-to posts where we explain the detailed steps to perform more or less advanced tasks on the KiChain. In this first post, we will tackle the chain upgrade procedure. Upgrading a chain allows the operators to update their chain configurations or to integrate breaking code changes to it while maintaining its state.
A couple of weeks after launching our first testnet KiChain-t-0, we performed a chain upgrade and launched KiChain-t-1 a.k.a. Kazeki (which you can join by following these steps. Here is why you should!). Hereafter we detail the steps that the KiChain node operators followed to achieve a smooth and secure switch to the new testnet.
ℹ️ To keep this post as informational as possible and since this process is similar to some other cosmos based chains, I will try to keep the steps and their explanations as generic as possible while instantiating them to our use case.
⚠️ This process has already been completed for the KiChain and this post is only for informational purposes. New validators must not perform this procedure anymore.
🗳️ Prepare the upgrade
Before jumping into the practical steps of the upgrade it is important to make some decisions and set some specs for the upgrade. These decisions and specs are made through a proposal submission and a voting process. They concern the following aspects:
- Halt block height: The block height at which the chain should be halted.
- Upgrade window: The time window during which the update needs to be performed and after which the upgraded chain is launched.
- Upgrade success height and window: The minimum height that should be reached in the given time window to confirm the success of the upgrade.
- The new configuration/code base: the changements which are the subject of the upgrade.
Our upgrade was performed at height 125340 during 60 minutes. The success of the upgrade was confirmed when the height 2 was reached (within a window of 1 hour).
🛑 Stop the node
First you will need to stop the node before starting the upgrade process. Depending on how you’ve launched your node (screen, background, … ), this step might change. In general, it suffices to kill the
kid process either using the
ctrl+c shortcut or using the command
💾 Backup your old chain data
Problems should not occur during the upgrade process. But they definitely might. In order to be able to fall back to the old chain, it is important to backup its data. To do so, backup your node folder (e.g., copy it). The node folder is the one that contains the
kicli/ mainly (and the
kilogs/ folder if you’ve followed this tutorial to launch your node). If you’ve setup and launched your node without the
--home command, then backup the default
It is critically important to back-up the
kid/data/priv_validator_state.json file after stopping your
kid process. It is needed to prevent double-signing in case the upgrade fails and the previous chain needs to be restarted.
Tech Tip :
priv_validator_state.jsonkeeps track of your validator validation history. It is updated with the last height, round, step and a signature, every time your validator participates in a consensus round.
📦 Export your old chain state
Once the data are safely stored, export the state of the chain at the halt height as follows:
$ kid export — for-zero-height — height=125340 — home [your_node_home]/kid > KiChain-t-0_genesis_export.json
Then verify the
SHA256 of the (sorted) exported genesis file:
$ jq -S -c -M '' KiChain-t-0_genesis_export.json | shasum -a 256
The previous command will yield a hash of the exported state file. Verify it against the hashes produced by the fellow validators on a common channel (we used our slack which you can join here). This validation ensures all validators are starting with the exact same version of the genesis. If the hashes match, proceed with the following steps. Otherwise, ensure that you are exporting the state of the correct blockchain (in case you have multiple nodes running on the same server) and that you are using a sorted version of your genesis.
⚙️ Generate the new genesis file
Now that the old state is exported and verified, we will modify the exported file to produce the genesis file of the new chain. Three things need to be changed in this step:
- genesis_time : as the new chain will start 60 minutes after halting the old chain, the genesis time should be computed relative to the blocktime of the halt height i.e., 125340. To find the new genesis time, fetch the blocktime of height 125340 and add 60 minutes to it with the subseconds truncated. An example shell command to compute this value by fetching the block time from a running node is:
curl http://xx.xx.xx.xx:26657/block?height=125340 | date -d " $(jq -r '.result["block_meta"]["header"]["time"]') +60 minutes" + "%Y-%m-%dT%H:%M:%SZ"
curl http://xx.xx.xx.xx:26657/block?height=125340 | jq -r '.result["block_meta"]["header"]["time"]'|xargs -0 date -v +60M -j -f "% Y-%m-%dT%H:%M:%S" +"%Y-%m-%dT%H:%M:%SZ"
Or without using the API endpoint by manually entering the halt block time:
date -d "[Halt block time] +60 minutes" +"%Y-%m-%dT%H:%M:%SZ"
- Chain_id: The chain id of the upgraded chain. In our case we passed from KiChain-t-0 to KiChain-t-1
- Chain parameters: update the other predetermined (step 1) parameters to their new values.
⚠️ Some genesis parameters in the exported state are automatically computed (e.g., inflation, annual_provision, …). Changing them might induce an inconsistency in the genesis file. One needs to be careful if they decide to upgrade them.
Change the name of the updated genesis file to genesis.json and verify its
$ jq -S -c -M '' genesis.json | shasum -a 256
The previous command will yield a hash of the exported state file. Verify it against the hashes produced by the fellow validators. If the hashes match, proceed with the following steps. If your hash doesn't match the other hashes, make sure you are using a sorted version of your file, ensure that the genesis time you've computed on your side (after truncation) is equal to what the other validators computed, and verify all the other manually made parameter changes.
☠️ Reset the node
Be sure you have a complete backed up state of your node (as explained earlier in the document) before proceeding with this step.
$ kid unsafe-reset-all --home [Your node home]/kid/
Move the new genesis.json to your
🚀 Start the node
The moment has come ! your node is now ready to be launched. Wait for the end of the upgrade window and launch your node as you are used to do with:
kid start --home [Your node home]/kid/
In the next post we will tackle the multi-signatures and explain how to setup a multisig account and how to send multi signed transactions on the KiChain.