# Install opengov-cli ```shell cargo install --locked --force --git https://github.com/joepetrowski/opengov-cli opengov-cli ``` Note: if you already have opengov-cli installed you'll need to update to get the changes from [opengov-cli#34](https://github.com/joepetrowski/opengov-cli/pull/34) # Enactment times We'll schedule these to enact first on Kusama, then on Polkadot a week later. Both scheduled times will be morning UTC on a weekday when most engineers are online. Kusama runtime upgrades usually confirm in about 7 days, Polkadot more like 9 or 10 depending on backing. I'm posting them both on 20250210 (a Monday), so Kusama should be scheduled for 9 days and Polkadot 16 days from now (20250219 and 20250226 respectively). Grabbing some block numbers to make this coincide with roughly 8am UTC on these days gives us: Kusama enactment block: [27155056](https://kusama.subscan.io/block/27155056) Polkadot enactment block: [24899075](https://polkadot.subscan.io/block/24899075) # Upgrade Kusama to v1.4.0 https://github.com/polkadot-fellows/runtimes/releases/tag/v1.4.0 ## Create ref ### Build upgrade ```shell ❯ opengov-cli build-upgrade --network kusama --relay-version v1.4.0 Downloading runtimes. Downloading... kusama_runtime-v1004000.compact.compressed.wasm Downloading... asset-hub-kusama_runtime-v1004000.compact.compressed.wasm Downloading... encointer-kusama_runtime-v1004000.compact.compressed.wasm Downloading... bridge-hub-kusama_runtime-v1004000.compact.compressed.wasm Downloading... people-kusama_runtime-v1004000.compact.compressed.wasm Downloading... coretime-kusama_runtime-v1004000.compact.compressed.wasm Generating parachain authorization calls. The runtime hashes are logged if you would like to verify them with srtool. Kusama Asset Hub Runtime Hash: 0x04915337fde3497621c5caa36cacd94c53bfda3fc7089cfaf18bfd1510b95d18 Kusama Encointer Runtime Hash: 0x35f406c64afd06508e9d86edbfa33abd3bbd748dbc0c6640baa3e6c6a4dd37a0 Kusama Bridge Hub Runtime Hash: 0xbdad0af3745ff7d17776b51e29c261290ea72e7d4c65140300d199ba8ee50deb Kusama People Runtime Hash: 0x3ca7ebbfc8fafec59a1f0559227b96d31a5f00964c46d388ee17f6fadd5b39cf Kusama Coretime Runtime Hash: 0x766d1d6ab828473defb23986d05c4410ed5035042be48bc1f6ccd41b4020ac0f Generating Relay Chain upgrade call. The runtime hash is logged if you would like to verify it with srtool. Kusama Relay Chain Runtime Hash: 0xa5b7291bd5984a80f8819c3af0030d484c2af5a78ea4cd9b8422681ea81ff4e7 Batching calls. Success! The call data was written to ./upgrade-kusama-1.4.0/kusama-1.4.0.call To submit this as a referendum in OpenGov, run: opengov-cli submit-referendum \ --proposal "./upgrade-kusama-1.4.0/kusama-1.4.0.call" \ --network "kusama" --track <"root" or "whitelistedcaller"> ``` ### Generate referendum calls ```log! ❯ opengov-cli submit-referendum --at 27155056 \ --proposal "./upgrade-kusama-1.4.0/kusama-1.4.0.call" \ --network "kusama" --track "whitelistedcaller" ``` Submit the preimage for the Fellowship referendum: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.dwellir.com#/extrinsics/decode/0x2000882c00740edba4531f2695dc8762141c48fa857efaded3f126e67e1d912a80b64e42fb Open a Fellowship referendum to whitelist the call: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.dwellir.com#/extrinsics/decode/0x17002b0f02b0d94fdc83d6a0d4812da1d774fd1d7d3ffae85b0dacb9fd14a8ce61b17bf64722000000010a000000 Submit the preimage for the public referendum: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.dwellir.com#/extrinsics/decode/0x200001052c03180418630004000100a10f04082f000006024247c139011088000904915337fde3497621c5caa36cacd94c53bfda3fc7089cfaf18bfd1510b95d18630004000100a50f04082f000006020300943577012088000935f406c64afd06508e9d86edbfa33abd3bbd748dbc0c6640baa3e6c6a4dd37a0630004000100a90f04082f000006028200493b0110880009bdad0af3745ff7d17776b51e29c261290ea72e7d4c65140300d199ba8ee50deb630004000100b10f04082f0000060282f4563901108800093ca7ebbfc8fafec59a1f0559227b96d31a5f00964c46d388ee17f6fadd5b39cf630004000100b50f04082f0000060242456e390110880009766d1d6ab828473defb23986d05c4410ed5035042be48bc1f6ccd41b4020ac0f0009a5b7291bd5984a80f8819c3af0030d484c2af5a78ea4cd9b8422681ea81ff4e7 Open a public referendum to dispatch the call: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.dwellir.com#/extrinsics/decode/0x15002b0d0272282a8971a9df79ef27ebebf9a4bff4499df9f7657deaf286dc4b8aa19fcc994001000000705a9e01 Batch to submit on Kusama Relay Chain: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.dwellir.com#/extrinsics/decode/0x1804102000882c00740edba4531f2695dc8762141c48fa857efaded3f126e67e1d912a80b64e42fb17002b0f02b0d94fdc83d6a0d4812da1d774fd1d7d3ffae85b0dacb9fd14a8ce61b17bf64722000000010a000000200001052c03180418630004000100a10f04082f000006024247c139011088000904915337fde3497621c5caa36cacd94c53bfda3fc7089cfaf18bfd1510b95d18630004000100a50f04082f000006020300943577012088000935f406c64afd06508e9d86edbfa33abd3bbd748dbc0c6640baa3e6c6a4dd37a0630004000100a90f04082f000006028200493b0110880009bdad0af3745ff7d17776b51e29c261290ea72e7d4c65140300d199ba8ee50deb630004000100b10f04082f0000060282f4563901108800093ca7ebbfc8fafec59a1f0559227b96d31a5f00964c46d388ee17f6fadd5b39cf630004000100b50f04082f0000060242456e390110880009766d1d6ab828473defb23986d05c4410ed5035042be48bc1f6ccd41b4020ac0f0009a5b7291bd5984a80f8819c3af0030d484c2af5a78ea4cd9b8422681ea81ff4e715002b0d0272282a8971a9df79ef27ebebf9a4bff4499df9f7657deaf286dc4b8aa19fcc994001000000705a9e01 ## Test ref We can fork the network with chopsticks and check that the XCMs are sent and that we can upgrade the chains without error. ``` npx @acala-network/chopsticks@latest xcm -r kusama -p kusama-asset-hub -p encointer-kusama -p kusama-bridge-hub -p kusama-people -p kusama-coretime ``` Submit the preimage for the referendum on localhost:8005 (kusama relay) using the call from opengov-cli ![Screenshot 2025-02-10 at 12.25.28](https://hackmd.io/_uploads/ryIBldPK1e.png) whitelist the call from the fellows origin using the same call output by opengov-cli in the [js window](https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8005#/js): ``` // Grab the block number of the current head // api is already imported, no need to add anything but the following. const number = (await api.rpc.chain.getHeader()).number.toNumber() // use chopsticks dev_setStorage to inject the call into the scheduler state for the next block. await api.rpc('dev_setStorage', { scheduler: { agenda: [ [ [number + 1], [ { call: { Inline: '0x2c00740edba4531f2695dc8762141c48fa857efaded3f126e67e1d912a80b64e42fb' }, origin: { Origins: 'Fellows' } } ] ] ] } }) // Make a block to include the extrinsic await api.rpc('dev_newBlock', { count: 1 }) ``` dispatch the referendum call manually from the whitelistedcaller origin in the [js window](https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8005#/js): ``` // Grab the block number of the current head // api is already imported, no need to add anything but the following. const number = (await api.rpc.chain.getHeader()).number.toNumber() // use chopsticks dev_setStorage to inject the call into the scheduler state for the next block. The value of `Inline` is just the call data. Crucially with this call we can set the origin to `Root` await api.rpc('dev_setStorage', { scheduler: { agenda: [ [ [number + 1], [ { call: { Lookup: { hash: '0x72282a8971a9df79ef27ebebf9a4bff4499df9f7657deaf286dc4b8aa19fcc99', len: 320 } }, origin: { Origins: 'WhitelistedCaller' } } ] ] ] } }) // Make a block to include the extrinsic await api.rpc('dev_newBlock', { count: 1 }) ``` Then go through each chain (available at 800n) with n in [0,5] and compare its `system->authorizedUpgrade` hash in state to the hash for each runtime in the fellows release. You should be able to upload the wasm for each chain with the `system->applyAuthorizedUpgrade` # Upgrade Polkadot to v1.4.0 https://github.com/polkadot-fellows/runtimes/releases/tag/v1.4.0 ## Create ref ### Build upgrade calls ```shell opengov-cli build-upgrade --network polkadot --relay-version v1.4.0 ``` This will include all system parachains in the upgrade. ```log ❯ opengov-cli build-upgrade --network polkadot --relay-version v1.4.0 Downloading runtimes. Downloading... polkadot_runtime-v1004000.compact.compressed.wasm Downloading... asset-hub-polkadot_runtime-v1004000.compact.compressed.wasm Downloading... collectives-polkadot_runtime-v1004000.compact.compressed.wasm Downloading... bridge-hub-polkadot_runtime-v1004000.compact.compressed.wasm Downloading... people-polkadot_runtime-v1004000.compact.compressed.wasm Downloading... coretime-polkadot_runtime-v1004000.compact.compressed.wasm Generating parachain authorization calls. The runtime hashes are logged if you would like to verify them with srtool. Polkadot Asset Hub Runtime Hash: 0x5627437c6d5af9296b46fc39ffc066ef453fd99bb90c539a739c7e98c8364582 Polkadot Collectives Runtime Hash: 0x313481ebf6228d2950b92345d2c90ef33a84e5b4c571c6986c507dca08fee9d0 Polkadot Bridge Hub Runtime Hash: 0xcd32415306cadec074e05fbf42647a7e9909331bd97dd1e532d8f9f41d688011 Polkadot People Runtime Hash: 0x2e567d68c1913de7292d66827b057c10a2ef8a6aa1e47e316b6cd5e7b4295e85 Polkadot Coretime Runtime Hash: 0x8f84199c39c4ce451af0400bef1b8fd980ec2ab1192093441c55b29ecca2fe32 Generating Relay Chain upgrade call. The runtime hash is logged if you would like to verify it with srtool. Polkadot Relay Chain Runtime Hash: 0xdad432732e565b785a2ac346c10578fd3331352dfdf4d1ae33ca005fd3f07fe0 Batching calls. Success! The call data was written to ./upgrade-polkadot-1.4.0/polkadot-1.4.0.call To submit this as a referendum in OpenGov, run: opengov-cli submit-referendum \ --proposal "./upgrade-polkadot-1.4.0/polkadot-1.4.0.call" \ --network "polkadot" --track <"root" or "whitelistedcaller"> ``` ### Generate referendum calls ```log! ❯ opengov-cli submit-referendum --at 24899075 \ --proposal "./upgrade-polkadot-1.4.0/polkadot-1.4.0.call" \ --network "polkadot" --track "whitelistedcaller" ``` Submit the preimage for the Fellowship referendum: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-collectives-rpc.polkadot.io#/extrinsics/decode/0x2b00d41f0004010004082f0000060342c78b76216f88170023491956e1a07d55bf6fa0ac7a90404bdb2fe16599064d4ccaf82c22f1c72f21 Open a Fellowship referendum to whitelist the call: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-collectives-rpc.polkadot.io#/extrinsics/decode/0x3d003e0202623e4656d33843d987d5dfa54e31f7434f8c85fdea3a06916490fae72787459935000000010a000000 Submit the preimage for the public referendum: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-rpc.dwellir.com#/extrinsics/decode/0x0a00fd0417031a0418630004000100a10f04082f00000602823e213901108800095627437c6d5af9296b46fc39ffc066ef453fd99bb90c539a739c7e98c8364582630004000100a50f04082f0000060202b8203b0110880009313481ebf6228d2950b92345d2c90ef33a84e5b4c571c6986c507dca08fee9d0630004000100a90f04082f0000060202dca3390110880009cd32415306cadec074e05fbf42647a7e9909331bd97dd1e532d8f9f41d688011630004000100b10f04082f0000060242a2143b01108800092e567d68c1913de7292d66827b057c10a2ef8a6aa1e47e316b6cd5e7b4295e85630004000100b50f04082f0000060202e29c3a01108800098f84199c39c4ce451af0400bef1b8fd980ec2ab1192093441c55b29ecca2fe320009dad432732e565b785a2ac346c10578fd3331352dfdf4d1ae33ca005fd3f07fe0 Open a public referendum to dispatch the call: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-rpc.dwellir.com#/extrinsics/decode/0x1500160d021e4765ea1528d5f3e3367133191bc501cc5bf4fbacf9b16704dba45aec6f92753f0100000003ee7b01 Batch to submit on Polkadot Relay Chain: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-rpc.dwellir.com#/extrinsics/decode/0x1a04080a00fd0417031a0418630004000100a10f04082f00000602823e213901108800095627437c6d5af9296b46fc39ffc066ef453fd99bb90c539a739c7e98c8364582630004000100a50f04082f0000060202b8203b0110880009313481ebf6228d2950b92345d2c90ef33a84e5b4c571c6986c507dca08fee9d0630004000100a90f04082f0000060202dca3390110880009cd32415306cadec074e05fbf42647a7e9909331bd97dd1e532d8f9f41d688011630004000100b10f04082f0000060242a2143b01108800092e567d68c1913de7292d66827b057c10a2ef8a6aa1e47e316b6cd5e7b4295e85630004000100b50f04082f0000060202e29c3a01108800098f84199c39c4ce451af0400bef1b8fd980ec2ab1192093441c55b29ecca2fe320009dad432732e565b785a2ac346c10578fd3331352dfdf4d1ae33ca005fd3f07fe01500160d021e4765ea1528d5f3e3367133191bc501cc5bf4fbacf9b16704dba45aec6f92753f0100000003ee7b01 Batch to submit on Polkadot Collectives Chain: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-collectives-rpc.polkadot.io#/extrinsics/decode/0x2804082b00d41f0004010004082f0000060342c78b76216f88170023491956e1a07d55bf6fa0ac7a90404bdb2fe16599064d4ccaf82c22f1c72f213d003e0202623e4656d33843d987d5dfa54e31f7434f8c85fdea3a06916490fae72787459935000000010a000000 ## Test ref We can fork the network with chopsticks and check that the XCMs are sent and that we can upgrade the chains without error. ``` npx @acala-network/chopsticks@latest xcm -r polkadot -p polkadot-asset-hub -p polkadot-collectives -p polkadot-bridge-hub -p polkadot-people -p polkadot-coretime ``` Submit the preimage for the referendum on localhost:8005 (polkadot relay) using the call from opengov-cli whitelist the call from the fellows origin using the same call output by opengov-cli in the collectives [js window](https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8001#/js): ``` // Grab the block number of the current head // api is already imported, no need to add anything but the following. const number = (await api.rpc.chain.getHeader()).number.toNumber() // use chopsticks dev_setStorage to inject the call into the scheduler state for the next block. await api.rpc('dev_setStorage', { scheduler: { agenda: [ [ [number + 1], [ { call: { Inline: '0x2c00740edba4531f2695dc8762141c48fa857efaded3f126e67e1d912a80b64e42fb' }, origin: { FellowshipOrigins: 'Fellows' } } ] ] ] } }) // Make a block to include the extrinsic await api.rpc('dev_newBlock', { count: 1 }) ``` You can see the events on the relay whitelisting the call and requesting the preimage. ![Screenshot 2025-02-10 at 17.16.32](https://hackmd.io/_uploads/Hk1KV3DYyg.png) Upload the public referendum preimage from opengov-cli to the relay chain. Dispatch the referendum call manually from the whitelistedcaller origin in the relay chain [js window](https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8005#/js): ``` // Grab the block number of the current head // api is already imported, no need to add anything but the following. const number = (await api.rpc.chain.getHeader()).number.toNumber() // use chopsticks dev_setStorage to inject the call into the scheduler state for the next block. The value of `Inline` is just the call data. Crucially with this call we can set the origin to `Root` await api.rpc('dev_setStorage', { scheduler: { agenda: [ [ [number + 1], [ { call: { Lookup: { hash: '0x1e4765ea1528d5f3e3367133191bc501cc5bf4fbacf9b16704dba45aec6f9275', len: 319 } }, origin: { Origins: 'WhitelistedCaller' } } ] ] ] } }) // Make a block to include the extrinsic await api.rpc('dev_newBlock', { count: 1 }) ``` Then go through each chain (available at 800n) with n in [0,5] and compare its `system->authorizedUpgrade` hash in state to the hash for each runtime in the fellows release. You should be able to upload the wasm for each chain with the `system->applyAuthorizedUpgrade`