From d085306205d9b4ccf90d4e75093f796197c10782 Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 2 Jan 2025 14:00:37 +0100 Subject: [PATCH 1/6] new proxy --- solo-chains/runtime/dancelight/src/lib.rs | 11 +++ .../proxy/test-proxy-validator-management.ts | 94 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts diff --git a/solo-chains/runtime/dancelight/src/lib.rs b/solo-chains/runtime/dancelight/src/lib.rs index bf87423ed..e4d3de8be 100644 --- a/solo-chains/runtime/dancelight/src/lib.rs +++ b/solo-chains/runtime/dancelight/src/lib.rs @@ -841,6 +841,7 @@ pub enum ProxyType { Auction, OnDemandOrdering, SudoRegistrar, + SudoValidatorManagement, } impl Default for ProxyType { fn default() -> Self { @@ -914,6 +915,16 @@ impl InstanceFilter for ProxyType { } _ => false, }, + ProxyType::SudoValidatorManagement => match c { + RuntimeCall::Sudo(pallet_sudo::Call::sudo { call: ref x }) => { + matches!( + x.as_ref(), + &RuntimeCall::ExternalValidators(..) + | &RuntimeCall::ExternalValidatorSlashes(..) + ) + } + _ => false, + }, } } fn is_superset(&self, o: &Self) -> bool { diff --git a/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts b/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts new file mode 100644 index 000000000..59e8611d7 --- /dev/null +++ b/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts @@ -0,0 +1,94 @@ +import "@tanssi/api-augment"; +import { describeSuite, expect, beforeAll } from "@moonwall/cli"; +import { KeyringPair } from "@moonwall/util"; +import { ApiPromise } from "@polkadot/api"; +import { initializeCustomCreateBlock, jumpSessions } from "../../../util/block"; + +describeSuite({ + id: "DTR1201", + title: "Proxy test suite", + foundationMethods: "dev", + testCases: ({ it, context }) => { + let polkadotJs: ApiPromise; + let sudoAlice: KeyringPair; + let delegateBob: KeyringPair; + let charlie: KeyringPair; + const VALIDATOR_PROXY_INDEX = 8; + + beforeAll(() => { + initializeCustomCreateBlock(context); + + sudoAlice = context.keyring.alice; + delegateBob = context.keyring.bob; + charlie = context.keyring.charlie; + + polkadotJs = context.polkadotJs(); + }); + + it({ + id: "E01", + title: "Can add proxy", + test: async function () { + await context.createBlock(); + + const tx = polkadotJs.tx.proxy.addProxy(delegateBob.address, VALIDATOR_PROXY_INDEX, 0); + await context.createBlock([await tx.signAsync(sudoAlice)]); + + const proxies = await polkadotJs.query.proxy.proxies(sudoAlice.address); + expect(proxies.toJSON()[0]).to.deep.equal([ + { + delegate: delegateBob.address, + proxyType: "SudoValidatorManagement", + delay: 0, + }, + ]); + }, + }); + + it({ + id: "E02", + title: "Delegated account can sudo txs in external validators", + test: async function () { + const txAddWhitelisted = polkadotJs.tx.proxy.proxy( + sudoAlice.address, + null, + polkadotJs.tx.sudo.sudo( + polkadotJs.tx.externalValidators.addWhitelisted( + delegateBob.address, + ) + ) + ); + await context.createBlock([await txAddWhitelisted.signAsync(delegateBob)]); + + const whitelistedValidatorInfo = await polkadotJs.query.externalValidators.whitelistedValidators(); + expect(whitelistedValidatorInfo.toHuman().includes(delegateBob.address)).to.be.true; + }, + }); + + it({ + id: "E02", + title: "Delegated account can sudo txs in external validator slashes", + test: async function () { + const txAddWhitelisted = polkadotJs.tx.proxy.proxy( + sudoAlice.address, + null, + polkadotJs.tx.sudo.sudo( + polkadotJs.tx.externalValidatorSlashes.forceInjectSlash( + 0, + sudoAlice.address, + 1000, + ) + ) + ); + await context.createBlock([await txAddWhitelisted.signAsync(delegateBob)]); + + const DeferPeriod = (await polkadotJs.consts.externalValidatorSlashes.slashDeferDuration).toNumber(); + + // scheduled slashes + const expectedSlashes = await polkadotJs.query.externalValidatorSlashes.slashes(DeferPeriod + 1); + expect(expectedSlashes.length).to.be.eq(1); + + }, + }); + }, +}); From 615b38a574452a4551824a51b4bcf2c1e62360a0 Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 2 Jan 2025 14:10:58 +0100 Subject: [PATCH 2/6] test session key proxy --- .../proxy/test-session-keys-management.ts | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 test/suites/dev-tanssi-relay/proxy/test-session-keys-management.ts diff --git a/test/suites/dev-tanssi-relay/proxy/test-session-keys-management.ts b/test/suites/dev-tanssi-relay/proxy/test-session-keys-management.ts new file mode 100644 index 000000000..c14306f02 --- /dev/null +++ b/test/suites/dev-tanssi-relay/proxy/test-session-keys-management.ts @@ -0,0 +1,77 @@ +import "@polkadot/api-augment"; +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { ApiPromise } from "@polkadot/api"; + +describeSuite({ + id: "DT0601", + title: "Proxy test suite - ProxyType::SessionKeyManagement", + foundationMethods: "dev", + testCases: ({ it, context }) => { + let polkadotJs: ApiPromise; + const sessionKeysManagementProxy = 9; + const someKeys = "0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF"; + + beforeAll(() => { + polkadotJs = context.polkadotJs(); + }); + + it({ + id: "E01", + title: "Delegate account can manage keys", + test: async function () { + const delegator_alice = context.keyring.alice; + const delegate_charlie = context.keyring.charlie; + + let tx = polkadotJs.tx.proxy.addProxy(delegate_charlie.address, sessionKeysManagementProxy, 0); + await context.createBlock([await tx.signAsync(delegator_alice)]); + + let events = await polkadotJs.query.system.events(); + let ev1 = events.filter((a) => { + return a.event.method == "ProxyAdded"; + }); + expect(ev1.length).to.be.equal(1); + + await context.createBlock(); + + tx = polkadotJs.tx.proxy.proxy( + delegator_alice.address, + null, + polkadotJs.tx.session.setKeys(someKeys, "0x") + ); + await context.createBlock([await tx.signAsync(delegate_charlie)]); + events = await polkadotJs.query.system.events(); + ev1 = events.filter((a) => { + return a.event.method == "ProxyExecuted"; + }); + expect(ev1.length).to.be.equal(1); + expect(ev1[0].event.data[0].toString()).to.be.eq("Ok"); + }, + }); + + it({ + id: "E02", + title: "Non-Delegate account fails to manage other account's keys", + test: async function () { + const alice = context.keyring.alice; + const non_delegate_dave = context.keyring.dave; + + await context.createBlock(); + + const tx = polkadotJs.tx.proxy.proxy( + alice.address, + null, + polkadotJs.tx.session.setKeys( + "0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF", + "0x" + ) + ); + await context.createBlock([await tx.signAsync(non_delegate_dave)]); + const events = await polkadotJs.query.system.events(); + const ev1 = events.filter((a) => { + return a.event.method == "ProxyExecuted"; + }); + expect(ev1.length).to.be.equal(0); + }, + }); + }, +}); From 00bbfadc1053df82d67deabfb0719ba5b5cb8702 Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 2 Jan 2025 14:28:57 +0100 Subject: [PATCH 3/6] add proxies --- solo-chains/runtime/dancelight/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solo-chains/runtime/dancelight/src/lib.rs b/solo-chains/runtime/dancelight/src/lib.rs index e4d3de8be..a92a6a642 100644 --- a/solo-chains/runtime/dancelight/src/lib.rs +++ b/solo-chains/runtime/dancelight/src/lib.rs @@ -842,6 +842,8 @@ pub enum ProxyType { OnDemandOrdering, SudoRegistrar, SudoValidatorManagement, + SessionKeyManagement, + Staking } impl Default for ProxyType { fn default() -> Self { @@ -925,6 +927,12 @@ impl InstanceFilter for ProxyType { } _ => false, }, + ProxyType::SessionKeyManagement => { + matches!(c, RuntimeCall::Session(..)) + }, + ProxyType::Staking => { + matches!(c, RuntimeCall::Session(..) | RuntimeCall::PooledStaking(..)) + } } } fn is_superset(&self, o: &Self) -> bool { From 403f7e84eb96e7297c94ebd4e15e77d66d09af8d Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 2 Jan 2025 15:30:18 +0100 Subject: [PATCH 4/6] typescript api --- .../dancelight/interfaces/augment-api-tx.ts | 18 ++++++++++++++++++ .../src/dancelight/interfaces/lookup.ts | 3 +++ .../src/dancelight/interfaces/types-lookup.ts | 8 +++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/typescript-api/src/dancelight/interfaces/augment-api-tx.ts b/typescript-api/src/dancelight/interfaces/augment-api-tx.ts index 150d67c7e..3a5e4cbf1 100644 --- a/typescript-api/src/dancelight/interfaces/augment-api-tx.ts +++ b/typescript-api/src/dancelight/interfaces/augment-api-tx.ts @@ -3371,6 +3371,9 @@ declare module "@polkadot/api-base/types/submittable" { | "Auction" | "OnDemandOrdering" | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking" | number | Uint8Array, delay: u32 | AnyNumber | Uint8Array @@ -3439,6 +3442,9 @@ declare module "@polkadot/api-base/types/submittable" { | "Auction" | "OnDemandOrdering" | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking" | number | Uint8Array, delay: u32 | AnyNumber | Uint8Array, @@ -3484,6 +3490,9 @@ declare module "@polkadot/api-base/types/submittable" { | "Auction" | "OnDemandOrdering" | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking" | number | Uint8Array, index: u16 | AnyNumber | Uint8Array, @@ -3527,6 +3536,9 @@ declare module "@polkadot/api-base/types/submittable" { | "Auction" | "OnDemandOrdering" | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking" | number, call: Call | IMethod | string | Uint8Array ) => SubmittableExtrinsic, @@ -3578,6 +3590,9 @@ declare module "@polkadot/api-base/types/submittable" { | "Auction" | "OnDemandOrdering" | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking" | number, call: Call | IMethod | string | Uint8Array ) => SubmittableExtrinsic, @@ -3678,6 +3693,9 @@ declare module "@polkadot/api-base/types/submittable" { | "Auction" | "OnDemandOrdering" | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking" | number | Uint8Array, delay: u32 | AnyNumber | Uint8Array diff --git a/typescript-api/src/dancelight/interfaces/lookup.ts b/typescript-api/src/dancelight/interfaces/lookup.ts index 5a0bdb5a4..7500c7b0a 100644 --- a/typescript-api/src/dancelight/interfaces/lookup.ts +++ b/typescript-api/src/dancelight/interfaces/lookup.ts @@ -2852,6 +2852,9 @@ export default { "Auction", "OnDemandOrdering", "SudoRegistrar", + "SudoValidatorManagement", + "SessionKeyManagement", + "Staking", ], }, /** Lookup309: pallet_multisig::pallet::Call */ diff --git a/typescript-api/src/dancelight/interfaces/types-lookup.ts b/typescript-api/src/dancelight/interfaces/types-lookup.ts index fd91b28f9..34eb03773 100644 --- a/typescript-api/src/dancelight/interfaces/types-lookup.ts +++ b/typescript-api/src/dancelight/interfaces/types-lookup.ts @@ -3499,6 +3499,9 @@ declare module "@polkadot/types/lookup" { readonly isAuction: boolean; readonly isOnDemandOrdering: boolean; readonly isSudoRegistrar: boolean; + readonly isSudoValidatorManagement: boolean; + readonly isSessionKeyManagement: boolean; + readonly isStaking: boolean; readonly type: | "Any" | "NonTransfer" @@ -3507,7 +3510,10 @@ declare module "@polkadot/types/lookup" { | "CancelProxy" | "Auction" | "OnDemandOrdering" - | "SudoRegistrar"; + | "SudoRegistrar" + | "SudoValidatorManagement" + | "SessionKeyManagement" + | "Staking"; } /** @name PalletMultisigCall (309) */ From 9277587b1639d17b32968efcefffa81218786915 Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 2 Jan 2025 15:31:32 +0100 Subject: [PATCH 5/6] fmt --- .../proxy/test-proxy-validator-management.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts b/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts index 59e8611d7..22e6bf58b 100644 --- a/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts +++ b/test/suites/dev-tanssi-relay/proxy/test-proxy-validator-management.ts @@ -2,7 +2,7 @@ import "@tanssi/api-augment"; import { describeSuite, expect, beforeAll } from "@moonwall/cli"; import { KeyringPair } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; -import { initializeCustomCreateBlock, jumpSessions } from "../../../util/block"; +import { initializeCustomCreateBlock } from "../../../util/block"; describeSuite({ id: "DTR1201", @@ -12,7 +12,6 @@ describeSuite({ let polkadotJs: ApiPromise; let sudoAlice: KeyringPair; let delegateBob: KeyringPair; - let charlie: KeyringPair; const VALIDATOR_PROXY_INDEX = 8; beforeAll(() => { @@ -20,7 +19,6 @@ describeSuite({ sudoAlice = context.keyring.alice; delegateBob = context.keyring.bob; - charlie = context.keyring.charlie; polkadotJs = context.polkadotJs(); }); @@ -52,11 +50,7 @@ describeSuite({ const txAddWhitelisted = polkadotJs.tx.proxy.proxy( sudoAlice.address, null, - polkadotJs.tx.sudo.sudo( - polkadotJs.tx.externalValidators.addWhitelisted( - delegateBob.address, - ) - ) + polkadotJs.tx.sudo.sudo(polkadotJs.tx.externalValidators.addWhitelisted(delegateBob.address)) ); await context.createBlock([await txAddWhitelisted.signAsync(delegateBob)]); @@ -73,11 +67,7 @@ describeSuite({ sudoAlice.address, null, polkadotJs.tx.sudo.sudo( - polkadotJs.tx.externalValidatorSlashes.forceInjectSlash( - 0, - sudoAlice.address, - 1000, - ) + polkadotJs.tx.externalValidatorSlashes.forceInjectSlash(0, sudoAlice.address, 1000) ) ); await context.createBlock([await txAddWhitelisted.signAsync(delegateBob)]); @@ -87,7 +77,6 @@ describeSuite({ // scheduled slashes const expectedSlashes = await polkadotJs.query.externalValidatorSlashes.slashes(DeferPeriod + 1); expect(expectedSlashes.length).to.be.eq(1); - }, }); }, From 7187e4793f8c23958d8ab12ae4c3adb2ee3f54fc Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 2 Jan 2025 15:40:51 +0100 Subject: [PATCH 6/6] fmt --- solo-chains/runtime/dancelight/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solo-chains/runtime/dancelight/src/lib.rs b/solo-chains/runtime/dancelight/src/lib.rs index a92a6a642..adcd905ac 100644 --- a/solo-chains/runtime/dancelight/src/lib.rs +++ b/solo-chains/runtime/dancelight/src/lib.rs @@ -843,7 +843,7 @@ pub enum ProxyType { SudoRegistrar, SudoValidatorManagement, SessionKeyManagement, - Staking + Staking, } impl Default for ProxyType { fn default() -> Self { @@ -929,7 +929,7 @@ impl InstanceFilter for ProxyType { }, ProxyType::SessionKeyManagement => { matches!(c, RuntimeCall::Session(..)) - }, + } ProxyType::Staking => { matches!(c, RuntimeCall::Session(..) | RuntimeCall::PooledStaking(..)) }