# 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

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.

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`