From 439ffc84fcce230aa3931da2fb023da2ee833d02 Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 31 Oct 2025 15:08:29 +0100 Subject: [PATCH 01/11] Introduce scenarios about runtime upgrades via referendas (root/whitelisted caller tracks) --- .../assetHubKusama.bridgeHubKusama.test.ts | 14 +- .../src/assetHubKusama.coretimeKusama.test.ts | 14 +- .../kusama/src/assetHubKusama.kusama.test.ts | 23 +- .../src/assetHubKusama.peopleKusama.test.ts | 14 +- .../src/assetHubKusama.system.e2e.test.ts | 3 + .../src/encointer.assetHubKusama.test.ts | 14 +- .../assetHubPolkadot.polkadot.test.ts.snap | 24 +- ...assetHubPolkadot.bridgeHubPolkadot.test.ts | 13 + ...setHubPolkadot.collectivesPolkadot.test.ts | 17 + .../assetHubPolkadot.coretimePolkadot.test.ts | 13 + .../assetHubPolkadot.peoplePolkadot.test.ts | 13 + .../src/assetHubPolkadot.polkadot.test.ts | 15 +- .../src/assetHubPolkadot.system.e2e.test.ts | 2 + .../src/collectivesPolkadot.polkadot.test.ts | 17 +- .../polkadot/src/polkadot.system.e2e.test.ts | 3 + packages/shared/src/collectives.ts | 25 +- packages/shared/src/upgrade.ts | 766 +++++++++++++++++- 17 files changed, 947 insertions(+), 43 deletions(-) diff --git a/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts b/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts index 9d8ce5f1e..c37c551bd 100644 --- a/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts +++ b/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts @@ -1,7 +1,8 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, bridgeHubKusama } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' +import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' @@ -38,3 +39,14 @@ describe('assetHubKusama & bridgeHubKusama', async () => { } }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubKusama & bridgeHubKusama', + addressEncoding: 2, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubKusama, bridgeHubKusama, testConfigForLocalScheduler), +) diff --git a/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts b/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts index be74b6181..76478b7a6 100644 --- a/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts +++ b/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts @@ -1,7 +1,8 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, coretimeKusama } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' +import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' @@ -38,3 +39,14 @@ describe('assetHubKusama & coretimeKusama', async () => { } }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubKusama & coretimeKusama', + addressEncoding: 2, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubKusama, coretimeKusama, testConfigForLocalScheduler), +) diff --git a/packages/kusama/src/assetHubKusama.kusama.test.ts b/packages/kusama/src/assetHubKusama.kusama.test.ts index 741ebfe3e..0c1ef13c4 100644 --- a/packages/kusama/src/assetHubKusama.kusama.test.ts +++ b/packages/kusama/src/assetHubKusama.kusama.test.ts @@ -1,12 +1,16 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, kusama } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' +import { + governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite, + governanceChainUpgradesOtherChainViaRootReferendumSuite, +} from '@e2e-test/shared/upgrade' import { runXcmPalletDown, runXcmPalletUp } from '@e2e-test/shared/xcm' import { describe } from 'vitest' -describe('kusama & assetHubKusama', async () => { +describe('assetHubKusama & kusama', async () => { const [kusamaClient, assetHubClient] = await setupNetworks(kusama, assetHubKusama) const assetHubKSM = assetHubKusama.custom.ksm @@ -42,3 +46,18 @@ describe('kusama & assetHubKusama', async () => { { skip: true }, ) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubKusama & kusama', + addressEncoding: 2, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite(assetHubKusama, kusama, testConfigForLocalScheduler), +) + +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubKusama, kusama, testConfigForLocalScheduler), +) diff --git a/packages/kusama/src/assetHubKusama.peopleKusama.test.ts b/packages/kusama/src/assetHubKusama.peopleKusama.test.ts index 1894eb4e4..b39271701 100644 --- a/packages/kusama/src/assetHubKusama.peopleKusama.test.ts +++ b/packages/kusama/src/assetHubKusama.peopleKusama.test.ts @@ -1,7 +1,8 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, peopleKusama } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' +import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' @@ -42,3 +43,14 @@ describe('assetHubKusama & peopleKusama', async () => { { skip: true }, ) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubKusama & peopleKusama', + addressEncoding: 2, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubKusama, peopleKusama, testConfigForLocalScheduler), +) diff --git a/packages/kusama/src/assetHubKusama.system.e2e.test.ts b/packages/kusama/src/assetHubKusama.system.e2e.test.ts index c431dda53..fa6897e5c 100644 --- a/packages/kusama/src/assetHubKusama.system.e2e.test.ts +++ b/packages/kusama/src/assetHubKusama.system.e2e.test.ts @@ -1,5 +1,6 @@ import { assetHubKusama } from '@e2e-test/networks/chains' import { type ParaTestConfig, registerTestTree, systemE2ETestsForParaWithScheduler } from '@e2e-test/shared' +import { governanceChainSelfUpgradeViaRootReferendumSuite } from '@e2e-test/shared/upgrade' // TODO: Uncomment after Kusama 2.0+ release due to polkadot-fellows/runtimes#957 // const testConfig: ParaTestConfig = { @@ -18,3 +19,5 @@ const testConfigForLocalScheduler: ParaTestConfig = { } registerTestTree(systemE2ETestsForParaWithScheduler(assetHubKusama, testConfigForLocalScheduler)) + +registerTestTree(governanceChainSelfUpgradeViaRootReferendumSuite(assetHubKusama, testConfigForLocalScheduler)) diff --git a/packages/kusama/src/encointer.assetHubKusama.test.ts b/packages/kusama/src/encointer.assetHubKusama.test.ts index 6d7a9f27f..e1f03610d 100644 --- a/packages/kusama/src/encointer.assetHubKusama.test.ts +++ b/packages/kusama/src/encointer.assetHubKusama.test.ts @@ -1,7 +1,8 @@ import { defaultAccountsSr25519 } from '@e2e-test/networks' import { assetHubKusama, encointerKusama } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' +import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' @@ -41,3 +42,14 @@ describe('encointerKusama & assetHubKusama', async () => { } }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'encointerKusama & assetHubKusama', + addressEncoding: 2, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubKusama, encointerKusama, testConfigForLocalScheduler), +) diff --git a/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap b/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap index 2720035f8..87b00bb25 100644 --- a/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap +++ b/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > balance on from chain 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Asset Hub to Polkadot > balance on from chain 1`] = ` { "consumers": 0, "data": { @@ -15,7 +15,7 @@ exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > balanc } `; -exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > balance on to chain 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Asset Hub to Polkadot > balance on to chain 1`] = ` { "consumers": 0, "data": { @@ -30,7 +30,7 @@ exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > balanc } `; -exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > from chain ump messages 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Asset Hub to Polkadot > from chain ump messages 1`] = ` [ { "v5": [ @@ -100,7 +100,7 @@ exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > from c ] `; -exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > to chain ump events 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Asset Hub to Polkadot > to chain ump events 1`] = ` [ { "data": { @@ -122,7 +122,7 @@ exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > to cha ] `; -exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > tx events 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Asset Hub to Polkadot > tx events 1`] = ` [ { "data": { @@ -155,7 +155,7 @@ exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > tx eve "Complete": { "used": { "proofSize": "(rounded 400000)", - "refTime": "(rounded 40000000000)", + "refTime": "(rounded 50000000000)", }, }, }, @@ -166,7 +166,7 @@ exports[`asset hub & polkadot > Teleport DOT from Asset Hub to Polkadot > tx eve ] `; -exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > balance on from chain 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Polkadot to Asset Hub > balance on from chain 1`] = ` { "consumers": 0, "data": { @@ -181,7 +181,7 @@ exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > balanc } `; -exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > balance on to chain 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Polkadot to Asset Hub > balance on to chain 1`] = ` { "consumers": 0, "data": { @@ -196,7 +196,7 @@ exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > balanc } `; -exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > to chain dmp events 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Polkadot to Asset Hub > to chain dmp events 1`] = ` [ { "data": { @@ -210,7 +210,7 @@ exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > to cha "dmqHead": "(hash)", "weightUsed": { "proofSize": "(rounded 4000)", - "refTime": "(rounded 1000000000)", + "refTime": "(rounded 800000000)", }, }, "method": "DownwardMessagesProcessed", @@ -222,7 +222,7 @@ exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > to cha "origin": "Parent", "success": true, "weightUsed": { - "proofSize": "(rounded 7000)", + "proofSize": "(rounded 9000)", "refTime": "(rounded 600000000)", }, }, @@ -232,7 +232,7 @@ exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > to cha ] `; -exports[`asset hub & polkadot > Teleport DOT from Polkadot to Asset Hub > tx events 1`] = ` +exports[`assetHubPolkadot & polkadot > Teleport DOT from Polkadot to Asset Hub > tx events 1`] = ` [ { "data": { diff --git a/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts index ff953328c..f5f120b1e 100644 --- a/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts @@ -38,3 +38,16 @@ describe('assetHubPolkadot & bridgeHubPolkadot', async () => { } }) }) + +// TODO: Uncomment Post-AHM on Polkadot + +// const testConfigForLocalScheduler: ParaTestConfig = { +// testSuiteName: 'assetHubPolkadot & bridgeHubPolkadot', +// addressEncoding: 0, +// blockProvider: 'NonLocal', +// asyncBacking: 'Enabled', +// } + +// registerTestTree( +// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, bridgeHubPolkadot, testConfigForLocalScheduler), +// ) diff --git a/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts index 0ae86bef1..98be64d58 100644 --- a/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts @@ -42,3 +42,20 @@ describe('assetHubPolkadot & collectivesPolkadot', async () => { } }) }) + +// // TODO: Uncomment Post-AHM on Polkadot + +// const testConfigForLocalScheduler: ParaTestConfig = { +// testSuiteName: 'assetHubPolkadot & collectivesPolkadot', +// addressEncoding: 0, +// blockProvider: 'NonLocal', +// asyncBacking: 'Enabled', +// } + +// registerTestTree( +// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, collectivesPolkadot, testConfigForLocalScheduler), +// ) + +// registerTestTree( +// governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite(assetHubPolkadot, collectivesPolkadot, testConfigForLocalScheduler), +// ) diff --git a/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts index 158c65163..19ebb5c37 100644 --- a/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts @@ -38,3 +38,16 @@ describe('assetHubPolkadot & coretimePolkadot', async () => { } }) }) + +// TODO: Uncomment Post-AHM on Polkadot + +// const testConfigForLocalScheduler: ParaTestConfig = { +// testSuiteName: 'assetHubPolkadot & coretimePolkadot', +// addressEncoding: 0, +// blockProvider: 'NonLocal', +// asyncBacking: 'Enabled', +// } + +// registerTestTree( +// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, coretimePolkadot, testConfigForLocalScheduler), +// ) diff --git a/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts index 51f984670..f02ad507a 100644 --- a/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts @@ -38,3 +38,16 @@ describe('assetHubPolkadot & peoplePolkadot', async () => { } }) }) + +// TODO: Uncomment Post-AHM on Polkadot + +// const testConfigForLocalScheduler: ParaTestConfig = { +// testSuiteName: 'assetHubPolkadot & peoplePolkadot', +// addressEncoding: 0, +// blockProvider: 'NonLocal', +// asyncBacking: 'Enabled', +// } + +// registerTestTree( +// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, peoplePolkadot, testConfigForLocalScheduler), +// ) diff --git a/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts index f145d2a12..3b8a0b60f 100644 --- a/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts @@ -6,7 +6,7 @@ import { runXcmPalletDown, runXcmPalletUp } from '@e2e-test/shared/xcm' import { describe } from 'vitest' -describe('asset hub & polkadot', async () => { +describe('assetHubPolkadot & polkadot', async () => { const [polkadotClient, ahClient] = await setupNetworks(polkadot, assetHubPolkadot) runXcmPalletUp('Teleport DOT from Asset Hub to Polkadot', async () => { @@ -175,3 +175,16 @@ describe('asset hub & polkadot', async () => { } }) }) + +// TODO: Uncomment Post-AHM on Polkadot + +// const testConfigForLocalScheduler: ParaTestConfig = { +// testSuiteName: 'assetHubPolkadot & polkadot', +// addressEncoding: 0, +// blockProvider: 'NonLocal', +// asyncBacking: 'Enabled', +// } + +// registerTestTree( +// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, polkadot, testConfigForLocalScheduler), +// ) diff --git a/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts b/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts index 41402c209..8b0063c18 100644 --- a/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts @@ -20,3 +20,5 @@ registerTestTree(systemE2ETestsViaRemoteScheduler(polkadot, assetHubPolkadot, te // } // registerTestTree(systemE2ETestsForParaWithScheduler(assetHubPolkadot, testConfigForLocalScheduler)) + +// registerTestTree(governanceChainSelfUpgradeViaRootReferendumSuite(assetHubPolkadot, testConfigForLocalScheduler)) diff --git a/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts b/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts index 26f5780d1..c339806a4 100644 --- a/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts +++ b/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts @@ -1,7 +1,10 @@ import { collectivesPolkadot, polkadot } from '@e2e-test/networks/chains' -import { baseCollectivesChainE2ETests, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { baseCollectivesChainE2ETests, registerTestTree, setupNetworks, type TestConfig } from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { + authorizeUpgradeViaCollectives, + governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite, +} from '@e2e-test/shared/upgrade.js' import { runXcmPalletDown, runXcmPalletUp } from '@e2e-test/shared/xcm' import { describe, test } from 'vitest' @@ -44,3 +47,13 @@ describe('collectives & polkadot', async () => { await authorizeUpgradeViaCollectives(polkadotClient, collectivesClient, collectivesClient) }) }) + +const testConfig: TestConfig = { + testSuiteName: 'collectives & polkadot', + addressEncoding: 0, + blockProvider: 'Local', +} + +registerTestTree( + governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite(polkadot, collectivesPolkadot, testConfig), +) diff --git a/packages/polkadot/src/polkadot.system.e2e.test.ts b/packages/polkadot/src/polkadot.system.e2e.test.ts index a7ed937b9..9075b0965 100644 --- a/packages/polkadot/src/polkadot.system.e2e.test.ts +++ b/packages/polkadot/src/polkadot.system.e2e.test.ts @@ -1,5 +1,6 @@ import { polkadot } from '@e2e-test/networks/chains' import { type RelayTestConfig, registerTestTree, systemE2ETests } from '@e2e-test/shared' +import { governanceChainSelfUpgradeViaRootReferendumSuite } from '@e2e-test/shared/upgrade' const testConfig: RelayTestConfig = { testSuiteName: 'Polkadot System', @@ -9,6 +10,8 @@ const testConfig: RelayTestConfig = { registerTestTree(systemE2ETests(polkadot, testConfig)) +registerTestTree(governanceChainSelfUpgradeViaRootReferendumSuite(polkadot, testConfig)) + // TODO: Uncomment Post-AHM on Polkadot // const testConfigForAssetHub: ParaTestConfig = { diff --git a/packages/shared/src/collectives.ts b/packages/shared/src/collectives.ts index 17f3d4721..35326b0c8 100644 --- a/packages/shared/src/collectives.ts +++ b/packages/shared/src/collectives.ts @@ -10,7 +10,7 @@ import type { Chain, Client } from '@e2e-test/networks' -import { checkSystemEvents, createXcmTransactSend, scheduleInlineCallWithOrigin } from './helpers/index.js' +import { checkSystemEvents, createXcmTransactSend, getXcmRoute, scheduleInlineCallWithOrigin } from './helpers/index.js' import { setupNetworks } from './setup.js' import type { RootTestTree } from './types.js' /** @@ -59,19 +59,7 @@ export async function sendWhitelistCallViaXcmTransact( encodedChainCallData: `0x${string}`, requireWeightAtMost = { proofSize: '10000', refTime: '100000000' }, ): Promise { - let dest: { parents: number; interior: any } - - if (destClient.config.isRelayChain) { - dest = { - parents: 1, - interior: 'Here', - } - } else { - dest = { - parents: 1, - interior: { X1: [{ Parachain: destClient.config.paraId }] }, - } - } + const dest = getXcmRoute(collectivesClient.config, destClient.config) const xcmTx = createXcmTransactSend( collectivesClient, @@ -81,7 +69,14 @@ export async function sendWhitelistCallViaXcmTransact( requireWeightAtMost, ) - await scheduleInlineCallWithOrigin(collectivesClient, xcmTx.method.toHex(), { FellowshipOrigins: 'Fellows' }) + let origin: { Origins: 'Fellows' } | { FellowshipOrigins: 'Fellows' } + if (collectivesClient.config.name === 'kusama') { + origin = { Origins: 'Fellows' } + } else { + origin = { FellowshipOrigins: 'Fellows' } + } + + await scheduleInlineCallWithOrigin(collectivesClient, xcmTx.method.toHex(), origin) } /** diff --git a/packages/shared/src/upgrade.ts b/packages/shared/src/upgrade.ts index a7ce6ef34..8fa103337 100644 --- a/packages/shared/src/upgrade.ts +++ b/packages/shared/src/upgrade.ts @@ -1,20 +1,30 @@ import { sendTransaction } from '@acala-network/chopsticks-testing' -import { type Client, defaultAccounts } from '@e2e-test/networks' -import { sendWhitelistCallViaXcmTransact } from '@e2e-test/shared' +import { type Chain, type Client, defaultAccounts, defaultAccountsSr25519 as devAccounts } from '@e2e-test/networks' +import { type RootTestTree, sendWhitelistCallViaXcmTransact, setupNetworks } from '@e2e-test/shared' +import type { SubmittableExtrinsic } from '@polkadot/api/types' +import type { IU8a } from '@polkadot/types/types' +import { bufferToU8a, compactAddLength } from '@polkadot/util' import type { HexString } from '@polkadot/util/types' import { assert } from 'vitest' import { + assertExpectedEvents, + type BlockProvider, checkEvents, checkSystemEvents, createXcmTransactSend, getXcmRoute, + nextSchedulableBlockNum, scheduleInlineCallWithOrigin, + type TestConfig, } from './helpers/index.js' +type AuthorizeUpgradeFn = (codeHash: string | Uint8Array) => SubmittableExtrinsic<'promise'> +type ExpectedEvents = Parameters[1] + /** * Constructs an XCM forceBatch transaction that authorizes a runtime upgrade on a destination chain. * @@ -48,12 +58,12 @@ export function createXcmAuthorizeUpgradeBatch(codeHash: HexString, sourceClient * * @param governingChain - The chain where the governance is running, allowed to execute as superuser on other chains * @param chainToUpgrade - The chain whose runtime is being upgraded. - * @param collectivesChain - The chain that hosts the collective body which will whitelist the upgrade call. + * @param fellowshipChain - The chain that hosts the collective body which will whitelist the upgrade call. */ export async function authorizeUpgradeViaCollectives( governingChain: Client, chainToUpgrade: Client, - collectivesChain: Client, + fellowshipChain: Client, ) { // NOTE: Since the test is run against some live chain data, it may happen that at some moment some upgrade // is already authorized - expected result is that the authorized hash will be overriden by this test @@ -95,12 +105,12 @@ export async function authorizeUpgradeViaCollectives( await assertAuthorizedUpgradeUnchanged() // collectives whitelisting a call - await sendWhitelistCallViaXcmTransact(governingChain, collectivesChain, authorizeUpgradeCall.method.hash.toHex(), { + await sendWhitelistCallViaXcmTransact(governingChain, fellowshipChain, authorizeUpgradeCall.method.hash.toHex(), { proofSize: '10000', refTime: '500000000', }) - await collectivesChain.dev.newBlock() - await checkSystemEvents(collectivesChain, 'polkadotXcm') + await fellowshipChain.dev.newBlock() + await checkSystemEvents(fellowshipChain, 'polkadotXcm') .redact({ hash: false, redactKeys: /messageId/ }) .toMatchSnapshot('collectives events emitted when sending xcm') await governingChain.dev.newBlock() @@ -136,3 +146,745 @@ export async function authorizeUpgradeViaCollectives( assert.equal((await chainToUpgrade.api.query.system.authorizedUpgrade()).value.codeHash.toHex(), codeHash) } + +/** + * Helper function to create and fast-track a referendum for testing purposes. + * + * This simulates the full governance flow by: + * 1. Submitting a preimage with the call + * 2. Creating a referendum on the specified track + * 3. Placing the decision deposit to move it to the decision phase + * 4. Fast-tracking approval by manipulating storage to simulate voting + * 5. Waiting for the referendum to execute + * + * @param client - The client instance for the chain + * @param call - The call to be executed via referendum + * @param track - The origin track (e.g., { system: 'Root' } or { Origins: 'WhitelistedCaller' }) + * @returns The referendum index + */ +async function createAndFastTrackReferendum( + client: Client, + call: SubmittableExtrinsic<'promise'>, + track: { system: string } | { Origins: string }, + blockProvider: BlockProvider, +): Promise { + const alice = devAccounts.alice + + // Fund Alice for preimage and deposits + await client.dev.setStorage({ + System: { + account: [[[alice.address], { providers: 1, data: { free: 100000 * 1e10 } }]], + }, + }) + + // Step 1: Submit preimage + const preimageCall = call.method + const preimageHash = preimageCall.hash + const preimageTx = client.api.tx.preimage.notePreimage(preimageCall.toHex()) + await sendTransaction(preimageTx.signAsync(alice)) + await client.dev.newBlock({ count: 1 }) + + assertExpectedEvents(await client.api.query.system.events(), [ + { type: client.api.events.preimage.Noted, args: { hash_: preimageHash } }, + ]) + + // Step 2: Submit referendum + const proposalOrigin = track + const proposal = { + Lookup: { + hash: preimageHash, + len: preimageCall.encodedLength, + }, + } + const enactmentMoment = { After: 0 } // Execute immediately after approval + + const submitTx = client.api.tx.referenda.submit(proposalOrigin as any, proposal, enactmentMoment) + await sendTransaction(submitTx.signAsync(alice)) + await client.dev.newBlock({ count: 1 }) + + // Get referendum index from events + const events = await client.api.query.system.events() + const submittedEvent = events.find((record) => client.api.events.referenda.Submitted.is(record.event)) + + if (!submittedEvent || !client.api.events.referenda.Submitted.is(submittedEvent.event)) { + throw new Error('Referendum submission failed - Submitted event not found') + } + + const referendumIndex = submittedEvent.event.data.index.toNumber() + + // Step 3: Place decision deposit to move to decision phase + const placeDecisionDepositTx = client.api.tx.referenda.placeDecisionDeposit(referendumIndex) + await sendTransaction(placeDecisionDepositTx.signAsync(alice)) + await client.dev.newBlock({ count: 1 }) + + // Step 4: Fast-track by manipulating referendum storage to simulate approval + // We set the tally to have overwhelming support + const referendumInfo = await client.api.query.referenda.referendumInfoFor(referendumIndex) + + if (referendumInfo.isNone) { + throw new Error(`Referendum ${referendumIndex} not found in storage`) + } + + const ongoing = referendumInfo.unwrap().asOngoing + + // Get total issuance for realistic tally values + const totalIssuance = (await client.api.query.balances.totalIssuance()).toBigInt() + + // Get current block number + const currentBlock = (await client.api.rpc.chain.getHeader()).number.toNumber() + + // Support Lookup, Inline or Legacy proposals + const callHash = ongoing.proposal.isLookup + ? ongoing.proposal.asLookup.hash.toHex() + : ongoing.proposal.isInline + ? client.api.registry.hash(ongoing.proposal.asInline).toHex() + : ongoing.proposal.asLegacy.hash.toHex() + + // Create the fast-tracked proposal data + const fastProposalData = { + ongoing: { + ...ongoing.toJSON(), + enactment: { after: 0 }, + deciding: { + since: currentBlock - 1, + confirming: currentBlock - 1, + }, + tally: { + ayes: (totalIssuance - 1n).toString(), + nays: '0', + support: (totalIssuance - 1n).toString(), + }, + alarm: [currentBlock + 1, [currentBlock + 1, 0]], + }, + } + + let fastProposal: any + try { + fastProposal = client.api.registry.createType('Option', fastProposalData) + } catch { + try { + fastProposal = client.api.registry.createType( + 'Option', + fastProposalData, + ) + } catch { + fastProposal = client.api.registry.createType( + 'Option', + fastProposalData, + ) + } + } + + const referendumKey = client.api.query.referenda.referendumInfoFor.key(referendumIndex) + await client.api.rpc('dev_setStorage', [[referendumKey, fastProposal.toHex()]]) + + // Helper function to speed up execution of existing scheduled calls (re-scheduled at next block) + const moveScheduledCallToNextBlock = async (verifier: (call: any) => boolean) => { + const nextBlockNumber = await nextSchedulableBlockNum(client.api, blockProvider) + const agenda = await client.api.query.scheduler.agenda.entries() + let found = false + + for (const agendaEntry of agenda) { + for (const scheduledEntry of agendaEntry[1]) { + if (scheduledEntry.isSome && verifier(scheduledEntry.unwrap().call)) { + found = true + + await client.api.rpc('dev_setStorage', [ + [agendaEntry[0]], + [await client.api.query.scheduler.agenda.key(nextBlockNumber), agendaEntry[1].toHex()], + ]) + + if (scheduledEntry.unwrap().maybeId.isSome) { + const id = scheduledEntry.unwrap().maybeId.unwrap().toHex() + const lookup = await client.api.query.scheduler.lookup(id) + + if (lookup.isSome) { + const lookupKey = await client.api.query.scheduler.lookup.key(id) + const fastLookup = client.api.registry.createType('Option<(u32,u32)>', [nextBlockNumber, 0]) + await client.api.rpc('dev_setStorage', [[lookupKey, fastLookup.toHex()]]) + } + } + } + } + } + + if (!found) { + throw new Error('No scheduled call found') + } + } + + // Move the nudgeReferendum call to the next block + await moveScheduledCallToNextBlock((call) => { + if (!call.isInline) { + return false + } + const callData = client.api.createType('Call', call.asInline.toHex()) + return callData.method === 'nudgeReferendum' && (callData.args[0] as any).toNumber() === referendumIndex + }) + await client.dev.newBlock({ count: 1 }) + + // Move the actual proposal call to the next block + await moveScheduledCallToNextBlock((call) => { + return call.isLookup + ? call.asLookup.hash.toHex() === callHash + : call.isInline + ? client.api.registry.hash(call.asInline).toHex() === callHash + : call.asLegacy.hash.toHex() === callHash + }) + + const finalReferendumInfo = await client.api.query.referenda.referendumInfoFor(referendumIndex) + assert(finalReferendumInfo.unwrap().isApproved) + + // Create another block to execute the proposal + await client.dev.newBlock({ count: 1 }) + + return referendumIndex +} + +/** + * Runs the authorize upgrade + apply authorized upgrade scenario via Root track referendum. + * + * This test demonstrates the full governance flow: + * 1. Fetches current runtime WASM and hashes it + * 2. Creates a Root track referendum containing the authorizeUpgrade call + * 3. Fast-tracks the referendum to approval + * 4. Applies the upgrade with applyAuthorizedUpgrade + * 5. Verifies expected events + */ +async function runAuthorizeUpgradeViaRootReferendum( + governingChain: Client, + chainToUpgrade: Client, + testConfig: TestConfig, + params: { + call: AuthorizeUpgradeFn + expectedAfterApply: (hash: IU8a) => ExpectedEvents + }, +) { + const alice = devAccounts.alice + + const currentWasm = bufferToU8a(Buffer.from((await chainToUpgrade.chain.head.wasm).slice(2), 'hex')) + const currentWasmHash = chainToUpgrade.api.registry.hash(currentWasm) + + // Create the authorize upgrade call (could be local or XCM-based) + const authorizeUpgradeCall = + governingChain.url === chainToUpgrade.url + ? params.call(currentWasmHash) + : governingChain.api.tx.utility.forceBatch([ + (() => { + const call = chainToUpgrade.api.tx.system.authorizeUpgrade(currentWasmHash) + const dest = getXcmRoute(governingChain.config, chainToUpgrade.config) + return createXcmTransactSend(governingChain, dest, call.method.toHex(), 'Superuser', { + refTime: '5000000000', + proofSize: '500000', + }) + })(), + ]) + + // Create and fast-track a Root referendum with the authorize upgrade call + await createAndFastTrackReferendum(governingChain, authorizeUpgradeCall, { system: 'Root' }, testConfig.blockProvider) + + // Apply the authorized upgrade + const applyCall = chainToUpgrade.api.tx.system.applyAuthorizedUpgrade(compactAddLength(currentWasm)) + await sendTransaction(applyCall.signAsync(alice)) + + await chainToUpgrade.dev.newBlock({ count: 1 }) + + if (chainToUpgrade.config.isRelayChain) { + assertExpectedEvents(await chainToUpgrade.api.query.system.events(), params.expectedAfterApply(currentWasmHash)) + } else { + const eventsAfterFirstBlock = await chainToUpgrade.api.query.system.events() + await chainToUpgrade.dev.newBlock({ count: 1 }) + const eventsAfterSecondBlock = await chainToUpgrade.api.query.system.events() + assertExpectedEvents( + eventsAfterFirstBlock.concat(eventsAfterSecondBlock), + params.expectedAfterApply(currentWasmHash), + ) + } +} + +/** + * Runs the authorize upgrade + apply authorized upgrade scenario via WhitelistedCaller track referendum. + * + * This test demonstrates the full governance flow with collectives integration: + * 1. Fetches current runtime WASM and hashes it + * 2. Uses authorizeUpgradeViaCollectives flow to whitelist the upgrade call + * 3. Creates a WhitelistedCaller track referendum that dispatches the whitelisted call + * 4. Fast-tracks the referendum to approval + * 5. The referendum executes the whitelisted call, which authorizes the upgrade + * 6. Applies the upgrade with applyAuthorizedUpgrade + * 7. Verifies expected events + * + * @param governingChain - The chain where the governance is running + * @param chainToUpgrade - The chain whose runtime is being upgraded + * @param fellowshipChain - The chain that hosts the collective body + * @param testConfig - Test configuration + * @param params - Contains the authorizeUpgrade call variant and expected events + */ +async function runAuthorizeUpgradeViaWhitelistedCallerReferendum( + governingChain: Client, + chainToUpgrade: Client, + fellowshipChain: Client, + testConfig: TestConfig, + params: { + call: AuthorizeUpgradeFn + expectedAfterApply: (hash: IU8a) => ExpectedEvents + }, +) { + const alice = devAccounts.alice + + const currentWasm = bufferToU8a(Buffer.from((await chainToUpgrade.chain.head.wasm).slice(2), 'hex')) + const currentWasmHash = chainToUpgrade.api.registry.hash(currentWasm) + + // Create the authorize upgrade call (could be local or XCM-based) + const authorizeUpgradeCall = + governingChain.url === chainToUpgrade.url + ? params.call(currentWasmHash) + : governingChain.api.tx.utility.forceBatch([ + (() => { + const call = chainToUpgrade.api.tx.system.authorizeUpgrade(currentWasmHash) + const dest = getXcmRoute(governingChain.config, chainToUpgrade.config) + return createXcmTransactSend(governingChain, dest, call.method.toHex(), 'Superuser', { + refTime: '5000000000', + proofSize: '500000', + }) + })(), + ]) + + // First, whitelist the authorize upgrade call via collectives (before creating the referendum) + await sendWhitelistCallViaXcmTransact(governingChain, fellowshipChain, authorizeUpgradeCall.method.hash.toHex(), { + proofSize: '10000', + refTime: '500000000', + }) + await fellowshipChain.dev.newBlock() + await governingChain.dev.newBlock() + + // Now create the whitelisted dispatch call + const whitelistedDispatchCall = governingChain.api.tx.whitelist.dispatchWhitelistedCallWithPreimage( + authorizeUpgradeCall.method.toHex(), + ) + + // Create and fast-track a WhitelistedCaller referendum + await createAndFastTrackReferendum( + governingChain, + whitelistedDispatchCall, + { Origins: 'WhitelistedCaller' }, + testConfig.blockProvider, + ) + + // Apply the authorized upgrade + const applyCall = chainToUpgrade.api.tx.system.applyAuthorizedUpgrade(compactAddLength(currentWasm)) + await sendTransaction(applyCall.signAsync(alice)) + + await chainToUpgrade.dev.newBlock({ count: 1 }) + + if (chainToUpgrade.config.isRelayChain) { + assertExpectedEvents(await chainToUpgrade.api.query.system.events(), params.expectedAfterApply(currentWasmHash)) + } else { + const eventsAfterFirstBlock = await chainToUpgrade.api.query.system.events() + await chainToUpgrade.dev.newBlock({ count: 1 }) + const eventsAfterSecondBlock = await chainToUpgrade.api.query.system.events() + assertExpectedEvents( + eventsAfterFirstBlock.concat(eventsAfterSecondBlock), + params.expectedAfterApply(currentWasmHash), + ) + } +} + +/** + * Tests `authorizeUpgrade` flow via Root track referendum — upgrade to same WASM should fail validation. + */ +export async function authorizeUpgradeViaRootReferendumTests< + TCustom extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, + TInitStoragesPara extends Record> | undefined, +>( + governanceChain: Chain, + toBeUpgradedChain: Chain, + testConfig: TestConfig, +) { + let governanceClient: Client + let toBeUpgradedClient: Client + + if (governanceChain.url === toBeUpgradedChain.url) { + ;[governanceClient] = await setupNetworks(governanceChain) + toBeUpgradedClient = governanceClient + } else { + ;[governanceClient, toBeUpgradedClient] = await setupNetworks(governanceChain, toBeUpgradedChain) + } + return runAuthorizeUpgradeViaRootReferendum(governanceClient, toBeUpgradedClient, testConfig, { + call: toBeUpgradedClient.api.tx.system.authorizeUpgrade, + expectedAfterApply: (hash) => [ + { + type: toBeUpgradedClient.api.events.system.RejectedInvalidAuthorizedUpgrade, + args: { + codeHash: hash, + error: (r: any) => toBeUpgradedClient.api.errors.system.SpecVersionNeedsToIncrease.is(r.asModule), + }, + }, + ], + }) +} + +/** + * Tests `authorizeUpgradeWithoutChecks` via Root track referendum — upgrade to same WASM should succeed. + */ +export async function authorizeUpgradeWithoutChecksViaRootReferendumTests< + TCustom extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, + TInitStoragesPara extends Record> | undefined, +>( + governanceChain: Chain, + toBeUpgradedChain: Chain, + testConfig: TestConfig, +) { + let governanceClient: Client + let toBeUpgradedClient: Client + + if (governanceChain.url === toBeUpgradedChain.url) { + ;[governanceClient] = await setupNetworks(governanceChain) + toBeUpgradedClient = governanceClient + } else { + ;[governanceClient, toBeUpgradedClient] = await setupNetworks(governanceChain, toBeUpgradedChain) + } + + let expectedEvents: ExpectedEvents = [] + if (toBeUpgradedChain.isRelayChain) { + expectedEvents = [{ type: toBeUpgradedClient.api.events.system.CodeUpdated }] + } else { + expectedEvents = [ + { type: toBeUpgradedClient.api.events.parachainSystem.ValidationFunctionStored }, + { type: toBeUpgradedClient.api.events.parachainSystem.ValidationFunctionApplied }, + { type: toBeUpgradedClient.api.events.system.CodeUpdated }, + ] + } + + return runAuthorizeUpgradeViaRootReferendum(governanceClient, toBeUpgradedClient, testConfig, { + call: toBeUpgradedClient.api.tx.system.authorizeUpgradeWithoutChecks, + expectedAfterApply: () => expectedEvents, + }) +} + +/** + * Tests `authorizeUpgrade` flow via WhitelistedCaller track referendum with collectives — upgrade to same WASM should fail validation. + */ +export async function authorizeUpgradeViaWhitelistedCallerReferendumTests< + TCustomRelay extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, + TInitStoragesPara extends Record> | undefined, + TCustomCollectives extends Record | undefined, + TInitStoragesCollectives extends Record> | undefined, +>( + governanceChain: Chain, + toBeUpgradedChain: Chain, + fellowshipChain: Chain, + testConfig: TestConfig, +) { + let governanceClient: Client + let toBeUpgradedClient: Client + let fellowshipClient: Client + + if (governanceChain.url === toBeUpgradedChain.url) { + ;[governanceClient, fellowshipClient] = await setupNetworks(governanceChain, fellowshipChain) + toBeUpgradedClient = governanceClient + } else { + ;[governanceClient, toBeUpgradedClient, fellowshipClient] = await setupNetworks( + governanceChain, + toBeUpgradedChain, + fellowshipChain, + ) + } + return runAuthorizeUpgradeViaWhitelistedCallerReferendum( + governanceClient, + toBeUpgradedClient, + fellowshipClient, + testConfig, + { + call: toBeUpgradedClient.api.tx.system.authorizeUpgrade, + expectedAfterApply: (hash) => [ + { + type: toBeUpgradedClient.api.events.system.RejectedInvalidAuthorizedUpgrade, + args: { + codeHash: hash, + error: (r: any) => toBeUpgradedClient.api.errors.system.SpecVersionNeedsToIncrease.is(r.asModule), + }, + }, + ], + }, + ) +} + +/** + * Tests `authorizeUpgradeWithoutChecks` via WhitelistedCaller track referendum with collectives — upgrade to same WASM should succeed. + */ +export async function authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests< + TCustomRelay extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, + TInitStoragesPara extends Record> | undefined, + TCustomCollectives extends Record | undefined, + TInitStoragesCollectives extends Record> | undefined, +>( + governanceChain: Chain, + toBeUpgradedChain: Chain, + fellowshipChain: Chain, + testConfig: TestConfig, +) { + let governanceClient: Client + let toBeUpgradedClient: Client + let fellowshipClient: Client + + if (governanceChain.url === toBeUpgradedChain.url) { + ;[governanceClient, fellowshipClient] = await setupNetworks(governanceChain, fellowshipChain) + toBeUpgradedClient = governanceClient + } else { + ;[governanceClient, toBeUpgradedClient, fellowshipClient] = await setupNetworks( + governanceChain, + toBeUpgradedChain, + fellowshipChain, + ) + } + + let expectedEvents: ExpectedEvents = [] + if (toBeUpgradedChain.isRelayChain) { + expectedEvents = [{ type: toBeUpgradedClient.api.events.system.CodeUpdated }] + } else { + expectedEvents = [ + { type: toBeUpgradedClient.api.events.parachainSystem.ValidationFunctionStored }, + { type: toBeUpgradedClient.api.events.parachainSystem.ValidationFunctionApplied }, + { type: toBeUpgradedClient.api.events.system.CodeUpdated }, + ] + } + + return runAuthorizeUpgradeViaWhitelistedCallerReferendum( + governanceClient, + toBeUpgradedClient, + fellowshipClient, + testConfig, + { + call: toBeUpgradedClient.api.tx.system.authorizeUpgradeWithoutChecks, + expectedAfterApply: () => expectedEvents, + }, + ) +} + +/** + * Test suite for self-upgrade scenarios via Root track referendum. + * + * Tests a governance chain upgrading its own runtime through a fast-tracked Root referendum. + * The full flow includes: + * 1. Creating a referendum with an authorize_upgrade call + * 2. Fast-tracking the referendum to immediate approval + * 3. Applying the authorized upgrade + * 4. Verifying the upgrade outcome + * + * This suite covers both `authorizeUpgrade` (which validates WASM and should fail for same version) + * and `authorizeUpgradeWithoutChecks` (which skips validation and should succeed). + * + * @param governanceChain - The chain configuration that will upgrade itself + * @param testConfig - Test configuration including block provider and test suite name + * @returns A test tree with Root referendum upgrade scenarios + */ +export function governanceChainSelfUpgradeViaRootReferendumSuite< + TCustomRelay extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, +>(governanceChain: Chain, testConfig: TestConfig): RootTestTree { + return { + kind: 'describe', + label: testConfig.testSuiteName, + children: [ + { + kind: 'test', + label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via Root referendum)`, + testFn: async () => + await authorizeUpgradeWithoutChecksViaRootReferendumTests(governanceChain, governanceChain, testConfig), + }, + { + kind: 'test', + label: `authorize_upgrade doesnt allow upgrade to the same wasm (via Root referendum)`, + testFn: async () => await authorizeUpgradeViaRootReferendumTests(governanceChain, governanceChain, testConfig), + }, + ], + } +} + +/** + * Test suite for cross-chain upgrade scenarios via Root track referendum. + * + * Tests a governance chain (e.g., relay chain) upgrading another chain (e.g., system parachain) + * through a fast-tracked Root referendum. The authorization call is sent via XCM Transact. + * + * The full flow includes: + * 1. Creating a referendum with an XCM message containing authorize_upgrade + * 2. Fast-tracking the referendum to immediate approval + * 3. Executing the XCM on the target chain to authorize the upgrade + * 4. Applying the authorized upgrade on the target chain + * 5. Verifying the upgrade outcome + * + * This suite covers both `authorizeUpgrade` (which validates WASM and should fail for same version) + * and `authorizeUpgradeWithoutChecks` (which skips validation and should succeed). + * + * @param governanceChain - The chain that governs and can execute Root calls (e.g., relay chain) + * @param toBeUpgradedChain - The chain whose runtime will be upgraded (e.g., system parachain) + * @param testConfig - Test configuration including block provider and test suite name + * @returns A test tree with cross-chain Root referendum upgrade scenarios + */ +export function governanceChainUpgradesOtherChainViaRootReferendumSuite< + TCustomRelay extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, + TInitStoragesPara extends Record> | undefined, +>( + governanceChain: Chain, + toBeUpgradedChain: Chain, + testConfig: TestConfig, +): RootTestTree { + return { + kind: 'describe', + label: testConfig.testSuiteName, + children: [ + { + kind: 'test', + label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via Root referendum)`, + testFn: async () => + await authorizeUpgradeWithoutChecksViaRootReferendumTests(governanceChain, toBeUpgradedChain, testConfig), + }, + { + kind: 'test', + label: `authorize_upgrade doesnt allow upgrade to the same wasm (via Root referendum)`, + testFn: async () => await authorizeUpgradeViaRootReferendumTests(governanceChain, governanceChain, testConfig), + }, + ], + } +} + +/** + * Test suite for self-upgrade scenarios via WhitelistedCaller track referendum with Fellowship approval. + * + * Tests a governance chain upgrading its own runtime through a WhitelistedCaller referendum, + * with the upgrade call whitelisted by the Fellowship collective. + * + * The full flow includes: + * 1. Whitelisting the authorize_upgrade call via Fellowship (XCM from Fellowship to governance chain) + * 2. Creating a WhitelistedCaller referendum with dispatchWhitelistedCallWithPreimage + * 3. Fast-tracking the referendum to immediate approval + * 4. Executing the whitelisted call to authorize the upgrade + * 5. Applying the authorized upgrade + * 6. Verifying the upgrade outcome + * + * This demonstrates the two-step governance process where: + * - Fellowship (technical experts) whitelist the upgrade as technically sound + * - WhitelistedCaller referendum (token holders) approve executing it + * + * @param governanceChain - The chain that will upgrade itself (e.g., relay chain) + * @param fellowshipChain - The Fellowship collective chain that whitelists calls (e.g., Collectives parachain) + * @param testConfig - Test configuration including block provider and test suite name + * @returns A test tree with WhitelistedCaller referendum self-upgrade scenarios + */ +export function governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite< + TCustomRelay extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TInitStoragesPara extends Record> | undefined, +>( + governanceChain: Chain, + fellowshipChain: Chain, + testConfig: TestConfig, +): RootTestTree { + return { + kind: 'describe', + label: testConfig.testSuiteName, + children: [ + { + kind: 'test', + label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, + testFn: async () => + await authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests( + governanceChain, + governanceChain, + fellowshipChain, + testConfig, + ), + }, + { + kind: 'test', + label: `authorize_upgrade doesnt allow upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, + testFn: async () => + await authorizeUpgradeViaWhitelistedCallerReferendumTests( + governanceChain, + governanceChain, + fellowshipChain, + testConfig, + ), + }, + ], + } +} + +/** + * Test suite for cross-chain upgrade scenarios via WhitelistedCaller track referendum with Fellowship approval. + * + * Tests a governance chain (e.g., relay chain) upgrading another chain (e.g., system parachain) + * through a WhitelistedCaller referendum, with the upgrade call whitelisted by the Fellowship collective. + * + * The full flow includes: + * 1. Whitelisting the XCM-wrapped authorize_upgrade call via Fellowship + * 2. Creating a WhitelistedCaller referendum with dispatchWhitelistedCallWithPreimage + * 3. Fast-tracking the referendum to immediate approval + * 4. Executing the whitelisted call which sends XCM to the target chain + * 5. Authorizing the upgrade on the target chain via XCM Transact + * 6. Applying the authorized upgrade on the target chain + * 7. Verifying the upgrade outcome + * + * This demonstrates the two-step governance process for cross-chain operations where: + * - Fellowship (technical experts) whitelist the upgrade as technically sound + * - WhitelistedCaller referendum (token holders) approve executing it + * - The upgrade is applied to a different chain via XCM + * + * @param governanceChain - The chain that governs and initiates the upgrade (e.g., relay chain) + * @param toBeUpgradedChain - The chain whose runtime will be upgraded (e.g., system parachain) + * @param fellowshipChain - The Fellowship collective chain that whitelists calls (e.g., Collectives parachain) + * @param testConfig - Test configuration including block provider and test suite name + * @returns A test tree with cross-chain WhitelistedCaller referendum upgrade scenarios + */ +export function governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite< + TCustomRelay extends Record | undefined, + TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, + TInitStoragesPara extends Record> | undefined, +>( + governanceChain: Chain, + toBeUpgradedChain: Chain, + fellowshipChain: Chain, + testConfig: TestConfig, +): RootTestTree { + return { + kind: 'describe', + label: testConfig.testSuiteName, + children: [ + { + kind: 'test', + label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, + testFn: async () => + await authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests( + governanceChain, + toBeUpgradedChain, + fellowshipChain, + testConfig, + ), + }, + { + kind: 'test', + label: `authorize_upgrade doesnt allow upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, + testFn: async () => + await authorizeUpgradeViaWhitelistedCallerReferendumTests( + governanceChain, + governanceChain, + fellowshipChain, + testConfig, + ), + }, + ], + } +} From 51ece98a9b645a0c25500fdb9236694b4bde0863 Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 31 Oct 2025 15:34:40 +0100 Subject: [PATCH 02/11] Fix imports --- .../kusama/src/assetHubKusama.bridgeHubKusama.test.ts | 8 ++++++-- .../kusama/src/assetHubKusama.coretimeKusama.test.ts | 8 ++++++-- packages/kusama/src/assetHubKusama.kusama.test.ts | 8 +++++--- packages/kusama/src/assetHubKusama.peopleKusama.test.ts | 8 ++++++-- packages/kusama/src/assetHubKusama.system.e2e.test.ts | 8 ++++++-- packages/kusama/src/encointer.assetHubKusama.test.ts | 8 ++++++-- .../polkadot/src/collectivesPolkadot.polkadot.test.ts | 9 ++++++--- ...polkadot.assetHubPolkadot.collectivesPolkadot.test.ts | 3 +-- ...olkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts | 3 +-- ...polkadot.coretimePolkadot.collectivesPolkadot.test.ts | 3 +-- .../polkadot.peoplePolkadot.collectivesPolkadot.test.ts | 3 +-- packages/polkadot/src/polkadot.system.e2e.test.ts | 8 ++++++-- packages/shared/src/index.ts | 1 + 13 files changed, 52 insertions(+), 26 deletions(-) diff --git a/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts b/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts index c37c551bd..beb4b0a2f 100644 --- a/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts +++ b/packages/kusama/src/assetHubKusama.bridgeHubKusama.test.ts @@ -1,8 +1,12 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, bridgeHubKusama } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' -import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' diff --git a/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts b/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts index 76478b7a6..a877bad60 100644 --- a/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts +++ b/packages/kusama/src/assetHubKusama.coretimeKusama.test.ts @@ -1,8 +1,12 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, coretimeKusama } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' -import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' diff --git a/packages/kusama/src/assetHubKusama.kusama.test.ts b/packages/kusama/src/assetHubKusama.kusama.test.ts index 0c1ef13c4..ebb76ae88 100644 --- a/packages/kusama/src/assetHubKusama.kusama.test.ts +++ b/packages/kusama/src/assetHubKusama.kusama.test.ts @@ -1,11 +1,13 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, kusama } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' -import { query, tx } from '@e2e-test/shared/api' import { governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite, governanceChainUpgradesOtherChainViaRootReferendumSuite, -} from '@e2e-test/shared/upgrade' + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' +import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletDown, runXcmPalletUp } from '@e2e-test/shared/xcm' import { describe } from 'vitest' diff --git a/packages/kusama/src/assetHubKusama.peopleKusama.test.ts b/packages/kusama/src/assetHubKusama.peopleKusama.test.ts index b39271701..3fc59dc52 100644 --- a/packages/kusama/src/assetHubKusama.peopleKusama.test.ts +++ b/packages/kusama/src/assetHubKusama.peopleKusama.test.ts @@ -1,8 +1,12 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubKusama, peopleKusama } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' -import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' diff --git a/packages/kusama/src/assetHubKusama.system.e2e.test.ts b/packages/kusama/src/assetHubKusama.system.e2e.test.ts index fa6897e5c..4e943b6b4 100644 --- a/packages/kusama/src/assetHubKusama.system.e2e.test.ts +++ b/packages/kusama/src/assetHubKusama.system.e2e.test.ts @@ -1,6 +1,10 @@ import { assetHubKusama } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, systemE2ETestsForParaWithScheduler } from '@e2e-test/shared' -import { governanceChainSelfUpgradeViaRootReferendumSuite } from '@e2e-test/shared/upgrade' +import { + governanceChainSelfUpgradeViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + systemE2ETestsForParaWithScheduler, +} from '@e2e-test/shared' // TODO: Uncomment after Kusama 2.0+ release due to polkadot-fellows/runtimes#957 // const testConfig: ParaTestConfig = { diff --git a/packages/kusama/src/encointer.assetHubKusama.test.ts b/packages/kusama/src/encointer.assetHubKusama.test.ts index e1f03610d..8629a8df1 100644 --- a/packages/kusama/src/encointer.assetHubKusama.test.ts +++ b/packages/kusama/src/encointer.assetHubKusama.test.ts @@ -1,8 +1,12 @@ import { defaultAccountsSr25519 } from '@e2e-test/networks' import { assetHubKusama, encointerKusama } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' -import { governanceChainUpgradesOtherChainViaRootReferendumSuite } from '@e2e-test/shared/upgrade' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' import { describe } from 'vitest' diff --git a/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts b/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts index c339806a4..21654e675 100644 --- a/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts +++ b/packages/polkadot/src/collectivesPolkadot.polkadot.test.ts @@ -1,10 +1,13 @@ import { collectivesPolkadot, polkadot } from '@e2e-test/networks/chains' -import { baseCollectivesChainE2ETests, registerTestTree, setupNetworks, type TestConfig } from '@e2e-test/shared' -import { query, tx } from '@e2e-test/shared/api' import { authorizeUpgradeViaCollectives, + baseCollectivesChainE2ETests, governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite, -} from '@e2e-test/shared/upgrade.js' + registerTestTree, + setupNetworks, + type TestConfig, +} from '@e2e-test/shared' +import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletDown, runXcmPalletUp } from '@e2e-test/shared/xcm' import { describe, test } from 'vitest' diff --git a/packages/polkadot/src/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts index fca460e07..3b563177b 100644 --- a/packages/polkadot/src/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,5 @@ import { assetHubPolkadot, collectivesPolkadot, polkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { authorizeUpgradeViaCollectives, setupNetworks } from '@e2e-test/shared' import { describe, test } from 'vitest' diff --git a/packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts index a8e53db27..15ff5b6e7 100644 --- a/packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,5 @@ import { bridgeHubPolkadot, collectivesPolkadot, polkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { authorizeUpgradeViaCollectives, setupNetworks } from '@e2e-test/shared' import { describe, test } from 'vitest' diff --git a/packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts index db766a199..33351ea0f 100644 --- a/packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,5 @@ import { collectivesPolkadot, coretimePolkadot, polkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { authorizeUpgradeViaCollectives, setupNetworks } from '@e2e-test/shared' import { describe, test } from 'vitest' diff --git a/packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts index b65dde86c..938f1d0b2 100644 --- a/packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,5 @@ import { collectivesPolkadot, peoplePolkadot, polkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { authorizeUpgradeViaCollectives, setupNetworks } from '@e2e-test/shared' import { describe, test } from 'vitest' diff --git a/packages/polkadot/src/polkadot.system.e2e.test.ts b/packages/polkadot/src/polkadot.system.e2e.test.ts index 9075b0965..7156b188a 100644 --- a/packages/polkadot/src/polkadot.system.e2e.test.ts +++ b/packages/polkadot/src/polkadot.system.e2e.test.ts @@ -1,6 +1,10 @@ import { polkadot } from '@e2e-test/networks/chains' -import { type RelayTestConfig, registerTestTree, systemE2ETests } from '@e2e-test/shared' -import { governanceChainSelfUpgradeViaRootReferendumSuite } from '@e2e-test/shared/upgrade' +import { + governanceChainSelfUpgradeViaRootReferendumSuite, + type RelayTestConfig, + registerTestTree, + systemE2ETests, +} from '@e2e-test/shared' const testConfig: RelayTestConfig = { testSuiteName: 'Polkadot System', diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 9d8f3172f..c7d507e1a 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -15,4 +15,5 @@ export * from './staking.js' export * from './system.js' export * from './treasury.js' export * from './types.js' +export * from './upgrade.js' export * from './vesting.js' From 583a5387ffc88430f667a92e6b952e3afe3c66e8 Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 31 Oct 2025 15:41:38 +0100 Subject: [PATCH 03/11] use getBlockNumber with correct provider --- packages/shared/src/upgrade.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/upgrade.ts b/packages/shared/src/upgrade.ts index 8fa103337..7e721d5fa 100644 --- a/packages/shared/src/upgrade.ts +++ b/packages/shared/src/upgrade.ts @@ -16,6 +16,7 @@ import { checkEvents, checkSystemEvents, createXcmTransactSend, + getBlockNumber, getXcmRoute, nextSchedulableBlockNum, scheduleInlineCallWithOrigin, @@ -230,8 +231,7 @@ async function createAndFastTrackReferendum( // Get total issuance for realistic tally values const totalIssuance = (await client.api.query.balances.totalIssuance()).toBigInt() - // Get current block number - const currentBlock = (await client.api.rpc.chain.getHeader()).number.toNumber() + const currentBlock = await getBlockNumber(client.api, blockProvider) // Support Lookup, Inline or Legacy proposals const callHash = ongoing.proposal.isLookup From 5caad736c4b4dd8844cb174ee03aab8e10c5f5fb Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 31 Oct 2025 16:04:33 +0100 Subject: [PATCH 04/11] Bring back old snapshot data --- .../__snapshots__/assetHubPolkadot.polkadot.test.ts.snap | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap b/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap index 87b00bb25..d9a088ad5 100644 --- a/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap +++ b/packages/polkadot/src/__snapshots__/assetHubPolkadot.polkadot.test.ts.snap @@ -155,7 +155,7 @@ exports[`assetHubPolkadot & polkadot > Teleport DOT from Asset Hub to Polkadot > "Complete": { "used": { "proofSize": "(rounded 400000)", - "refTime": "(rounded 50000000000)", + "refTime": "(rounded 40000000000)", }, }, }, @@ -210,7 +210,7 @@ exports[`assetHubPolkadot & polkadot > Teleport DOT from Polkadot to Asset Hub > "dmqHead": "(hash)", "weightUsed": { "proofSize": "(rounded 4000)", - "refTime": "(rounded 800000000)", + "refTime": "(rounded 1000000000)", }, }, "method": "DownwardMessagesProcessed", @@ -222,7 +222,7 @@ exports[`assetHubPolkadot & polkadot > Teleport DOT from Polkadot to Asset Hub > "origin": "Parent", "success": true, "weightUsed": { - "proofSize": "(rounded 9000)", + "proofSize": "(rounded 7000)", "refTime": "(rounded 600000000)", }, }, From 72a5282013ebee16614ba810c2750fcd663d7b9a Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 7 Nov 2025 17:46:32 +0100 Subject: [PATCH 05/11] System e2e cleanup --- .../polkadot/src/assetHubPolkadot.system.e2e.test.ts | 10 ---------- .../polkadot/src/bridgeHubPolkadot.system.e2e.test.ts | 10 ---------- .../src/collectivesPolkadot.system.e2e.test.ts | 3 --- .../polkadot/src/coretimePolkadot.system.e2e.test.ts | 9 --------- .../polkadot/src/peoplePolkadot.system.e2e.test.ts | 10 ---------- packages/polkadot/src/polkadot.system.e2e.test.ts | 11 ----------- 6 files changed, 53 deletions(-) diff --git a/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts b/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts index 7c5232b58..b801f3d9f 100644 --- a/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts @@ -1,16 +1,6 @@ import { assetHubPolkadot } from '@e2e-test/networks/chains' import { type ParaTestConfig, registerTestTree, systemE2ETestsForParaWithScheduler } from '@e2e-test/shared' -/* const testConfig: ParaTestConfig = { - testSuiteName: 'Polkadot AssetHub System', - addressEncoding: 0, - blockProvider: 'Local', - asyncBacking: 'Enabled', -} - -registerTestTree(systemE2ETests(assetHubPolkadot, testConfig)) - */ - const testConfigForLocalScheduler: ParaTestConfig = { testSuiteName: 'Polkadot AssetHub System', addressEncoding: 0, diff --git a/packages/polkadot/src/bridgeHubPolkadot.system.e2e.test.ts b/packages/polkadot/src/bridgeHubPolkadot.system.e2e.test.ts index 650d1dcf5..16a3773b0 100644 --- a/packages/polkadot/src/bridgeHubPolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/bridgeHubPolkadot.system.e2e.test.ts @@ -1,16 +1,6 @@ import { assetHubPolkadot, bridgeHubPolkadot } from '@e2e-test/networks/chains' import { type ParaTestConfig, registerTestTree, systemE2ETestsViaRemoteScheduler } from '@e2e-test/shared' -/* const testConfig: ParaTestConfig = { - testSuiteName: 'Polkadot BridgeHub System', - addressEncoding: 0, - blockProvider: 'Local', - asyncBacking: 'Enabled', -} - -registerTestTree(systemE2ETestsViaRemoteScheduler(polkadot, bridgeHubPolkadot, testConfig)) -*/ - const testConfigForAssetHub: ParaTestConfig = { testSuiteName: 'Polkadot BridgeHub System', addressEncoding: 0, diff --git a/packages/polkadot/src/collectivesPolkadot.system.e2e.test.ts b/packages/polkadot/src/collectivesPolkadot.system.e2e.test.ts index 8810881df..01c1db5e7 100644 --- a/packages/polkadot/src/collectivesPolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/collectivesPolkadot.system.e2e.test.ts @@ -13,11 +13,8 @@ const testConfig: ParaTestConfig = { asyncBacking: 'Enabled', } -//registerTestTree(systemE2ETestsViaRemoteScheduler(polkadot, collectivesPolkadot, testConfig)) registerTestTree(systemE2ETestsForParaWithScheduler(collectivesPolkadot, testConfig)) -// TODO: Uncomment Post-AHM on Polkadot - const testConfigForAssetHub: ParaTestConfig = { testSuiteName: 'Polkadot Collectives System', addressEncoding: 0, diff --git a/packages/polkadot/src/coretimePolkadot.system.e2e.test.ts b/packages/polkadot/src/coretimePolkadot.system.e2e.test.ts index 4479e2ce3..3e1ee7d6c 100644 --- a/packages/polkadot/src/coretimePolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/coretimePolkadot.system.e2e.test.ts @@ -1,15 +1,6 @@ import { assetHubPolkadot, coretimePolkadot } from '@e2e-test/networks/chains' import { type ParaTestConfig, registerTestTree, systemE2ETestsViaRemoteScheduler } from '@e2e-test/shared' -/* const testConfig: ParaTestConfig = { - testSuiteName: 'Polkadot Coretime System', - addressEncoding: 0, - blockProvider: 'Local', - asyncBacking: 'Enabled', -} - -registerTestTree(systemE2ETestsViaRemoteScheduler(polkadot, coretimePolkadot, testConfig)) */ - const testConfigForAssetHub: ParaTestConfig = { testSuiteName: 'Polkadot Coretime System', addressEncoding: 0, diff --git a/packages/polkadot/src/peoplePolkadot.system.e2e.test.ts b/packages/polkadot/src/peoplePolkadot.system.e2e.test.ts index d879351a8..d6b01be4f 100644 --- a/packages/polkadot/src/peoplePolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/peoplePolkadot.system.e2e.test.ts @@ -1,16 +1,6 @@ import { assetHubPolkadot, peoplePolkadot } from '@e2e-test/networks/chains' import { type ParaTestConfig, registerTestTree, systemE2ETestsViaRemoteScheduler } from '@e2e-test/shared' -/* const testConfig: ParaTestConfig = { - testSuiteName: 'Polkadot People System', - addressEncoding: 0, - blockProvider: 'Local', - asyncBacking: 'Enabled', -} - -registerTestTree(systemE2ETestsViaRemoteScheduler(polkadot, peoplePolkadot, testConfig)) -*/ - const testConfigForAssetHub: ParaTestConfig = { testSuiteName: 'Polkadot People System', addressEncoding: 0, diff --git a/packages/polkadot/src/polkadot.system.e2e.test.ts b/packages/polkadot/src/polkadot.system.e2e.test.ts index 08e8db59f..c4ff3875b 100644 --- a/packages/polkadot/src/polkadot.system.e2e.test.ts +++ b/packages/polkadot/src/polkadot.system.e2e.test.ts @@ -9,14 +9,3 @@ const testConfigForAssetHub: ParaTestConfig = { } registerTestTree(systemE2ETestsViaRemoteScheduler(assetHubPolkadot, polkadot, testConfigForAssetHub)) - -// TODO: Uncomment Post-AHM on Polkadot - -// const testConfigForAssetHub: ParaTestConfig = { -// testSuiteName: 'Polkadot System', -// addressEncoding: 0, -// blockProvider: 'NonLocal', -// asyncBacking: 'Enabled', -// } - -// registerTestTree(systemE2ETestsViaRemoteScheduler(assetHubPolkadot, polkadot, testConfigForAssetHub)) From 9e6fcc9d2ac181345ccc40f7bceb03845db3a215 Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 7 Nov 2025 18:59:28 +0100 Subject: [PATCH 06/11] Adapt to post-AHM state --- ...assetHubPolkadot.bridgeHubPolkadot.test.ts | 31 ++++++++------ ...setHubPolkadot.collectivesPolkadot.test.ts | 42 ++++++++++++------- .../assetHubPolkadot.coretimePolkadot.test.ts | 31 ++++++++------ .../assetHubPolkadot.peoplePolkadot.test.ts | 31 ++++++++------ .../src/assetHubPolkadot.polkadot.test.ts | 27 ++++++------ 5 files changed, 99 insertions(+), 63 deletions(-) diff --git a/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts index df9436cb1..19c5717ab 100644 --- a/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.test.ts @@ -1,6 +1,11 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubPolkadot, bridgeHubPolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' @@ -43,15 +48,17 @@ describe('assetHubPolkadot & bridgeHubPolkadot', async () => { ) }) -// TODO: Uncomment Post-AHM on Polkadot +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubPolkadot & bridgeHubPolkadot', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} -// const testConfigForLocalScheduler: ParaTestConfig = { -// testSuiteName: 'assetHubPolkadot & bridgeHubPolkadot', -// addressEncoding: 0, -// blockProvider: 'NonLocal', -// asyncBacking: 'Enabled', -// } - -// registerTestTree( -// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, bridgeHubPolkadot, testConfigForLocalScheduler), -// ) +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite( + assetHubPolkadot, + bridgeHubPolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts index a3f112792..ad149d353 100644 --- a/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,12 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubPolkadot, collectivesPolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { + governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite, + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' @@ -47,19 +53,25 @@ describe('assetHubPolkadot & collectivesPolkadot', async () => { ) }) -// // TODO: Uncomment Post-AHM on Polkadot +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubPolkadot & collectivesPolkadot', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} -// const testConfigForLocalScheduler: ParaTestConfig = { -// testSuiteName: 'assetHubPolkadot & collectivesPolkadot', -// addressEncoding: 0, -// blockProvider: 'NonLocal', -// asyncBacking: 'Enabled', -// } +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite( + assetHubPolkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) -// registerTestTree( -// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, collectivesPolkadot, testConfigForLocalScheduler), -// ) - -// registerTestTree( -// governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite(assetHubPolkadot, collectivesPolkadot, testConfigForLocalScheduler), -// ) +registerTestTree( + governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite( + assetHubPolkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts index f3fc12818..1f45e3e51 100644 --- a/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.test.ts @@ -1,6 +1,11 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubPolkadot, coretimePolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' @@ -43,15 +48,17 @@ describe('assetHubPolkadot & coretimePolkadot', async () => { ) }) -// TODO: Uncomment Post-AHM on Polkadot +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubPolkadot & coretimePolkadot', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} -// const testConfigForLocalScheduler: ParaTestConfig = { -// testSuiteName: 'assetHubPolkadot & coretimePolkadot', -// addressEncoding: 0, -// blockProvider: 'NonLocal', -// asyncBacking: 'Enabled', -// } - -// registerTestTree( -// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, coretimePolkadot, testConfigForLocalScheduler), -// ) +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite( + assetHubPolkadot, + coretimePolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts index 486ea8eaa..2d8b52e63 100644 --- a/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.test.ts @@ -1,6 +1,11 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubPolkadot, peoplePolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletHorizontal } from '@e2e-test/shared/xcm' @@ -43,15 +48,17 @@ describe('assetHubPolkadot & peoplePolkadot', async () => { ) }) -// TODO: Uncomment Post-AHM on Polkadot +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubPolkadot & peoplePolkadot', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} -// const testConfigForLocalScheduler: ParaTestConfig = { -// testSuiteName: 'assetHubPolkadot & peoplePolkadot', -// addressEncoding: 0, -// blockProvider: 'NonLocal', -// asyncBacking: 'Enabled', -// } - -// registerTestTree( -// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, peoplePolkadot, testConfigForLocalScheduler), -// ) +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite( + assetHubPolkadot, + peoplePolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts index 3b8a0b60f..0db8eb12c 100644 --- a/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.polkadot.test.ts @@ -1,6 +1,11 @@ import { defaultAccounts } from '@e2e-test/networks' import { assetHubPolkadot, polkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' +import { + governanceChainUpgradesOtherChainViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { query, tx } from '@e2e-test/shared/api' import { runXcmPalletDown, runXcmPalletUp } from '@e2e-test/shared/xcm' @@ -176,15 +181,13 @@ describe('assetHubPolkadot & polkadot', async () => { }) }) -// TODO: Uncomment Post-AHM on Polkadot +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'assetHubPolkadot & polkadot', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} -// const testConfigForLocalScheduler: ParaTestConfig = { -// testSuiteName: 'assetHubPolkadot & polkadot', -// addressEncoding: 0, -// blockProvider: 'NonLocal', -// asyncBacking: 'Enabled', -// } - -// registerTestTree( -// governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, polkadot, testConfigForLocalScheduler), -// ) +registerTestTree( + governanceChainUpgradesOtherChainViaRootReferendumSuite(assetHubPolkadot, polkadot, testConfigForLocalScheduler), +) From 6b583058b38aa461e9a2e5a6522771772b68662d Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 7 Nov 2025 19:02:20 +0100 Subject: [PATCH 07/11] Missing import --- packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts b/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts index ad872589c..468eca466 100644 --- a/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.system.e2e.test.ts @@ -1,5 +1,10 @@ import { assetHubPolkadot } from '@e2e-test/networks/chains' -import { type ParaTestConfig, registerTestTree, systemE2ETestsForParaWithScheduler } from '@e2e-test/shared' +import { + governanceChainSelfUpgradeViaRootReferendumSuite, + type ParaTestConfig, + registerTestTree, + systemE2ETestsForParaWithScheduler, +} from '@e2e-test/shared' const testConfigForLocalScheduler: ParaTestConfig = { testSuiteName: 'Polkadot AssetHub System', From c93c613e20c2a943db2324dda00b926e234023ce Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Fri, 7 Nov 2025 21:22:16 +0100 Subject: [PATCH 08/11] Clear Preimage storage before referedum test --- packages/shared/src/upgrade.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/shared/src/upgrade.ts b/packages/shared/src/upgrade.ts index 2589bf3aa..11bb953e8 100644 --- a/packages/shared/src/upgrade.ts +++ b/packages/shared/src/upgrade.ts @@ -173,6 +173,12 @@ async function createAndFastTrackReferendum( // Fund Alice for preimage and deposits await client.dev.setStorage({ + // It may happen that real referendum preimage is still in place and since we are basically + // upgrading to the same WASM it will yield the same preimage and test can fail due to preimage + // already noted + Preimage: { + $removePrefix: ['preimageFor', 'statusFor', 'requestStatusFor'], + }, System: { account: [[[alice.address], { providers: 1, data: { free: 100000 * 1e10 } }]], }, @@ -796,17 +802,17 @@ export function governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite< kind: 'describe', label: testConfig.testSuiteName, children: [ - { - kind: 'test', - label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, - testFn: async () => - await authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests( - governanceChain, - governanceChain, - fellowshipChain, - testConfig, - ), - }, + // { + // kind: 'test', + // label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, + // testFn: async () => + // await authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests( + // governanceChain, + // governanceChain, + // fellowshipChain, + // testConfig, + // ), + // }, { kind: 'test', label: `authorize_upgrade doesnt allow upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, From 7e627676f6aa06ebb26d36a48c0ce62daf35c8cd Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Sat, 8 Nov 2025 22:04:04 +0100 Subject: [PATCH 09/11] Bot review fixes --- packages/shared/src/upgrade.ts | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/shared/src/upgrade.ts b/packages/shared/src/upgrade.ts index 11bb953e8..6dfbcd4a5 100644 --- a/packages/shared/src/upgrade.ts +++ b/packages/shared/src/upgrade.ts @@ -760,7 +760,8 @@ export function governanceChainUpgradesOtherChainViaRootReferendumSuite< { kind: 'test', label: `authorize_upgrade doesnt allow upgrade to the same wasm (via Root referendum)`, - testFn: async () => await authorizeUpgradeViaRootReferendumTests(governanceChain, governanceChain, testConfig), + testFn: async () => + await authorizeUpgradeViaRootReferendumTests(governanceChain, toBeUpgradedChain, testConfig), }, ], } @@ -802,17 +803,17 @@ export function governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite< kind: 'describe', label: testConfig.testSuiteName, children: [ - // { - // kind: 'test', - // label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, - // testFn: async () => - // await authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests( - // governanceChain, - // governanceChain, - // fellowshipChain, - // testConfig, - // ), - // }, + { + kind: 'test', + label: `authorize_upgrade_without_checks allows upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, + testFn: async () => + await authorizeUpgradeWithoutChecksViaWhitelistedCallerReferendumTests( + governanceChain, + governanceChain, + fellowshipChain, + testConfig, + ), + }, { kind: 'test', label: `authorize_upgrade doesnt allow upgrade to the same wasm (via WhitelistedCaller referendum, approved by Fellowship)`, @@ -886,7 +887,7 @@ export function governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumS testFn: async () => await authorizeUpgradeViaWhitelistedCallerReferendumTests( governanceChain, - governanceChain, + toBeUpgradedChain, fellowshipChain, testConfig, ), From feff846b79199157caa761000aac2d8b14339f60 Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Sat, 8 Nov 2025 22:25:57 +0100 Subject: [PATCH 10/11] More review fixes --- packages/shared/src/upgrade.ts | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/packages/shared/src/upgrade.ts b/packages/shared/src/upgrade.ts index 6dfbcd4a5..2f2716767 100644 --- a/packages/shared/src/upgrade.ts +++ b/packages/shared/src/upgrade.ts @@ -264,22 +264,9 @@ async function createAndFastTrackReferendum( }, } - let fastProposal: any - try { - fastProposal = client.api.registry.createType('Option', fastProposalData) - } catch { - try { - fastProposal = client.api.registry.createType( - 'Option', - fastProposalData, - ) - } catch { - fastProposal = client.api.registry.createType( - 'Option', - fastProposalData, - ) - } - } + const refMeta = client.api.query.referenda.referendumInfoFor.creator.meta + const refValueType = client.api.registry.lookup.getTypeDef(refMeta.type.asMap.value).type + const fastProposal = client.api.registry.createType(refValueType, fastProposalData) const referendumKey = client.api.query.referenda.referendumInfoFor.key(referendumIndex) await client.api.rpc('dev_setStorage', [[referendumKey, fastProposal.toHex()]]) @@ -306,7 +293,9 @@ async function createAndFastTrackReferendum( if (lookup.isSome) { const lookupKey = await client.api.query.scheduler.lookup.key(id) - const fastLookup = client.api.registry.createType('Option<(u32,u32)>', [nextBlockNumber, 0]) + const lookupMeta = client.api.query.scheduler.lookup.creator.meta + const lookupValueType = client.api.registry.lookup.getTypeDef(lookupMeta.type.asMap.value).type + const fastLookup = client.api.registry.createType(lookupValueType, [nextBlockNumber, 0]) await client.api.rpc('dev_setStorage', [[lookupKey, fastLookup.toHex()]]) } } From 8d42a820c832a545349f9a21b6a62507cdba9b0a Mon Sep 17 00:00:00 2001 From: Karol Kokoszka Date: Mon, 24 Nov 2025 13:43:00 +0100 Subject: [PATCH 11/11] Cleanup, more tests --- ...bPolkadot.collectivesPolkadot.test.ts.snap | 120 ------------------ ...bPolkadot.collectivesPolkadot.test.ts.snap | 120 ------------------ ...ePolkadot.collectivesPolkadot.test.ts.snap | 120 ------------------ ...dgeHubPolkadot.collectivesPolkadot.test.ts | 23 +++- ...setHubPolkadot.collectivesPolkadot.test.ts | 10 ++ ...retimePolkadot.collectivesPolkadot.test.ts | 23 +++- ...peoplePolkadot.collectivesPolkadot.test.ts | 23 +++- ...kadot.polkadot.collectivesPolkadot.test.ts | 24 +++- ...dgeHubPolkadot.collectivesPolkadot.test.ts | 0 ...retimePolkadot.collectivesPolkadot.test.ts | 0 ...peoplePolkadot.collectivesPolkadot.test.ts | 0 packages/shared/src/upgrade.ts | 13 +- 12 files changed, 104 insertions(+), 372 deletions(-) delete mode 100644 packages/polkadot/src/__snapshots__/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts.snap delete mode 100644 packages/polkadot/src/__snapshots__/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts.snap delete mode 100644 packages/polkadot/src/__snapshots__/polkadot.coretimePolkadot.collectivesPolkadot.test.ts.snap delete mode 100644 packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts delete mode 100644 packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts delete mode 100644 packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts diff --git a/packages/polkadot/src/__snapshots__/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts.snap b/packages/polkadot/src/__snapshots__/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts.snap deleted file mode 100644 index f1f912860..000000000 --- a/packages/polkadot/src/__snapshots__/polkadot.assetHubPolkadot.collectivesPolkadot.test.ts.snap +++ /dev/null @@ -1,120 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > collectives events emitted when sending xcm 1`] = ` -[ - { - "data": { - "destination": { - "interior": "Here", - "parents": 1, - }, - "message": [ - { - "UnpaidExecution": { - "checkOrigin": null, - "weightLimit": "Unlimited", - }, - }, - { - "Transact": { - "call": { - "encoded": "0x170089ba36353c2150427d20dc71ab18e6762c07f560a6e485f64c26a608abecb473", - }, - "fallbackMaxWeight": { - "proofSize": 10000, - "refTime": 500000000, - }, - "originKind": "Xcm", - }, - }, - ], - "messageId": "(redacted)", - "origin": { - "interior": { - "X1": [ - { - "Plurality": { - "id": "Technical", - "part": "Voice", - }, - }, - ], - }, - "parents": 0, - }, - }, - "method": "Sent", - "section": "polkadotXcm", - }, -] -`; - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > events after notePreimge 1`] = `[]`; - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > events when dispatching non-whitelisted call 1`] = ` -[ - { - "data": { - "id": null, - "result": { - "Err": { - "Module": { - "error": "0x05000000", - "index": 0, - }, - }, - }, - "task": "(redacted)", - }, - "method": "Dispatched", - "section": "scheduler", - }, -] -`; - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > events when dispatching whitelisted call with bad origin 1`] = ` -[ - { - "data": { - "id": null, - "result": { - "Err": { - "Module": { - "error": "0x05000000", - "index": 0, - }, - }, - }, - "task": "(redacted)", - }, - "method": "Dispatched", - "section": "scheduler", - }, -] -`; - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > governing chain events about dispatching whitelisted call 1`] = `[]`; - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > governing chain events emitted on receiving xcm from collectives 1`] = ` -[ - { - "data": { - "id": "(redacted)", - "origin": { - "Ump": { - "Para": "(rounded 1000)", - }, - }, - "success": true, - "weightUsed": { - "proofSize": "(rounded 6000)", - "refTime": "(rounded 300000000)", - }, - }, - "method": "Processed", - "section": "messageQueue", - }, -] -`; - -exports[`polkadot & asset hub & collectives > Relay authorizes AssetHub upgrade via Collectives > to-be-upgraded chain events to confirm authorized upgrade 1`] = `[]`; diff --git a/packages/polkadot/src/__snapshots__/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts.snap b/packages/polkadot/src/__snapshots__/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts.snap deleted file mode 100644 index eadfe6ee1..000000000 --- a/packages/polkadot/src/__snapshots__/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts.snap +++ /dev/null @@ -1,120 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > collectives events emitted when sending xcm 1`] = ` -[ - { - "data": { - "destination": { - "interior": "Here", - "parents": 1, - }, - "message": [ - { - "UnpaidExecution": { - "checkOrigin": null, - "weightLimit": "Unlimited", - }, - }, - { - "Transact": { - "call": { - "encoded": "0x1700bec38f9174094d5d36794d04bd0b9d4a4da7ad1db83473bce75b31b465d95a7b", - }, - "fallbackMaxWeight": { - "proofSize": 10000, - "refTime": 500000000, - }, - "originKind": "Xcm", - }, - }, - ], - "messageId": "(redacted)", - "origin": { - "interior": { - "X1": [ - { - "Plurality": { - "id": "Technical", - "part": "Voice", - }, - }, - ], - }, - "parents": 0, - }, - }, - "method": "Sent", - "section": "polkadotXcm", - }, -] -`; - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > events after notePreimge 1`] = `[]`; - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > events when dispatching non-whitelisted call 1`] = ` -[ - { - "data": { - "id": null, - "result": { - "Err": { - "Module": { - "error": "0x05000000", - "index": 0, - }, - }, - }, - "task": "(redacted)", - }, - "method": "Dispatched", - "section": "scheduler", - }, -] -`; - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > events when dispatching whitelisted call with bad origin 1`] = ` -[ - { - "data": { - "id": null, - "result": { - "Err": { - "Module": { - "error": "0x05000000", - "index": 0, - }, - }, - }, - "task": "(redacted)", - }, - "method": "Dispatched", - "section": "scheduler", - }, -] -`; - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > governing chain events about dispatching whitelisted call 1`] = `[]`; - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > governing chain events emitted on receiving xcm from collectives 1`] = ` -[ - { - "data": { - "id": "(redacted)", - "origin": { - "Ump": { - "Para": "(rounded 1000)", - }, - }, - "success": true, - "weightUsed": { - "proofSize": "(rounded 6000)", - "refTime": "(rounded 300000000)", - }, - }, - "method": "Processed", - "section": "messageQueue", - }, -] -`; - -exports[`polkadot & bridgeHub & collectives > Relay authorizes Bridge Hub upgrade via Collectives > to-be-upgraded chain events to confirm authorized upgrade 1`] = `[]`; diff --git a/packages/polkadot/src/__snapshots__/polkadot.coretimePolkadot.collectivesPolkadot.test.ts.snap b/packages/polkadot/src/__snapshots__/polkadot.coretimePolkadot.collectivesPolkadot.test.ts.snap deleted file mode 100644 index 9dc6e91ff..000000000 --- a/packages/polkadot/src/__snapshots__/polkadot.coretimePolkadot.collectivesPolkadot.test.ts.snap +++ /dev/null @@ -1,120 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > collectives events emitted when sending xcm 1`] = ` -[ - { - "data": { - "destination": { - "interior": "Here", - "parents": 1, - }, - "message": [ - { - "UnpaidExecution": { - "checkOrigin": null, - "weightLimit": "Unlimited", - }, - }, - { - "Transact": { - "call": { - "encoded": "0x17008097b9f2e0aa4ab3b2b40d8912071ce5fd27e15432afcd3b204548d56468f21b", - }, - "fallbackMaxWeight": { - "proofSize": 10000, - "refTime": 500000000, - }, - "originKind": "Xcm", - }, - }, - ], - "messageId": "(redacted)", - "origin": { - "interior": { - "X1": [ - { - "Plurality": { - "id": "Technical", - "part": "Voice", - }, - }, - ], - }, - "parents": 0, - }, - }, - "method": "Sent", - "section": "polkadotXcm", - }, -] -`; - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > events after notePreimge 1`] = `[]`; - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > events when dispatching non-whitelisted call 1`] = ` -[ - { - "data": { - "id": null, - "result": { - "Err": { - "Module": { - "error": "0x05000000", - "index": 0, - }, - }, - }, - "task": "(redacted)", - }, - "method": "Dispatched", - "section": "scheduler", - }, -] -`; - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > events when dispatching whitelisted call with bad origin 1`] = ` -[ - { - "data": { - "id": null, - "result": { - "Err": { - "Module": { - "error": "0x05000000", - "index": 0, - }, - }, - }, - "task": "(redacted)", - }, - "method": "Dispatched", - "section": "scheduler", - }, -] -`; - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > governing chain events about dispatching whitelisted call 1`] = `[]`; - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > governing chain events emitted on receiving xcm from collectives 1`] = ` -[ - { - "data": { - "id": "(redacted)", - "origin": { - "Ump": { - "Para": "(rounded 1000)", - }, - }, - "success": true, - "weightUsed": { - "proofSize": "(rounded 6000)", - "refTime": "(rounded 300000000)", - }, - }, - "method": "Processed", - "section": "messageQueue", - }, -] -`; - -exports[`polkadot & coretime & collectives > Relay authorizes Coretime upgrade via Collectives > to-be-upgraded chain events to confirm authorized upgrade 1`] = `[]`; diff --git a/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts index 6cd558ac5..91bb44add 100644 --- a/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,9 @@ import { assetHubPolkadot, bridgeHubPolkadot, collectivesPolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + authorizeUpgradeViaCollectives, + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite, +} from '@e2e-test/shared/upgrade.js' import { describe, test } from 'vitest' @@ -15,3 +18,19 @@ describe('asset hub & bridgeHub & collectives', async () => { await authorizeUpgradeViaCollectives(assetHubPolkadotClient, bridgeHubClient, collectivesClient) }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'asset hub & bridgeHub & collectives', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite( + assetHubPolkadot, + bridgeHubPolkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts index ad149d353..80b533fd2 100644 --- a/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.collectivesPolkadot.test.ts @@ -3,6 +3,7 @@ import { assetHubPolkadot, collectivesPolkadot } from '@e2e-test/networks/chains import { governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite, governanceChainUpgradesOtherChainViaRootReferendumSuite, + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite, type ParaTestConfig, registerTestTree, setupNetworks, @@ -68,6 +69,15 @@ registerTestTree( ), ) +registerTestTree( + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite( + assetHubPolkadot, + collectivesPolkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) + registerTestTree( governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite( assetHubPolkadot, diff --git a/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.collectivesPolkadot.test.ts index 6d2c12c0e..266c98679 100644 --- a/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.coretimePolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,9 @@ import { assetHubPolkadot, collectivesPolkadot, coretimePolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + authorizeUpgradeViaCollectives, + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite, +} from '@e2e-test/shared/upgrade.js' import { describe, test } from 'vitest' @@ -15,3 +18,19 @@ describe('asset hub & coretime & collectives', async () => { await authorizeUpgradeViaCollectives(assetHubPolkadotClient, coretimeClient, collectivesClient) }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'asset hub & coretime & collectives', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite( + assetHubPolkadot, + coretimePolkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.collectivesPolkadot.test.ts index 5176c606e..d5b45a6ea 100644 --- a/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.peoplePolkadot.collectivesPolkadot.test.ts @@ -1,6 +1,9 @@ import { assetHubPolkadot, collectivesPolkadot, peoplePolkadot } from '@e2e-test/networks/chains' -import { setupNetworks } from '@e2e-test/shared' -import { authorizeUpgradeViaCollectives } from '@e2e-test/shared/upgrade.js' +import { type ParaTestConfig, registerTestTree, setupNetworks } from '@e2e-test/shared' +import { + authorizeUpgradeViaCollectives, + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite, +} from '@e2e-test/shared/upgrade.js' import { describe, test } from 'vitest' @@ -15,3 +18,19 @@ describe('asset hub & people & collectives', async () => { await authorizeUpgradeViaCollectives(assetHubPolkadotClient, peopleClient, collectivesClient) }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'asset hub & people & collectives', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite( + assetHubPolkadot, + peoplePolkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/assetHubPolkadot.polkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/assetHubPolkadot.polkadot.collectivesPolkadot.test.ts index 21cab325f..26568a685 100644 --- a/packages/polkadot/src/assetHubPolkadot.polkadot.collectivesPolkadot.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.polkadot.collectivesPolkadot.test.ts @@ -1,5 +1,11 @@ import { assetHubPolkadot, collectivesPolkadot, polkadot } from '@e2e-test/networks/chains' -import { authorizeUpgradeViaCollectives, setupNetworks } from '@e2e-test/shared' +import { + authorizeUpgradeViaCollectives, + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite, + type ParaTestConfig, + registerTestTree, + setupNetworks, +} from '@e2e-test/shared' import { describe, test } from 'vitest' @@ -14,3 +20,19 @@ describe('asset hub & polkadot & collectives', async () => { await authorizeUpgradeViaCollectives(assetHubPolkadotClient, polkadotClient, collectivesClient) }) }) + +const testConfigForLocalScheduler: ParaTestConfig = { + testSuiteName: 'asset hub & people & collectives', + addressEncoding: 0, + blockProvider: 'NonLocal', + asyncBacking: 'Enabled', +} + +registerTestTree( + governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite( + assetHubPolkadot, + polkadot, + collectivesPolkadot, + testConfigForLocalScheduler, + ), +) diff --git a/packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.bridgeHubPolkadot.collectivesPolkadot.test.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.coretimePolkadot.collectivesPolkadot.test.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts b/packages/polkadot/src/polkadot.peoplePolkadot.collectivesPolkadot.test.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/shared/src/upgrade.ts b/packages/shared/src/upgrade.ts index 2f2716767..32c9c5146 100644 --- a/packages/shared/src/upgrade.ts +++ b/packages/shared/src/upgrade.ts @@ -782,10 +782,11 @@ export function governanceChainUpgradesOtherChainViaRootReferendumSuite< export function governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite< TCustomRelay extends Record | undefined, TInitStoragesRelay extends Record> | undefined, + TCustomPara extends Record | undefined, TInitStoragesPara extends Record> | undefined, >( governanceChain: Chain, - fellowshipChain: Chain, + fellowshipChain: Chain, testConfig: TestConfig, ): RootTestTree { return { @@ -847,12 +848,14 @@ export function governanceChainSelfUpgradeViaWhitelistedCallerReferendumSuite< export function governanceChainUpgradesOtherChainViaWhitelistedCallerReferendumSuite< TCustomRelay extends Record | undefined, TInitStoragesRelay extends Record> | undefined, - TCustomPara extends Record | undefined, - TInitStoragesPara extends Record> | undefined, + TCustomChain extends Record | undefined, + TInitStoragesChain extends Record> | undefined, + TCustomCollectives extends Record | undefined, + TInitStoragesCollectives extends Record> | undefined, >( governanceChain: Chain, - toBeUpgradedChain: Chain, - fellowshipChain: Chain, + toBeUpgradedChain: Chain, + fellowshipChain: Chain, testConfig: TestConfig, ): RootTestTree { return {