# Testing runtime upgrades for system parachains in Chopsticks ## Overview We need the ability to test governance proposals that depend on runtime upgrades that have not yet executed. Runtime upgrades for system parachains can take up to 4 weeks to execute. We therefore need to execute the runtime upgrade and the subsequent governance proposal in a simulated Chopsticks environment. ## Steps In the following scenario, we will simulate execution of the 1.2.0 upgrade: https://github.com/polkadot-fellows/runtimes/releases/tag/v1.2.0 1. Install [opengov-cli](https://github.com/joepetrowski/opengov-cli) 2. Build the preimage for the upgrade: ```shell opengov-cli build-upgrade --network polkadot --relay-version 1.2.0 --filename preimage.hex ``` 3. Convert the preimage from hex to binary ```shell xxd -r -p preimage.hex > preimage.bin ``` 4. Determine the size of the of preimage, save as `PREIMAGE_SIZE` ```shell $ stat -c%s preimage.bin 1567371 ``` 4. Compute blake2-256 hash of preimage, save as `PREIMAGE_HASH` ```shell $ b2sum -l 256 preimage.bin | awk '{print "0x"$1}' 0x15165c85152568b7f523e374ce1a5172f2aa148721d5dae0441f86c201c1a77b ``` 5. Prepend compact-encoded length prefix to preimage, and convert back to hex, save as `PREIMAGE_WITH_LENGTH_PREFIX`: ```rust= use codec::Encode; use std::fs::File; fn main() { let mut file = File::open("preimage.bin")?; let mut buf: Vec<u8> = Vec::new(); file.read_to_end(&mut buf)?; let bytes_encoded = buf.encode(); println!("0x{}", hex::encode(bytes_encoded)); } ``` 5. Create a chopsticks configuration file for the Polkadot relay chain, substituting the values generated previously: polkadot.yml ```yaml= endpoint: wss://polkadot-rpc.dwellir.com mock-signature-host: true block: ${env.POLKADOT_BLOCK_NUMBER} db: ./polkadot.sqlite import-storage: System: Account: - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY - providers: 1 data: free: '10000000000000000000' ParasDisputes: $removePrefix: ['disputes'] # those can makes block building super slow Preimage: { PreimageFor: [[[[PREIMAGE_HASH, PREIMAGE_SIZE]], PREIMAGE_WITH_LENGTH_PREFIX]], StatusFor: [[[PREIMAGE_HASH], { Requested: { count: 1, len: PREIMAGE_SIZE } }]], } ``` 6. Use these Chopstics config files for AssetHub and BridgeHub polkadot-asset-hub.yml: ```yaml endpoint: wss://statemint-rpc.dwellir.com mock-signature-host: true block: ${env.POLKADOT_ASSET_HUB_BLOCK_NUMBER} db: ./assethub.sqlite import-storage: System: Account: - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY - providers: 1 data: free: 1000000000000000 ``` polkadot-bridge-hub.yml: ```yaml endpoint: wss://polkadot-bridge-hub-rpc.dwellir.com mock-signature-host: true block: ${env.POLKADOT_BRIDGEHUB_BLOCK_NUMBER} db: ./bridgehub.sqlite import-storage: System: Account: - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY - providers: 1 data: free: 1000000000000000 ``` 7. Run Chopsticks ``` yarn start xcm -r polkadot.yml -p polkadot-asset-hub.yml -p polkadot-bridge-hub.yml ``` 8. Execute the upgrade on the relay chain using Polkadot-JS: ```javascript= const number = (await api.rpc.chain.getHeader()).number.toNumber() await api.rpc('dev_setStorage', { Scheduler: { Agenda: [ [ [number + 1], [ { call: { Lookup: { hash: PREIMAGE_HASH, len: PREIMAGE_SIZE, }, }, origin: { system: 'Root', }, }, ], ], ], }, }) await api.rpc('dev_newBlock', { count: 1 }) ``` 9. Advance a few blocks on the relay chain ```javascript await api.rpc('dev_newBlock', { count: 2 }) ``` 10. Advance by one block on bridgehub (not sure if necessary, need to experiment) ```javascript await api.rpc('dev_newBlock', { count: 1 }) ``` 11. Now that the upgrade has been authorized on BridgeHub, we can execute the upgrade by calling `parachainSystem.enactAuthorizedUpgrade`, passing the parachain WASM blob previously generated by `opengov-cli`: ![69887a907ad4f027c14651c6b8ba9fa0](https://hackmd.io/_uploads/HkbcIGExR.png) 12. Advance a few blocks on both bridgehub AND the relay chain ```javascript await api.rpc('dev_newBlock', { count: 1 }) ``` 13. The parachain should now be upgraded. ## Caveats Some polkadot API endpoints aggressively timeout connections, causing Chopsticks to die: ``` API-WS: disconnected from wss://polkadot-rpc.dwellir.com: 1006:: Abnormal Closure ``` The usual remedy is to restart chopsticks and pray the API connections don't die again.