From ce79d33f0d59ee7a864bad4ca2f907112ef49f9c Mon Sep 17 00:00:00 2001 From: Kurdistan Tech Ministry Date: Wed, 18 Feb 2026 23:36:31 +0300 Subject: [PATCH] feat(governance): activate OpenGov production periods and add Welati tracks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upgrade all 15 OpenGov track periods from Westend test values (minutes) to Polkadot production values (hours/days). Add 3 new Welati governance tracks (welati_election, welati_admin, citizenship_admin) with origins and XCM routing for RC → People Chain governance via OpenGov referenda. Bump spec_version: 1_020_007 → 1_020_008 --- .../people-pezkuwichain/src/xcm_config.rs | 30 +++ .../pezkuwichain/src/governance/mod.rs | 7 +- .../pezkuwichain/src/governance/origins.rs | 9 + .../pezkuwichain/src/governance/tracks.rs | 173 ++++++++++++------ pezkuwi/runtime/pezkuwichain/src/lib.rs | 2 +- .../runtime/pezkuwichain/src/xcm_config.rs | 22 ++- 6 files changed, 179 insertions(+), 64 deletions(-) diff --git a/pezcumulus/teyrchains/runtimes/people/people-pezkuwichain/src/xcm_config.rs b/pezcumulus/teyrchains/runtimes/people/people-pezkuwichain/src/xcm_config.rs index b8510dc2..1b5dc8a0 100644 --- a/pezcumulus/teyrchains/runtimes/people/people-pezkuwichain/src/xcm_config.rs +++ b/pezcumulus/teyrchains/runtimes/people/people-pezkuwichain/src/xcm_config.rs @@ -115,6 +115,34 @@ pub type FungibleTransactor = FungibleAdapter< (), >; +/// Converts relay chain Welati governance Plurality origins to Root. +/// +/// When an RC OpenGov referendum passes on a Welati track (40/41/42), the enacted call sends +/// an XCM Transact to this People Chain. The Welati origins are encoded as Plurality +/// (BodyId::Index(40/41/42)) from the relay parent. This converter maps them to Root so that +/// the welati pallet's `ensure_root` calls succeed. +/// +/// Recognized Welati body IDs: +/// - Index(40): WelatiElection — initiate/finalize elections +/// - Index(41): WelatiAdmin — tiki grants, official appointments +/// - Index(42): CitizenshipAdmin — citizenship revocation, trust score updates +pub struct RelayWelatiPluralityAsRoot; +impl xcm_executor::traits::ConvertOrigin for RelayWelatiPluralityAsRoot { + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + match (kind, origin.unpack()) { + ( + OriginKind::Superuser, + (1, [Plurality { id: BodyId::Index(40 | 41 | 42), .. }]), + ) => Ok(RuntimeOrigin::root()), + _ => Err(origin), + } + } +} + /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with XCM's `Transact`. There is an `OriginKind` that can /// bias the kind of local `Origin` it will become. @@ -132,6 +160,8 @@ pub type XcmOriginToTransactDispatchOrigin = ( // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a // transaction from the Root origin. ParentAsSuperuser, + // Welati governance origins from relay chain — converts Plurality(Index(40/41/42)) to Root. + RelayWelatiPluralityAsRoot, // Native signed account converter; this just converts an `AccountId32` origin into a normal // `RuntimeOrigin::Signed` origin of the same 32-byte value. SignedAccountId32AsNative, diff --git a/pezkuwi/runtime/pezkuwichain/src/governance/mod.rs b/pezkuwi/runtime/pezkuwichain/src/governance/mod.rs index f4072324..778b4a16 100644 --- a/pezkuwi/runtime/pezkuwichain/src/governance/mod.rs +++ b/pezkuwi/runtime/pezkuwichain/src/governance/mod.rs @@ -25,9 +25,10 @@ use pezframe_system::EnsureRootWithSuccess; mod origins; pub use origins::{ - pezpallet_custom_origins, AuctionAdmin, Fellows, FellowshipAdmin, FellowshipExperts, - FellowshipInitiates, FellowshipMasters, GeneralAdmin, LeaseAdmin, ReferendumCanceller, - ReferendumKiller, Spender, StakingAdmin, Treasurer, WhitelistedCaller, + pezpallet_custom_origins, AuctionAdmin, CitizenshipAdmin, Fellows, FellowshipAdmin, + FellowshipExperts, FellowshipInitiates, FellowshipMasters, GeneralAdmin, LeaseAdmin, + ReferendumCanceller, ReferendumKiller, Spender, StakingAdmin, Treasurer, WelatiAdmin, + WelatiElection, WhitelistedCaller, }; mod tracks; pub use tracks::TracksInfo; diff --git a/pezkuwi/runtime/pezkuwichain/src/governance/origins.rs b/pezkuwi/runtime/pezkuwichain/src/governance/origins.rs index 6fa23520..ea66030b 100644 --- a/pezkuwi/runtime/pezkuwichain/src/governance/origins.rs +++ b/pezkuwi/runtime/pezkuwichain/src/governance/origins.rs @@ -70,6 +70,12 @@ pub mod pezpallet_custom_origins { BigSpender, /// Origin able to dispatch a whitelisted call. WhitelistedCaller, + /// Origin for Welati election management (initiate/finalize elections on People Chain). + WelatiElection, + /// Origin for Welati administrative actions (tiki grants, appointments on People Chain). + WelatiAdmin, + /// Origin for citizenship management (revocation, trust score updates on People Chain). + CitizenshipAdmin, /// Origin commanded by any members of the Pezkuwi Fellowship (no Dan grade needed). FellowshipInitiates, /// Origin commanded by Pezkuwi Fellows (3rd Dan fellows or greater). @@ -141,6 +147,9 @@ pub mod pezpallet_custom_origins { ReferendumCanceller, ReferendumKiller, WhitelistedCaller, + WelatiElection, + WelatiAdmin, + CitizenshipAdmin, FellowshipInitiates: u16 = 0, Fellows: u16 = 3, FellowshipExperts: u16 = 5, diff --git a/pezkuwi/runtime/pezkuwichain/src/governance/tracks.rs b/pezkuwi/runtime/pezkuwichain/src/governance/tracks.rs index 35ee4482..30496b6b 100644 --- a/pezkuwi/runtime/pezkuwichain/src/governance/tracks.rs +++ b/pezkuwi/runtime/pezkuwichain/src/governance/tracks.rs @@ -68,17 +68,25 @@ const APP_WHITELISTED_CALLER: Curve = const SUP_WHITELISTED_CALLER: Curve = Curve::make_reciprocal(1, 28, percent(20), percent(5), percent(50)); -const TRACKS_DATA: [pezpallet_referenda::Track; 15] = [ +// Welati governance curves +const APP_WELATI_ELECTION: Curve = APP_ROOT; +const SUP_WELATI_ELECTION: Curve = SUP_ROOT; +const APP_WELATI_ADMIN: Curve = APP_GENERAL_ADMIN; +const SUP_WELATI_ADMIN: Curve = SUP_GENERAL_ADMIN; +const APP_CITIZENSHIP_ADMIN: Curve = APP_STAKING_ADMIN; +const SUP_CITIZENSHIP_ADMIN: Curve = SUP_STAKING_ADMIN; + +const TRACKS_DATA: [pezpallet_referenda::Track; 18] = [ pezpallet_referenda::Track { id: 0, info: pezpallet_referenda::TrackInfo { name: s("root"), max_deciding: 1, decision_deposit: 100 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 12 * MINUTES, - min_enactment_period: 5 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 24 * HOURS, min_approval: APP_ROOT, min_support: SUP_ROOT, }, @@ -89,10 +97,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("whitelisted_caller"), max_deciding: 100, decision_deposit: 10 * GRAND, - prepare_period: 6 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 4 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 30 * MINUTES, + decision_period: 28 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 10 * MINUTES, min_approval: APP_WHITELISTED_CALLER, min_support: SUP_WHITELISTED_CALLER, }, @@ -103,10 +111,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("staking_admin"), max_deciding: 10, decision_deposit: 5 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_STAKING_ADMIN, min_support: SUP_STAKING_ADMIN, }, @@ -117,10 +125,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("treasurer"), max_deciding: 10, decision_deposit: 1 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 5 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 24 * HOURS, min_approval: APP_TREASURER, min_support: SUP_TREASURER, }, @@ -131,10 +139,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("lease_admin"), max_deciding: 10, decision_deposit: 5 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_LEASE_ADMIN, min_support: SUP_LEASE_ADMIN, }, @@ -145,10 +153,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("fellowship_admin"), max_deciding: 10, decision_deposit: 5 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_FELLOWSHIP_ADMIN, min_support: SUP_FELLOWSHIP_ADMIN, }, @@ -159,10 +167,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("general_admin"), max_deciding: 10, decision_deposit: 5 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_GENERAL_ADMIN, min_support: SUP_GENERAL_ADMIN, }, @@ -173,10 +181,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("auction_admin"), max_deciding: 10, decision_deposit: 5 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_AUCTION_ADMIN, min_support: SUP_AUCTION_ADMIN, }, @@ -187,10 +195,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("referendum_canceller"), max_deciding: 1_000, decision_deposit: 10 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 14 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 7 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_REFERENDUM_CANCELLER, min_support: SUP_REFERENDUM_CANCELLER, }, @@ -201,10 +209,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("referendum_killer"), max_deciding: 1_000, decision_deposit: 50 * GRAND, - prepare_period: 8 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 8 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_REFERENDUM_KILLER, min_support: SUP_REFERENDUM_KILLER, }, @@ -216,8 +224,8 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = max_deciding: 200, decision_deposit: 1 * 3 * CENTS, prepare_period: 1 * MINUTES, - decision_period: 14 * MINUTES, - confirm_period: 4 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 10 * MINUTES, min_enactment_period: 1 * MINUTES, min_approval: APP_SMALL_TIPPER, min_support: SUP_SMALL_TIPPER, @@ -229,10 +237,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("big_tipper"), max_deciding: 100, decision_deposit: 10 * 3 * CENTS, - prepare_period: 4 * MINUTES, - decision_period: 14 * MINUTES, - confirm_period: 12 * MINUTES, - min_enactment_period: 3 * MINUTES, + prepare_period: 10 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 1 * HOURS, + min_enactment_period: 10 * MINUTES, min_approval: APP_BIG_TIPPER, min_support: SUP_BIG_TIPPER, }, @@ -243,10 +251,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("small_spender"), max_deciding: 50, decision_deposit: 100 * 3 * CENTS, - prepare_period: 10 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 10 * MINUTES, - min_enactment_period: 5 * MINUTES, + prepare_period: 4 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 12 * HOURS, + min_enactment_period: 24 * HOURS, min_approval: APP_SMALL_SPENDER, min_support: SUP_SMALL_SPENDER, }, @@ -257,10 +265,10 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("medium_spender"), max_deciding: 50, decision_deposit: 200 * 3 * CENTS, - prepare_period: 10 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 12 * MINUTES, - min_enactment_period: 5 * MINUTES, + prepare_period: 4 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 24 * HOURS, min_approval: APP_MEDIUM_SPENDER, min_support: SUP_MEDIUM_SPENDER, }, @@ -271,14 +279,57 @@ const TRACKS_DATA: [pezpallet_referenda::Track; 15] = name: s("big_spender"), max_deciding: 50, decision_deposit: 400 * 3 * CENTS, - prepare_period: 10 * MINUTES, - decision_period: 20 * MINUTES, - confirm_period: 14 * MINUTES, - min_enactment_period: 5 * MINUTES, + prepare_period: 4 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 48 * HOURS, + min_enactment_period: 24 * HOURS, min_approval: APP_BIG_SPENDER, min_support: SUP_BIG_SPENDER, }, }, + // Welati governance tracks (RC → People Chain via XCM) + pezpallet_referenda::Track { + id: 40, + info: pezpallet_referenda::TrackInfo { + name: s("welati_election"), + max_deciding: 1, + decision_deposit: 50 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 12 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_WELATI_ELECTION, + min_support: SUP_WELATI_ELECTION, + }, + }, + pezpallet_referenda::Track { + id: 41, + info: pezpallet_referenda::TrackInfo { + name: s("welati_admin"), + max_deciding: 10, + decision_deposit: 10 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 7 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_WELATI_ADMIN, + min_support: SUP_WELATI_ADMIN, + }, + }, + pezpallet_referenda::Track { + id: 42, + info: pezpallet_referenda::TrackInfo { + name: s("citizenship_admin"), + max_deciding: 10, + decision_deposit: 20 * GRAND, + prepare_period: 2 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 6 * HOURS, + min_enactment_period: 24 * HOURS, + min_approval: APP_CITIZENSHIP_ADMIN, + min_support: SUP_CITIZENSHIP_ADMIN, + }, + }, ]; pub struct TracksInfo; @@ -316,6 +367,10 @@ impl pezpallet_referenda::TracksInfo for TracksInfo { origins::Origin::SmallSpender => Ok(32), origins::Origin::MediumSpender => Ok(33), origins::Origin::BigSpender => Ok(34), + // Welati governance (RC → People Chain) + origins::Origin::WelatiElection => Ok(40), + origins::Origin::WelatiAdmin => Ok(41), + origins::Origin::CitizenshipAdmin => Ok(42), _ => Err(()), } } else { diff --git a/pezkuwi/runtime/pezkuwichain/src/lib.rs b/pezkuwi/runtime/pezkuwichain/src/lib.rs index 4ed20283..ee26192b 100644 --- a/pezkuwi/runtime/pezkuwichain/src/lib.rs +++ b/pezkuwi/runtime/pezkuwichain/src/lib.rs @@ -174,7 +174,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: alloc::borrow::Cow::Borrowed("pezkuwichain"), impl_name: alloc::borrow::Cow::Borrowed("parity-pezkuwichain"), authoring_version: 0, - spec_version: 1_020_007, + spec_version: 1_020_008, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 26, diff --git a/pezkuwi/runtime/pezkuwichain/src/xcm_config.rs b/pezkuwi/runtime/pezkuwichain/src/xcm_config.rs index dfed0880..cd8c8e65 100644 --- a/pezkuwi/runtime/pezkuwichain/src/xcm_config.rs +++ b/pezkuwi/runtime/pezkuwichain/src/xcm_config.rs @@ -22,7 +22,9 @@ use super::{ XcmPallet, }; -use crate::governance::StakingAdmin; +use crate::governance::{ + CitizenshipAdmin, StakingAdmin, WelatiAdmin, WelatiElection, +}; use pezframe_support::{ parameter_types, @@ -238,6 +240,12 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; /// Treasury pluralistic body. pub const TreasuryBodyId: BodyId = BodyId::Treasury; + /// Welati Election pluralistic body (People Chain governance via XCM). + pub const WelatiElectionBodyId: BodyId = BodyId::Index(40); + /// Welati Admin pluralistic body (People Chain tiki/appointment admin via XCM). + pub const WelatiAdminBodyId: BodyId = BodyId::Index(41); + /// Citizenship Admin pluralistic body (People Chain citizenship mgmt via XCM). + pub const CitizenshipAdminBodyId: BodyId = BodyId::Index(42); } /// Type to convert an `Origin` type value into a `Location` value which represents an interior @@ -257,6 +265,14 @@ pub type FellowsToPlurality = OriginToPluralityVoice; +/// Welati governance origin to Plurality converters (RC → People Chain via XCM). +pub type WelatiElectionToPlurality = + OriginToPluralityVoice; +pub type WelatiAdminToPlurality = + OriginToPluralityVoice; +pub type CitizenshipAdminToPlurality = + OriginToPluralityVoice; + /// Type to convert a pezpallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( @@ -266,6 +282,10 @@ pub type LocalPalletOriginToLocation = ( FellowsToPlurality, // Treasurer origin to be used in XCM as a corresponding Plurality `Location` value. TreasurerToPlurality, + // Welati governance origins — enable RC OpenGov to dispatch XCM to People Chain. + WelatiElectionToPlurality, + WelatiAdminToPlurality, + CitizenshipAdminToPlurality, ); impl pezpallet_xcm::Config for Runtime {