difftreelog
Merge pull request #1059 from UniqueNetwork/feature/financial-council
in: master
15 files changed
js-packages/.vscode/settings.jsondiffbeforeafterboth4 "RUN_XCM_TESTS": "1"4 "RUN_XCM_TESTS": "1"5 },5 },6 "mochaExplorer.files": "tests/**/*.test.ts",6 "mochaExplorer.files": "tests/**/*.test.ts",7 "mochaExplorer.esmLoader": true,7 "mochaExplorer.require": "ts-node/register",8 "mochaExplorer.nodeArgv": ["--loader", "ts-node/esm"],8 "eslint.format.enable": true,9 "eslint.format.enable": true,9 "[javascript]": {10 "[javascript]": {10 "editor.defaultFormatter": "dbaeumer.vscode-eslint"11 "editor.defaultFormatter": "dbaeumer.vscode-eslint"js-packages/test-utils/index.tsdiffbeforeafterboth214 }));214 }));215 };215 };216217 static FinCouncil = class extends EventSection('financialCouncil') {218 static Proposed = this.Method('Proposed', data => ({219 account: eventHumanData(data, 0),220 proposalIndex: eventJsonData<number>(data, 1),221 proposalHash: eventHumanData(data, 2),222 threshold: eventJsonData<number>(data, 3),223 }));224 static Closed = this.Method('Closed', data => ({225 proposalHash: eventHumanData(data, 0),226 yes: eventJsonData<number>(data, 1),227 no: eventJsonData<number>(data, 2),228 }));229 static Executed = this.Method('Executed', data => ({230 proposalHash: eventHumanData(data, 0),231 }));232 };216233217 static TechnicalCommittee = class extends EventSection('technicalCommittee') {234 static TechnicalCommittee = class extends EventSection('technicalCommittee') {218 static Proposed = this.Method('Proposed', data => ({235 static Proposed = this.Method('Proposed', data => ({475 scheduler: SchedulerGroup;492 scheduler: SchedulerGroup;476 collatorSelection: CollatorSelectionGroup;493 collatorSelection: CollatorSelectionGroup;477 council: ICollectiveGroup;494 council: ICollectiveGroup;495 finCouncil: ICollectiveGroup;478 technicalCommittee: ICollectiveGroup;496 technicalCommittee: ICollectiveGroup;479 fellowship: IFellowshipGroup;497 fellowship: IFellowshipGroup;480 democracy: DemocracyGroup;498 democracy: DemocracyGroup;498 collective: new CollectiveGroup(this, 'council'),516 collective: new CollectiveGroup(this, 'council'),499 membership: new CollectiveMembershipGroup(this, 'councilMembership'),517 membership: new CollectiveMembershipGroup(this, 'councilMembership'),500 };518 };519 this.finCouncil = {520 collective: new CollectiveGroup(this, 'financialCouncil'),521 membership: new CollectiveMembershipGroup(this, 'financialCouncilMembership'),522 };501 this.technicalCommittee = {523 this.technicalCommittee = {502 collective: new CollectiveGroup(this, 'technicalCommittee'),524 collective: new CollectiveGroup(this, 'technicalCommittee'),503 membership: new CollectiveMembershipGroup(this, 'technicalCommitteeMembership'),525 membership: new CollectiveMembershipGroup(this, 'technicalCommitteeMembership'),js-packages/tests/pallet-presence.test.tsdiffbeforeafterboth80 'scheduler',80 'scheduler',81 'technicalcommittee',81 'technicalcommittee',82 'technicalcommitteemembership',82 'technicalcommitteemembership',83 'financialcouncil',84 'financialcouncilmembership',83 'identity',85 'identity',84 ];86 ];85 const testUtils = 'testutils';87 const testUtils = 'testutils';js-packages/tests/sub/governance/council.test.tsdiffbeforeafterboth2import type {IKeyringPair} from '@polkadot/types/types';2import type {IKeyringPair} from '@polkadot/types/types';3import {usingPlaygrounds, itSub, expect, Pallets, requirePalletsOrSkip, describeGov} from '@unique/test-utils/util.js';3import {usingPlaygrounds, itSub, expect, Pallets, requirePalletsOrSkip, describeGov} from '@unique/test-utils/util.js';4import {Event} from '@unique/test-utils';4import {Event} from '@unique/test-utils';5import {initCouncil, democracyLaunchPeriod, democracyVotingPeriod, democracyEnactmentPeriod, councilMotionDuration, democracyFastTrackVotingPeriod, fellowshipRankLimit, clearCouncil, clearTechComm, initTechComm, clearFellowship, dummyProposal, dummyProposalCall, initFellowship, defaultEnactmentMoment, fellowshipPropositionOrigin} from './util.js';5import {initCouncil, democracyLaunchPeriod, democracyVotingPeriod, democracyEnactmentPeriod, councilMotionDuration, democracyFastTrackVotingPeriod, fellowshipRankLimit, clearCouncil, clearTechComm, initTechComm, clearFellowship, dummyProposal, dummyProposalCall, initFellowship, defaultEnactmentMoment, fellowshipPropositionOrigin, initFinCouncil} from './util.js';6import type {ICounselors} from './util.js';6import type {ICounselors} from './util.js';778describeGov('Governance: Council tests', () => {8describeGov('Governance: Council tests', () => {192 expect(techCommMembers).to.not.contains(techComm.andy.address);192 expect(techCommMembers).to.not.contains(techComm.andy.address);193 });193 });194195 itSub('Council can remove FinCouncil member', async ({helper}) => {196 const finCouncil = await initFinCouncil(donor, sudoer);197 const removeMemberPrpoposal = helper.finCouncil.membership.removeMemberCall(finCouncil.andy.address);198 await proposalFromMoreThanHalfCouncil(removeMemberPrpoposal);199200 const finCouncilMembers = await helper.finCouncil.membership.getMembers();201 expect(finCouncilMembers).to.not.contains(finCouncil.andy.address);202 });203204 itSub('Council can add FinCouncil member', async ({helper}) => {205 await initFinCouncil(donor, sudoer);206 const newFinCouncilMember = helper.arrange.createEmptyAccount();207 const addMemberPrpoposal = helper.finCouncil.membership.addMemberCall(newFinCouncilMember.address);208 await proposalFromMoreThanHalfCouncil(addMemberPrpoposal);209210 const finCouncilMembers = await helper.finCouncil.membership.getMembers();211 expect(finCouncilMembers).to.contains(newFinCouncilMember.address);212 });194213195 itSub.skip('Council member can add Fellowship member', async ({helper}) => {214 itSub.skip('Council member can add Fellowship member', async ({helper}) => {196 const newFellowshipMember = helper.arrange.createEmptyAccount();215 const newFellowshipMember = helper.arrange.createEmptyAccount();328 )).to.be.rejectedWith('BadOrigin');347 )).to.be.rejectedWith('BadOrigin');329 });348 });349350 itSub('[Negative] Council member can\'t add FinCouncil member', async ({helper}) => {351 const newFinCouncilMember = helper.arrange.createEmptyAccount();352 await expect(helper.council.collective.execute(353 counselors.alex,354 helper.finCouncil.membership.addMemberCall(newFinCouncilMember.address),355 )).rejectedWith('BadOrigin');356 });357358 itSub('[Negative] Council member can\'t remove FinCouncil member', async ({helper}) => {359 const finCouncil = await initFinCouncil(donor, sudoer);360 await expect(helper.council.collective.execute(361 counselors.alex,362 helper.finCouncil.membership.removeMemberCall(finCouncil.ildar.address),363 )).rejectedWith('BadOrigin');364 });330365331 itSub('[Negative] Council member cannot promote/demote a Fellowship member', async ({helper}) => {366 itSub('[Negative] Council member cannot promote/demote a Fellowship member', async ({helper}) => {332 const fellowship = await initFellowship(donor, sudoer);367 const fellowship = await initFellowship(donor, sudoer);454 await expect(helper.council.collective.close(counselors.filip, proposalHash, proposalIndex)).to.be.rejectedWith('TooEarly');489 await expect(helper.council.collective.close(counselors.filip, proposalHash, proposalIndex)).to.be.rejectedWith('TooEarly');455 });490 });456491492 itSub('[Negative] Council can\'t veto Democracy proposals', async ({helper}) => {493 const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);494 await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);495496 await expect(proposalFromAllCouncil(helper.democracy.vetoExternalCall(preimageHash)))497 .rejectedWith('BadOrigin');498 });499500 itSub('[Negative] Council member can\'t veto Democracy proposals', async ({helper}) => {501 const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);502 await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);503504 await expect(helper.council.collective.execute(505 counselors.charu,506 helper.democracy.vetoExternalCall(preimageHash),507 )).rejectedWith('BadOrigin');508 });457});509});458510js-packages/tests/sub/governance/financialCouncil.test.tsdiffbeforeafterbothno changes
js-packages/tests/sub/governance/technicalCommittee.test.tsdiffbeforeafterboth130 await clearFellowship(sudoer);130 await clearFellowship(sudoer);131 });131 });132133 itSub('[Negative] TechComm can\'t add FinCouncil member', async ({helper}) => {134 const newFinCouncilMember = helper.arrange.createEmptyAccount();135 const addMemberProposal = helper.finCouncil.membership.addMemberCall(newFinCouncilMember.address);136 await expect(proposalFromAllCommittee(addMemberProposal)).rejectedWith('BadOrigin');137138 const finCouncilMembers = await helper.finCouncil.membership.getMembers();139 expect(finCouncilMembers).to.not.contains(newFinCouncilMember.address);140 });141142143 itSub('[Negative] TechComm member can\'t add FinCouncil member', async ({helper}) => {144 const newFinCouncilMember = helper.arrange.createEmptyAccount();145 await expect(helper.technicalCommittee.collective.execute(146 techcomms.greg,147 helper.finCouncil.membership.addMemberCall(newFinCouncilMember.address),148 )).rejectedWith('BadOrigin');149 });150151 itSub('[Negative] TechComm member cannot register foreign asset', async ({helper}) => {152 const location = {153 parents: 1,154 interior: {X3: [155 {156 Parachain: 1000,157 },158 {159 PalletInstance: 50,160 },161 {162 GeneralIndex: 1985,163 },164 ]},165 };166 const assetId = {Concrete: location};167168 const foreignAssetProposal = helper.constructApiCall(169 'api.tx.foreignAssets.forceRegisterForeignAsset',170 [{V3: assetId}, helper.util.str2vec('New Asset2'), 'NEW', {Fungible: 10}],171 );172173 await expect(helper.technicalCommittee.collective.execute(techcomms.andy, foreignAssetProposal))174 .to.be.rejectedWith('BadOrigin');175 });132176133 itSub('[Negative] TechComm cannot submit regular democracy proposal', async ({helper}) => {177 itSub('[Negative] TechComm cannot submit regular democracy proposal', async ({helper}) => {134 const councilProposal = await helper.democracy.proposeCall(dummyProposalCall(helper), 0n);178 const councilProposal = await helper.democracy.proposeCall(dummyProposalCall(helper), 0n);js-packages/tests/sub/governance/util.tsdiffbeforeafterboth30 irina: IKeyringPair;30 irina: IKeyringPair;31}31}3233export interface IFinCounselors {34 greg: IKeyringPair;35 ildar: IKeyringPair;36 andy: IKeyringPair;37}3832export interface ITechComms {39export interface ITechComms {33 greg: IKeyringPair;40 greg: IKeyringPair;34 andy: IKeyringPair;41 andy: IKeyringPair;35 constantine: IKeyringPair;42 constantine: IKeyringPair;36}43}4445export function initFinCouncil(donor: IKeyringPair, superuser: IKeyringPair): Promise<IFinCounselors> {46 return usingPlaygrounds(async (helper) => {47 const [greg, ildar, andy] = await helper.arrange.createAccounts([10_000n, 10_000n, 10_000n], donor);48 const sudo = helper.getSudo();49 {50 const members = (await helper.callRpc('api.query.financialCouncilMembership.members')).toJSON() as [];51 if(members.length != 0) {52 await clearFinCouncil(superuser);53 }54 }55 const expectedMembers = [greg, ildar, andy];56 for(const member of expectedMembers) {57 await sudo.executeExtrinsic(superuser, 'api.tx.financialCouncilMembership.addMember', [member.address]);58 }59 await sudo.executeExtrinsic(superuser, 'api.tx.financialCouncilMembership.setPrime', [greg.address]);60 {61 const members = (await helper.callRpc('api.query.financialCouncilMembership.members')).toJSON();62 expect(members).to.containSubset(expectedMembers.map((x: IKeyringPair) => x.address));63 expect(members.length).to.be.equal(expectedMembers.length);64 }6566 return {67 greg,68 ildar,69 andy,70 };71 });72}7374export async function clearFinCouncil(superuser: IKeyringPair) {75 await usingPlaygrounds(async (helper) => {76 let members = (await helper.callRpc('api.query.financialCouncilMembership.members')).toJSON();77 if(members.length) {78 const sudo = helper.getSudo();79 for(const address of members) {80 await sudo.executeExtrinsic(superuser, 'api.tx.financialCouncilMembership.removeMember', [address]);81 }82 members = (await helper.callRpc('api.query.financialCouncilMembership.members')).toJSON();83 }84 expect(members).to.be.deep.equal([]);85 });86}378738export async function initCouncil(donor: IKeyringPair, superuser: IKeyringPair) {88export async function initCouncil(donor: IKeyringPair, superuser: IKeyringPair) {39 let counselors: IKeyringPair[] = [];89 let counselors: IKeyringPair[] = [];pallets/foreign-assets/src/lib.rsdiffbeforeafterboth107 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;107 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;108108109 /// Origin for force registering of a foreign asset.109 /// Origin for force registering of a foreign asset.110 type ForceRegisterOrigin: EnsureOrigin<Self::RuntimeOrigin>;110 type ManagerOrigin: EnsureOrigin<Self::RuntimeOrigin>;111111112 /// The ID of the foreign assets pallet.112 /// The ID of the foreign assets pallet.113 type PalletId: Get<PalletId>;113 type PalletId: Get<PalletId>;197 token_prefix: CollectionTokenPrefix,197 token_prefix: CollectionTokenPrefix,198 mode: ForeignCollectionMode,198 mode: ForeignCollectionMode,199 ) -> DispatchResult {199 ) -> DispatchResult {200 T::ForceRegisterOrigin::ensure_origin(origin.clone())?;200 T::ManagerOrigin::ensure_origin(origin.clone())?;201201202 let asset_id: AssetId = versioned_asset_id202 let asset_id: AssetId = versioned_asset_id203 .as_ref()203 .as_ref()runtime/common/config/governance/financial_council.rsdiffbeforeafterbothno changes
runtime/common/config/governance/mod.rsdiffbeforeafterboth36};36};373738use crate::{38use crate::{39 Balances, Council, OriginCaller, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,39 Balances, Council, FinancialCouncil, OriginCaller, Preimage, Runtime, RuntimeCall,40 Scheduler, TechnicalCommittee, Treasury,40 RuntimeEvent, RuntimeOrigin, Scheduler, TechnicalCommittee, Treasury,41};41};424249pub mod technical_committee;49pub mod technical_committee;50pub use technical_committee::*;50pub use technical_committee::*;5152pub mod financial_council;53pub use financial_council::*;515452pub mod fellowship;55pub mod fellowship;53pub use fellowship::*;56pub use fellowship::*;runtime/common/config/pallets/foreign_asset.rsdiffbeforeafterboth40 type RuntimeEvent = RuntimeEvent;40 type RuntimeEvent = RuntimeEvent;414142 #[cfg(feature = "governance")]42 #[cfg(feature = "governance")]43 type ForceRegisterOrigin = governance::RootOrTechnicalCommitteeMember;43 type ManagerOrigin = governance::RootOrFinancialCouncilMember;444445 #[cfg(not(feature = "governance"))]45 #[cfg(not(feature = "governance"))]46 type ForceRegisterOrigin = EnsureRoot<Self::AccountId>;46 type ManagerOrigin = EnsureRoot<Self::AccountId>;474748 type PalletId = ForeignAssetPalletId;48 type PalletId = ForeignAssetPalletId;49 type SelfLocation = SelfLocation;49 type SelfLocation = SelfLocation;runtime/common/construct_runtime.rsdiffbeforeafterboth81 Scheduler: pallet_scheduler = 49,81 Scheduler: pallet_scheduler = 49,828283 #[cfg(feature = "governance")]83 #[cfg(feature = "governance")]84 FinancialCouncil: pallet_collective::<Instance3> = 97,8586 #[cfg(feature = "governance")]87 FinancialCouncilMembership: pallet_membership::<Instance3> = 98,8889 #[cfg(feature = "governance")]84 Origins: pallet_gov_origins = 99,90 Origins: pallet_gov_origins = 99,859186 // XCM helpers.92 // XCM helpers.runtime/opal/src/governance_timings.rsdiffbeforeafterboth53 }53 }54}54}5556pub mod financial_council {57 use super::*;5859 parameter_types! {60 pub FinancialCouncilMotionDuration: BlockNumber = 15 * MINUTES;61 }62}5563runtime/quartz/src/governance_timings.rsdiffbeforeafterboth53 }53 }54}54}5556pub mod financial_council {57 use super::*;5859 parameter_types! {60 pub FinancialCouncilMotionDuration: BlockNumber = 3 * DAYS;61 }62}5563runtime/unique/src/governance_timings.rsdiffbeforeafterboth53 }53 }54}54}5556pub mod financial_council {57 use super::*;5859 parameter_types! {60 pub FinancialCouncilMotionDuration: BlockNumber = 3 * DAYS;61 }62}5563