# How to upgrade a system parachain runtime in a local network and stay sane ## Pre-requisites This guide assumes: * You have started a zombienet or other type of local network; * Your relay chain is producing blocks; * Your parachain has been onboarded and is producing blocks as well; * You know your parachain ID; * You possess credentials to submit `sudo` calls on the relay chain; * You prepared a new runtime binary you want to upgrade to. This guide refers to it as `new_runtime.wasm`. The actual name could be, e.g., `asset_hub_rococo_runtime.compact.compressed.wasm`. ## Preparation Open two separate polkadot.js instances in your browser: one at a relay chain validator and one at a parachain collator. They will be called the "relay chain side" and "parachain side", respectively. In case your relay chain runtime and parachain runtime were built with different versions of Polkadot SDK, they may have different default XCM versions and thus will not be able to communicate. If that's the case, from the relay chain side, issue a `sudo` call for `xcmPallet.forceXcmVersion`, specifying your parachain ID as a destination and parachain's preferred XCM version. Version 3 is the common ground at the time of writing. After doing so, make sure to only use XCM messages of the corresponding version in the following steps. ![immagine](https://hackmd.io/_uploads/BJVIr1bip.png) ## Upgrade process ### Encode the call On the parachain side, go to Developer → Extrinsics and select the `parachainSystem.authorizeUpgrade` extrinsic. In the `codeHash` field, select "hash a file" and provide your `new_runtime.wasm`. In the `checkVersion` field, choose whether you want your parachain checked for spec name equivalence and spec version increase during the upgrade. Do not submit that extrinsic! It's for call encoding only. Under "encoded call data", press the "copy" button to copy the encoded call to the clipboard. ![immagine](https://hackmd.io/_uploads/BJ6yLkbi6.png) ### Submit an XCM message to authorize the upgrade On the relay chain side, navigate to Developer → Sudo and choose the `xcmPallet.send` call. > NB: The following instructions are for XCM v3. Other versions of XCM may have different message semantics. In the `dest` section, set the version to `V3` and the `interior` to `X1`. Then, under `X1` junction, choose `Parachain` and specify your parachain ID. In the `message` section, set the version to `V3` as well. Add an item and select `Unpaid execution` instruction. Leave `weightLimit` with its default value `Unlimited`, and `checkOrigin` with `None`. Add one more item and choose the `Transact` instruction. Under `originKind`, choose `Superuser`. Under `requireWeightAtMost`, set `refTime` to `1000000000` and `proofSize` to `1000`. > **TODO: We could use some explanation of those magical weight values instead of encouraging users to specify them mindlessly.** Finally, at the `call` field, paste the encoded call you copied to the clipboard in the previous section. ![immagine](https://hackmd.io/_uploads/HkaC4kWi6.png) Now submit the `sudo`. After getting "in block" status, switch to the parachain side and watch events under Network → Explorer. After the next block is imported, you should see `parachainSystem.DownwardMessageReceived` and `parachainSystem.DownwardMessageProcessed` events. One block later, you should get `messageQueue.Processed` event, where `success` field is `Yes`. ![immagine](https://hackmd.io/_uploads/S1oBIkbja.png) #### Troubleshooting at this step * No events on the parachain side: check that the XCM address, including the parachain ID, is correct. * `messageQueue.ProcessingFailed`, with the `error` field being `Corrupt`: XCM version mismatch. Refer to this guide's [Preparation](#Preparation) section to set the correct XCM version. * `messageQueue.OverweightEnqueued`: the weight constants you submitted in the last step are too high; try halving them. * `messageQueue.Processed` received, but the `success` field is `No`: the weight constants you submitted in the last step are too low; try doubling them. ## Request the upgrade encation On the parachain side, navigate to Developer → Extrinsics and prepare a `parachainSystem.enactAuthorizedUpgrade` extrinsic. In the `code` field, check "file upload" and upload your `new_runtime.wasm`. ![immagine](https://hackmd.io/_uploads/r1isXMZjT.png) Then submit that extrinsic unsigned. However, if it fails for some reason, try to submit it signed. ## Wait for the enaction After the enaction is requested, validators will pre-check the PVF, which will be enacted on chain after some period. It may vary from 2 blocks in local development networks to 100 blocks in production networks. Refer to the `validationUpgradeDelay` and `minimumValidationUpgradeDelay` constants of the active parachain host configuration available under Developer → Chain state → `configuration.activeConfig()`.