lib.rs 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660
  1. //! # Council module
  2. //! Council module for the the Joystream platform.
  3. //!
  4. //! ## Overview
  5. //!
  6. //! The Council module let's privileged network users elect their voted representation.
  7. //!
  8. //! Each council cycle is composed of three phases. The default phase is the candidacy announcement
  9. //! phase, during which users can announce their candidacy to the next council. After a fixed amount
  10. //! of time (network blocks) candidacy announcement phase concludes, and the next phase starts if a
  11. //! minimum number of candidates is announced; restarts the announcement phase otherwise. The next
  12. //! phase is the Election phase, during which users can vote for their selected candidate.
  13. //! The election itself is handled by the Referendum module. After elections end and a minimum
  14. //! amount of candidates received votes, a new council is appointed, and the Council module enters
  15. //! an Idle phase for the fixed amount of time before another round's candidacy announcements begin.
  16. //!
  17. //! The module supports requiring staking currency for the both candidacy and voting.
  18. //!
  19. //! ## Implementation
  20. //! When implementing runtime for this module, don't forget to call all ReferendumConnection trait
  21. //! functions at proper places. See the trait details for more information.
  22. //!
  23. //! ## Supported extrinsics
  24. //! - [announce_candidacy](./struct.Module.html#method.announce_candidacy)
  25. //! - [release_candidacy_stake](./struct.Module.html#method.release_candidacy_stake)
  26. //! - [set_candidacy_note](./struct.Module.html#method.set_candidacy_note)
  27. //! - [set_budget](./struct.Module.html#method.set_budget)
  28. //! - [plan_budget_refill](./struct.Module.html#method.plan_budget_refill)
  29. //! - [set_budget_increment](./struct.Module.html#method.set_budget_increment)
  30. //! - [set_councilor_reward](./struct.Module.html#method.set_councilor_reward)
  31. //! - [funding_request](./struct.Module.html#method.funding_request)
  32. //!
  33. //! ## Important functions
  34. //! These functions have to be called by the runtime for the council to work properly.
  35. //! - [recieve_referendum_results](./trait.ReferendumConnection.html#method.recieve_referendum_results)
  36. //! - [can_unlock_vote_stake](./trait.ReferendumConnection.html#method.can_unlock_vote_stake)
  37. //!
  38. //! ## Dependencies:
  39. //! - [referendum](../referendum/index.html)
  40. /////////////////// Configuration //////////////////////////////////////////////
  41. #![cfg_attr(not(feature = "std"), no_std)]
  42. // used dependencies
  43. use codec::{Decode, Encode};
  44. use frame_support::traits::{Currency, Get, LockIdentifier};
  45. use frame_support::weights::Weight;
  46. use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, error::BadOrigin};
  47. use core::marker::PhantomData;
  48. use frame_support::dispatch::DispatchResult;
  49. use frame_system::ensure_root;
  50. #[cfg(feature = "std")]
  51. use serde::{Deserialize, Serialize};
  52. use sp_runtime::traits::{Hash, SaturatedConversion, Saturating, Zero};
  53. use sp_std::vec::Vec;
  54. use common::council::CouncilOriginValidator;
  55. use common::membership::MemberOriginValidator;
  56. use common::{FundingRequestParameters, StakingAccountValidator};
  57. use referendum::{CastVote, OptionResult, ReferendumManager};
  58. use staking_handler::StakingHandler;
  59. // declared modules
  60. mod benchmarking;
  61. mod mock;
  62. mod tests;
  63. /////////////////// Data Structures ////////////////////////////////////////////
  64. /// Information about council's current state and when it changed the last time.
  65. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  66. #[derive(Encode, Decode, PartialEq, Eq, Debug, Default)]
  67. pub struct CouncilStageUpdate<BlockNumber> {
  68. stage: CouncilStage,
  69. changed_at: BlockNumber,
  70. }
  71. /// Possible council states.
  72. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  73. #[derive(Encode, Decode, PartialEq, Eq, Debug)]
  74. pub enum CouncilStage {
  75. /// Candidacy announcement period.
  76. Announcing(CouncilStageAnnouncing),
  77. /// Election of the new council.
  78. Election(CouncilStageElection),
  79. /// The idle phase - no new council election is running now.
  80. Idle,
  81. }
  82. impl Default for CouncilStage {
  83. fn default() -> CouncilStage {
  84. CouncilStage::Announcing(CouncilStageAnnouncing {
  85. candidates_count: 0,
  86. })
  87. }
  88. }
  89. /// Representation for announcing candidacy stage state.
  90. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  91. #[derive(Encode, Decode, PartialEq, Eq, Debug, Default)]
  92. pub struct CouncilStageAnnouncing {
  93. candidates_count: u64,
  94. }
  95. /// Representation for new council members election stage state.
  96. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  97. #[derive(Encode, Decode, PartialEq, Eq, Debug, Default)]
  98. pub struct CouncilStageElection {
  99. candidates_count: u64,
  100. }
  101. /// Candidate representation.
  102. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  103. #[derive(Encode, Decode, PartialEq, Eq, Debug, Default, Clone)]
  104. pub struct Candidate<AccountId, Balance, Hash, VotePower> {
  105. staking_account_id: AccountId,
  106. reward_account_id: AccountId,
  107. cycle_id: u64,
  108. stake: Balance,
  109. vote_power: VotePower,
  110. note_hash: Option<Hash>,
  111. }
  112. /// Council member representation.
  113. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  114. #[derive(Encode, Decode, PartialEq, Eq, Debug, Default, Clone)]
  115. pub struct CouncilMember<AccountId, MemberId, Balance, BlockNumber> {
  116. staking_account_id: AccountId,
  117. reward_account_id: AccountId,
  118. membership_id: MemberId,
  119. stake: Balance,
  120. last_payment_block: BlockNumber,
  121. unpaid_reward: Balance,
  122. }
  123. impl<AccountId, MemberId, Balance, BlockNumber>
  124. CouncilMember<AccountId, MemberId, Balance, BlockNumber>
  125. {
  126. pub fn member_id(&self) -> &MemberId {
  127. &self.membership_id
  128. }
  129. }
  130. impl<AccountId, MemberId, Balance, Hash, VotePower, BlockNumber>
  131. From<(
  132. Candidate<AccountId, Balance, Hash, VotePower>,
  133. MemberId,
  134. BlockNumber,
  135. Balance,
  136. )> for CouncilMember<AccountId, MemberId, Balance, BlockNumber>
  137. {
  138. fn from(
  139. from: (
  140. Candidate<AccountId, Balance, Hash, VotePower>,
  141. MemberId,
  142. BlockNumber,
  143. Balance,
  144. ),
  145. ) -> Self {
  146. Self {
  147. staking_account_id: from.0.staking_account_id,
  148. reward_account_id: from.0.reward_account_id,
  149. membership_id: from.1,
  150. stake: from.0.stake,
  151. last_payment_block: from.2,
  152. unpaid_reward: from.3,
  153. }
  154. }
  155. }
  156. /////////////////// Type aliases ///////////////////////////////////////////////
  157. pub type Balance<T> = <T as balances::Trait>::Balance;
  158. pub type VotePowerOf<T> = <<T as Trait>::Referendum as ReferendumManager<
  159. <T as frame_system::Trait>::Origin,
  160. <T as frame_system::Trait>::AccountId,
  161. <T as common::membership::MembershipTypes>::MemberId,
  162. <T as frame_system::Trait>::Hash,
  163. >>::VotePower;
  164. pub type CastVoteOf<T> = CastVote<
  165. <T as frame_system::Trait>::Hash,
  166. Balance<T>,
  167. <T as common::membership::MembershipTypes>::MemberId,
  168. >;
  169. pub type CouncilMemberOf<T> = CouncilMember<
  170. <T as frame_system::Trait>::AccountId,
  171. <T as common::membership::MembershipTypes>::MemberId,
  172. Balance<T>,
  173. <T as frame_system::Trait>::BlockNumber,
  174. >;
  175. pub type CandidateOf<T> = Candidate<
  176. <T as frame_system::Trait>::AccountId,
  177. Balance<T>,
  178. <T as frame_system::Trait>::Hash,
  179. VotePowerOf<T>,
  180. >;
  181. pub type CouncilStageUpdateOf<T> = CouncilStageUpdate<<T as frame_system::Trait>::BlockNumber>;
  182. /////////////////// Traits, Storage, Errors, and Events /////////////////////////
  183. /// council WeightInfo
  184. /// Note: This was auto generated through the benchmark CLI using the `--weight-trait` flag
  185. pub trait WeightInfo {
  186. fn set_budget_increment() -> Weight;
  187. fn set_councilor_reward() -> Weight;
  188. fn funding_request(i: u32) -> Weight;
  189. fn try_process_budget() -> Weight;
  190. fn try_progress_stage_idle() -> Weight;
  191. fn try_progress_stage_announcing_start_election(i: u32) -> Weight;
  192. fn try_progress_stage_announcing_restart() -> Weight;
  193. fn announce_candidacy() -> Weight;
  194. fn release_candidacy_stake() -> Weight;
  195. fn set_candidacy_note(i: u32) -> Weight;
  196. fn withdraw_candidacy() -> Weight;
  197. fn set_budget() -> Weight;
  198. fn plan_budget_refill() -> Weight;
  199. }
  200. type CouncilWeightInfo<T> = <T as Trait>::WeightInfo;
  201. /// The main council trait.
  202. pub trait Trait:
  203. frame_system::Trait + common::membership::MembershipTypes + balances::Trait
  204. {
  205. /// The overarching event type.
  206. type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
  207. /// Referendum used for council elections.
  208. type Referendum: ReferendumManager<Self::Origin, Self::AccountId, Self::MemberId, Self::Hash>;
  209. /// Minimum number of extra candidates needed for the valid election.
  210. /// Number of total candidates is equal to council size plus extra candidates.
  211. type MinNumberOfExtraCandidates: Get<u64>;
  212. /// Council member count
  213. type CouncilSize: Get<u64>;
  214. /// Minimum stake candidate has to lock
  215. type MinCandidateStake: Get<Balance<Self>>;
  216. /// Identifier for currency lock used for candidacy staking.
  217. type CandidacyLock: StakingHandler<
  218. Self::AccountId,
  219. Balance<Self>,
  220. Self::MemberId,
  221. LockIdentifier,
  222. >;
  223. /// Identifier for currency lock used for candidacy staking.
  224. type CouncilorLock: StakingHandler<
  225. Self::AccountId,
  226. Balance<Self>,
  227. Self::MemberId,
  228. LockIdentifier,
  229. >;
  230. /// Validates staking account ownership for a member.
  231. type StakingAccountValidator: common::StakingAccountValidator<Self>;
  232. /// Duration of annoncing period
  233. type AnnouncingPeriodDuration: Get<Self::BlockNumber>;
  234. /// Duration of idle period
  235. type IdlePeriodDuration: Get<Self::BlockNumber>;
  236. /// Interval for automatic reward payments.
  237. type ElectedMemberRewardPeriod: Get<Self::BlockNumber>;
  238. /// Interval between automatic budget refills.
  239. type BudgetRefillPeriod: Get<Self::BlockNumber>;
  240. /// Weight information for extrinsics in this pallet.
  241. type WeightInfo: WeightInfo;
  242. /// Hook called right after the new council is elected.
  243. fn new_council_elected(elected_members: &[CouncilMemberOf<Self>]);
  244. /// Validates member id and origin combination
  245. type MemberOriginValidator: MemberOriginValidator<
  246. Self::Origin,
  247. common::MemberId<Self>,
  248. Self::AccountId,
  249. >;
  250. }
  251. /// Trait with functions that MUST be called by the runtime with values received from the
  252. /// referendum module.
  253. pub trait ReferendumConnection<T: Trait> {
  254. /// Process referendum results. This function MUST be called in runtime's implementation of
  255. /// referendum's `process_results()`.
  256. fn recieve_referendum_results(
  257. winners: &[OptionResult<
  258. <T as common::membership::MembershipTypes>::MemberId,
  259. VotePowerOf<T>,
  260. >],
  261. );
  262. /// Process referendum results. This function MUST be called in runtime's implementation of
  263. /// referendum's `can_release_voting_stake()`.
  264. fn can_unlock_vote_stake(vote: &CastVoteOf<T>) -> Result<(), Error<T>>;
  265. /// Checks that user is indeed candidating. This function MUST be called in runtime's
  266. /// implementation of referendum's `is_valid_option_id()`.
  267. fn is_valid_candidate_id(membership_id: &T::MemberId) -> bool;
  268. /// Return current voting power for a selected candidate.
  269. fn get_option_power(membership_id: &T::MemberId) -> VotePowerOf<T>;
  270. /// Recieve vote (power) for a selected candidate.
  271. fn increase_option_power(membership_id: &T::MemberId, amount: &VotePowerOf<T>);
  272. }
  273. decl_storage! {
  274. trait Store for Module<T: Trait> as Council {
  275. /// Current council voting stage
  276. pub Stage get(fn stage) config(): CouncilStageUpdate<T::BlockNumber>;
  277. /// Current council members
  278. pub CouncilMembers get(fn council_members) config(): Vec<CouncilMemberOf<T>>;
  279. /// Map of all candidates that ever candidated and haven't unstake yet.
  280. pub Candidates get(fn candidates) config(): map hasher(blake2_128_concat)
  281. T::MemberId => Candidate<T::AccountId, Balance<T>, T::Hash, VotePowerOf::<T>>;
  282. /// Index of the current candidacy period. It is incremented everytime announcement period
  283. /// starts.
  284. pub AnnouncementPeriodNr get(fn announcement_period_nr) config(): u64;
  285. /// Budget for the council's elected members rewards.
  286. pub Budget get(fn budget) config(): Balance<T>;
  287. /// The next block in which the elected council member rewards will be payed.
  288. pub NextRewardPayments get(fn next_reward_payments) config(): T::BlockNumber;
  289. /// The next block in which the budget will be increased.
  290. pub NextBudgetRefill get(fn next_budget_refill) config(): T::BlockNumber;
  291. /// Amount of balance to be refilled every budget period
  292. pub BudgetIncrement get(fn budget_increment) config(): Balance<T>;
  293. /// Councilor reward per block
  294. pub CouncilorReward get(fn councilor_reward) config(): Balance<T>;
  295. }
  296. }
  297. decl_event! {
  298. pub enum Event<T>
  299. where
  300. Balance = Balance<T>,
  301. <T as frame_system::Trait>::BlockNumber,
  302. <T as common::membership::MembershipTypes>::MemberId,
  303. <T as frame_system::Trait>::AccountId,
  304. {
  305. /// New council was elected
  306. AnnouncingPeriodStarted(),
  307. /// Announcing period can't finish because of insufficient candidtate count
  308. NotEnoughCandidates(),
  309. /// Candidates are announced and voting starts
  310. VotingPeriodStarted(u64),
  311. /// New candidate announced
  312. NewCandidate(MemberId, AccountId, AccountId, Balance),
  313. /// New council was elected and appointed
  314. NewCouncilElected(Vec<MemberId>),
  315. /// New council was elected and appointed
  316. NewCouncilNotElected(),
  317. /// Candidacy stake that was no longer needed was released
  318. CandidacyStakeRelease(MemberId),
  319. /// Candidate has withdrawn his candidacy
  320. CandidacyWithdraw(MemberId),
  321. /// The candidate has set a new note for their candidacy
  322. CandidacyNoteSet(MemberId, Vec<u8>),
  323. /// The whole reward was paid to the council member.
  324. RewardPayment(MemberId, AccountId, Balance, Balance),
  325. /// Budget balance was changed by the root.
  326. BudgetBalanceSet(Balance),
  327. /// Budget balance was increased by automatic refill.
  328. BudgetRefill(Balance),
  329. /// The next budget refill was planned.
  330. BudgetRefillPlanned(BlockNumber),
  331. /// Budget increment has been updated.
  332. BudgetIncrementUpdated(Balance),
  333. /// Councilor reward has been updated.
  334. CouncilorRewardUpdated(Balance),
  335. /// Request has been funded
  336. RequestFunded(AccountId, Balance),
  337. }
  338. }
  339. decl_error! {
  340. /// Council errors
  341. pub enum Error for Module<T: Trait> {
  342. /// Origin is invalid.
  343. BadOrigin,
  344. /// User tried to announce candidacy outside of the candidacy announcement period.
  345. CantCandidateNow,
  346. /// User tried to release stake outside of the revealing period.
  347. CantReleaseStakeNow,
  348. /// Candidate haven't provided sufficient stake.
  349. CandidacyStakeTooLow,
  350. /// User tried to announce candidacy twice in the same elections.
  351. CantCandidateTwice,
  352. /// User tried to announce candidacy with an account that has the conflicting type of stake
  353. /// with candidacy stake and has not enough balance for staking for both purposes.
  354. ConflictingStake,
  355. /// Council member and candidates can't withdraw stake yet.
  356. StakeStillNeeded,
  357. /// User tried to release stake when no stake exists.
  358. NoStake,
  359. /// Insufficient balance for candidacy staking.
  360. InsufficientBalanceForStaking,
  361. /// Candidate can't vote for himself.
  362. CantVoteForYourself,
  363. /// Invalid membership.
  364. MemberIdNotMatchAccount,
  365. /// The combination of membership id and account id is invalid for unstaking an existing
  366. /// candidacy stake.
  367. InvalidAccountToStakeReuse,
  368. /// User tried to withdraw candidacy when not candidating.
  369. NotCandidatingNow,
  370. /// Can't withdraw candidacy outside of the candidacy announcement period.
  371. CantWithdrawCandidacyNow,
  372. /// The member is not a councilor.
  373. NotCouncilor,
  374. /// Insufficent funds in council for executing 'Funding Request'
  375. InsufficientFundsForFundingRequest,
  376. /// Fund request no balance
  377. ZeroBalanceFundRequest,
  378. /// The same account is recieving funds from the same request twice
  379. RepeatedFundRequestAccount,
  380. /// Funding requests without recieving accounts
  381. EmptyFundingRequests
  382. }
  383. }
  384. impl<T: Trait> PartialEq for Error<T> {
  385. fn eq(&self, other: &Self) -> bool {
  386. self.as_u8() == other.as_u8()
  387. }
  388. }
  389. impl<T: Trait> From<BadOrigin> for Error<T> {
  390. fn from(_error: BadOrigin) -> Self {
  391. Error::<T>::BadOrigin
  392. }
  393. }
  394. /////////////////// Module definition and implementation ///////////////////////
  395. decl_module! {
  396. pub struct Module<T: Trait> for enum Call where origin: T::Origin {
  397. /// Predefined errors
  398. type Error = Error<T>;
  399. /// Setup events
  400. fn deposit_event() = default;
  401. /// Minimum number of extra candidates needed for the valid election.
  402. /// Number of total candidates is equal to council size plus extra candidates.
  403. const MinNumberOfExtraCandidates: u64 = T::MinNumberOfExtraCandidates::get();
  404. /// Council member count
  405. const CouncilSize: u64 = T::CouncilSize::get();
  406. /// Minimum stake candidate has to lock
  407. const MinCandidateStake: Balance<T> = T::MinCandidateStake::get();
  408. /// Duration of annoncing period
  409. const AnnouncingPeriodDuration: T::BlockNumber = T::AnnouncingPeriodDuration::get();
  410. /// Duration of idle period
  411. const IdlePeriodDuration: T::BlockNumber = T::IdlePeriodDuration::get();
  412. /// Interval for automatic reward payments.
  413. const ElectedMemberRewardPeriod: T::BlockNumber = T::ElectedMemberRewardPeriod::get();
  414. /// Interval between automatic budget refills.
  415. const BudgetRefillPeriod: T::BlockNumber = T::BudgetRefillPeriod::get();
  416. /// Exports const - candidacy lock id.
  417. const CandidacyLockId: LockIdentifier = T::CandidacyLock::lock_id();
  418. /// Exports const - councilor lock id.
  419. const CouncilorLockId: LockIdentifier = T::CouncilorLock::lock_id();
  420. /////////////////// Lifetime ///////////////////////////////////////////
  421. // No origin so this is a priviledged call
  422. fn on_initialize() -> Weight {
  423. let now = frame_system::Module::<T>::block_number();
  424. // Council stage progress it returns the number of candidates
  425. // if in announcing stage
  426. let mb_candidate_count = Self::try_progress_stage(now);
  427. // Budget reward payment + budget refill
  428. Self::try_process_budget(now);
  429. // Calculates the weight using the candidate count
  430. Self::calculate_on_initialize_weight(mb_candidate_count)
  431. }
  432. /////////////////// Election-related ///////////////////////////////////
  433. /// Subscribe candidate
  434. ///
  435. /// # <weight>
  436. ///
  437. /// ## weight
  438. /// `O (1)`
  439. /// - db:
  440. /// - `O(1)` doesn't depend on the state or parameters
  441. /// # </weight>
  442. #[weight = CouncilWeightInfo::<T>::announce_candidacy()]
  443. pub fn announce_candidacy(
  444. origin,
  445. membership_id: T::MemberId,
  446. staking_account_id: T::AccountId,
  447. reward_account_id: T::AccountId,
  448. stake: Balance<T>
  449. ) -> Result<(), Error<T>> {
  450. // ensure action can be started
  451. let (stage_data, previous_staking_account_id) =
  452. EnsureChecks::<T>::can_announce_candidacy(
  453. origin,
  454. &membership_id,
  455. &staking_account_id,
  456. &stake
  457. )?;
  458. // prepare candidate
  459. let candidate =
  460. Self::prepare_new_candidate(
  461. staking_account_id.clone(),
  462. reward_account_id.clone(),
  463. stake
  464. );
  465. //
  466. // == MUTATION SAFE ==
  467. //
  468. if let Some(tmp_account_id) = previous_staking_account_id {
  469. Mutations::<T>::release_candidacy_stake(&membership_id, &tmp_account_id);
  470. }
  471. // update state
  472. Mutations::<T>::announce_candidacy(&stage_data, &membership_id, &candidate, &stake);
  473. // emit event
  474. Self::deposit_event(RawEvent::NewCandidate(
  475. membership_id,
  476. staking_account_id,
  477. reward_account_id,
  478. stake
  479. ));
  480. Ok(())
  481. }
  482. /// Release candidacy stake that is no longer needed.
  483. ///
  484. /// # <weight>
  485. ///
  486. /// ## weight
  487. /// `O (1)`
  488. /// - db:
  489. /// - `O(1)` doesn't depend on the state or parameters
  490. /// # </weight>
  491. #[weight = CouncilWeightInfo::<T>::release_candidacy_stake()]
  492. pub fn release_candidacy_stake(origin, membership_id: T::MemberId)
  493. -> Result<(), Error<T>> {
  494. let staking_account_id =
  495. EnsureChecks::<T>::can_release_candidacy_stake(origin, &membership_id)?;
  496. //
  497. // == MUTATION SAFE ==
  498. //
  499. // update state
  500. Mutations::<T>::release_candidacy_stake(&membership_id, &staking_account_id);
  501. // emit event
  502. Self::deposit_event(RawEvent::CandidacyStakeRelease(membership_id));
  503. Ok(())
  504. }
  505. /// Withdraw candidacy and release candidacy stake.
  506. ///
  507. /// # <weight>
  508. ///
  509. /// ## weight
  510. /// `O (1)`
  511. /// - db:
  512. /// - `O(1)` doesn't depend on the state or parameters
  513. /// # </weight>
  514. #[weight = CouncilWeightInfo::<T>::withdraw_candidacy()]
  515. pub fn withdraw_candidacy(origin, membership_id: T::MemberId) -> Result<(), Error<T>> {
  516. let (stage_data, candidate) =
  517. EnsureChecks::<T>::can_withdraw_candidacy(origin, &membership_id)?;
  518. //
  519. // == MUTATION SAFE ==
  520. //
  521. // update state
  522. Mutations::<T>::withdraw_candidacy(&stage_data, &membership_id, &candidate);
  523. // emit event
  524. Self::deposit_event(RawEvent::CandidacyWithdraw(membership_id));
  525. Ok(())
  526. }
  527. /// Set short description for the user's candidacy. Can be called anytime during user's candidacy.
  528. ///
  529. /// # <weight>
  530. ///
  531. /// ## weight
  532. /// `O (N)` where:
  533. /// `N` is the length of `note`
  534. /// - db:
  535. /// - `O(1)` doesn't depend on the state or parameters
  536. /// # </weight>
  537. #[weight = CouncilWeightInfo::<T>::set_candidacy_note(note.len().saturated_into())]
  538. pub fn set_candidacy_note(origin, membership_id: T::MemberId, note: Vec<u8>)
  539. -> Result<(), Error<T>> {
  540. // ensure action can be started
  541. EnsureChecks::<T>::can_set_candidacy_note(origin, &membership_id)?;
  542. //
  543. // == MUTATION SAFE ==
  544. //
  545. // calculate note's hash
  546. let note_hash = T::Hashing::hash(note.as_slice());
  547. // update state
  548. Mutations::<T>::set_candidacy_note(&membership_id, &note_hash);
  549. // emit event
  550. Self::deposit_event(RawEvent::CandidacyNoteSet(membership_id, note));
  551. Ok(())
  552. }
  553. /// Sets the budget balance.
  554. ///
  555. /// # <weight>
  556. ///
  557. /// ## weight
  558. /// `O (1)`
  559. /// - db:
  560. /// - `O(1)` doesn't depend on the state or parameters
  561. /// # </weight>
  562. #[weight = CouncilWeightInfo::<T>::set_budget()]
  563. pub fn set_budget(origin, balance: Balance<T>) -> Result<(), Error<T>> {
  564. // ensure action can be started
  565. EnsureChecks::<T>::can_set_budget(origin)?;
  566. //
  567. // == MUTATION SAFE ==
  568. //
  569. // update state
  570. Mutations::<T>::set_budget(balance);
  571. // emit event
  572. Self::deposit_event(RawEvent::BudgetBalanceSet(balance));
  573. Ok(())
  574. }
  575. /// Plan the next budget refill.
  576. ///
  577. /// # <weight>
  578. ///
  579. /// ## weight
  580. /// `O (1)`
  581. /// - db:
  582. /// - `O(1)` doesn't depend on the state or parameters
  583. /// # </weight>
  584. #[weight = CouncilWeightInfo::<T>::plan_budget_refill()]
  585. pub fn plan_budget_refill(origin, next_refill: T::BlockNumber) -> Result<(), Error<T>> {
  586. // ensure action can be started
  587. EnsureChecks::<T>::can_plan_budget_refill(origin)?;
  588. //
  589. // == MUTATION SAFE ==
  590. //
  591. // update state
  592. Mutations::<T>::plan_budget_refill(&next_refill);
  593. // emit event
  594. Self::deposit_event(RawEvent::BudgetRefillPlanned(next_refill));
  595. Ok(())
  596. }
  597. /// Sets the budget refill amount
  598. ///
  599. /// # <weight>
  600. ///
  601. /// ## weight
  602. /// `O (1)`
  603. /// - db:
  604. /// - `O(1)` doesn't depend on the state or parameters
  605. /// # </weight>
  606. #[weight = CouncilWeightInfo::<T>::set_budget_increment()]
  607. pub fn set_budget_increment(origin, budget_increment: Balance<T>) -> Result<(), Error<T>> {
  608. // ensure action can be started
  609. EnsureChecks::<T>::can_set_budget_increment(origin)?;
  610. //
  611. // == MUTATION SAFE ==
  612. //
  613. // update state
  614. Mutations::<T>::set_budget_increment(budget_increment);
  615. // emit event
  616. Self::deposit_event(RawEvent::BudgetIncrementUpdated(budget_increment));
  617. Ok(())
  618. }
  619. /// Sets the councilor reward per block
  620. ///
  621. /// # <weight>
  622. ///
  623. /// ## weight
  624. /// `O (1)`
  625. /// - db:
  626. /// - `O(1)` doesn't depend on the state or parameters
  627. /// # </weight>
  628. #[weight = CouncilWeightInfo::<T>::set_councilor_reward()]
  629. pub fn set_councilor_reward(origin, councilor_reward: Balance<T>) -> Result<(), Error<T>> {
  630. // ensure action can be started
  631. EnsureChecks::<T>::can_set_councilor_reward(origin)?;
  632. //
  633. // == MUTATION SAFE ==
  634. //
  635. // update state
  636. Mutations::<T>::set_councilor_reward(councilor_reward);
  637. // emit event
  638. Self::deposit_event(RawEvent::CouncilorRewardUpdated(councilor_reward));
  639. Ok(())
  640. }
  641. /// Transfers funds from council budget to account
  642. ///
  643. /// # <weight>
  644. ///
  645. /// ## weight
  646. /// `O (F)` where:
  647. /// `F` is the length of `funding_requests`
  648. /// - db:
  649. /// - `O(1)` doesn't depend on the state or parameters
  650. /// # </weight>
  651. #[weight = CouncilWeightInfo::<T>::funding_request(
  652. funding_requests.len().saturated_into()
  653. )]
  654. pub fn funding_request(
  655. origin,
  656. funding_requests: Vec<FundingRequestParameters<Balance<T>, T::AccountId>>
  657. ) {
  658. // Checks
  659. ensure_root(origin)?;
  660. let funding_total: Balance<T> =
  661. funding_requests.iter().fold(
  662. Zero::zero(),
  663. |accumulated, funding_request| accumulated.saturating_add(funding_request.amount),
  664. );
  665. let current_budget = Self::budget();
  666. ensure!(
  667. funding_total <= current_budget,
  668. Error::<T>::InsufficientFundsForFundingRequest
  669. );
  670. ensure!(!funding_requests.is_empty(), Error::<T>::EmptyFundingRequests);
  671. let mut recieving_accounts = Vec::<&T::AccountId>::new();
  672. for funding_request in &funding_requests {
  673. ensure!(
  674. funding_request.amount != Zero::zero(),
  675. Error::<T>::ZeroBalanceFundRequest
  676. );
  677. ensure!(
  678. !recieving_accounts.contains(&&funding_request.account),
  679. Error::<T>::RepeatedFundRequestAccount
  680. );
  681. recieving_accounts.push(&funding_request.account);
  682. }
  683. //
  684. // == MUTATION SAFE ==
  685. //
  686. Mutations::<T>::set_budget(current_budget.saturating_sub(funding_total));
  687. for funding_request in funding_requests {
  688. let amount = funding_request.amount;
  689. let account = funding_request.account;
  690. let _ = balances::Module::<T>::deposit_creating(&account, amount);
  691. Self::deposit_event(RawEvent::RequestFunded(account, amount));
  692. }
  693. }
  694. }
  695. }
  696. /////////////////// Inner logic ////////////////////////////////////////////////
  697. impl<T: Trait> Module<T> {
  698. /////////////////// Lifetime ///////////////////////////////////////////
  699. // Checkout expire of referendum stage.
  700. // Returns the number of candidates if currently in stage announcing
  701. fn try_progress_stage(now: T::BlockNumber) -> Option<u64> {
  702. // election progress
  703. match Stage::<T>::get().stage {
  704. CouncilStage::Announcing(stage_data) => {
  705. let number_of_candidates = stage_data.candidates_count;
  706. if now == Stage::<T>::get().changed_at + T::AnnouncingPeriodDuration::get() {
  707. Self::end_announcement_period(stage_data);
  708. }
  709. Some(number_of_candidates)
  710. }
  711. CouncilStage::Idle => {
  712. if now == Stage::<T>::get().changed_at + T::IdlePeriodDuration::get() {
  713. Self::end_idle_period();
  714. }
  715. None
  716. }
  717. _ => None,
  718. }
  719. }
  720. // Checkout elected council members reward payments.
  721. fn try_process_budget(now: T::BlockNumber) {
  722. // budget autorefill
  723. if now == NextBudgetRefill::<T>::get() {
  724. Self::refill_budget(now);
  725. }
  726. // council members rewards
  727. if now == NextRewardPayments::<T>::get() {
  728. Self::pay_elected_member_rewards(now);
  729. }
  730. }
  731. // Finish voting and start ravealing.
  732. fn end_announcement_period(stage_data: CouncilStageAnnouncing) {
  733. let min_candidate_count = T::CouncilSize::get() + T::MinNumberOfExtraCandidates::get();
  734. // reset announcing period when not enough candidates registered
  735. if stage_data.candidates_count < min_candidate_count {
  736. Mutations::<T>::start_announcing_period();
  737. // emit event
  738. Self::deposit_event(RawEvent::NotEnoughCandidates());
  739. return;
  740. }
  741. // update state
  742. Mutations::<T>::finalize_announcing_period(&stage_data);
  743. // emit event
  744. Self::deposit_event(RawEvent::VotingPeriodStarted(stage_data.candidates_count));
  745. }
  746. // Conclude election period and elect new council if possible.
  747. fn end_election_period(
  748. winners: &[OptionResult<
  749. <T as common::membership::MembershipTypes>::MemberId,
  750. VotePowerOf<T>,
  751. >],
  752. ) {
  753. let council_size = T::CouncilSize::get();
  754. if winners.len() as u64 != council_size {
  755. // reset candidacy announcement period
  756. Mutations::<T>::start_announcing_period();
  757. // emit event
  758. Self::deposit_event(RawEvent::NewCouncilNotElected());
  759. return;
  760. }
  761. let now: T::BlockNumber = <frame_system::Module<T>>::block_number();
  762. // prepare candidates that got elected
  763. let elected_members: Vec<CouncilMemberOf<T>> = winners
  764. .iter()
  765. .map(|item| {
  766. let membership_id = item.option_id;
  767. let candidate = Candidates::<T>::get(membership_id);
  768. // clear candidate record and unlock their candidacy stake
  769. Mutations::<T>::clear_candidate(&membership_id, &candidate);
  770. (candidate, membership_id, now, Zero::zero()).into()
  771. })
  772. .collect();
  773. // prepare council users for event
  774. let elected_council_users = elected_members
  775. .iter()
  776. .map(|item| item.membership_id)
  777. .collect();
  778. // update state
  779. Mutations::<T>::elect_new_council(elected_members.as_slice(), now);
  780. // emit event
  781. Self::deposit_event(RawEvent::NewCouncilElected(elected_council_users));
  782. // trigger new-council-elected hook
  783. T::new_council_elected(elected_members.as_slice());
  784. }
  785. // Finish idle period and start new council election cycle (announcing period).
  786. fn end_idle_period() {
  787. // update state
  788. Mutations::<T>::start_announcing_period();
  789. // emit event
  790. Self::deposit_event(RawEvent::AnnouncingPeriodStarted());
  791. }
  792. /////////////////// Budget-related /////////////////////////////////////
  793. // Refill (increase) the budget's balance.
  794. fn refill_budget(now: T::BlockNumber) {
  795. // get refill amount
  796. let refill_amount = Self::budget_increment();
  797. // refill budget
  798. Mutations::<T>::refill_budget(refill_amount);
  799. // calculate next refill block number
  800. let refill_period = T::BudgetRefillPeriod::get();
  801. let next_refill = now + refill_period;
  802. // plan next budget refill
  803. Mutations::<T>::plan_budget_refill(&next_refill);
  804. // emit events
  805. Self::deposit_event(RawEvent::BudgetRefill(refill_amount));
  806. Self::deposit_event(RawEvent::BudgetRefillPlanned(next_refill));
  807. }
  808. // Pay rewards to elected council members.
  809. fn pay_elected_member_rewards(now: T::BlockNumber) {
  810. let reward_per_block = Self::councilor_reward();
  811. let starting_balance = Budget::<T>::get();
  812. // pay reward to all council members
  813. let new_balance = CouncilMembers::<T>::get().iter().enumerate().fold(
  814. starting_balance,
  815. |balance, (member_index, council_member)| {
  816. // calculate unpaid reward
  817. let unpaid_reward =
  818. Calculations::<T>::get_current_reward(&council_member, reward_per_block, now);
  819. // depleted budget or no accumulated reward to be paid?
  820. if balance == Zero::zero() || unpaid_reward == Zero::zero() {
  821. // no need to update council member record here; their unpaid reward will be
  822. // recalculated next time rewards are paid
  823. // emit event
  824. Self::deposit_event(RawEvent::RewardPayment(
  825. council_member.membership_id,
  826. council_member.reward_account_id.clone(),
  827. Zero::zero(),
  828. unpaid_reward,
  829. ));
  830. return balance;
  831. }
  832. // calculate withdrawable balance
  833. let (available_balance, missing_balance) =
  834. Calculations::<T>::payable_reward(&balance, &unpaid_reward);
  835. // pay reward
  836. Mutations::<T>::pay_reward(
  837. member_index,
  838. &council_member.reward_account_id,
  839. &available_balance,
  840. &missing_balance,
  841. &now,
  842. );
  843. // emit event
  844. Self::deposit_event(RawEvent::RewardPayment(
  845. council_member.membership_id,
  846. council_member.reward_account_id.clone(),
  847. available_balance,
  848. missing_balance,
  849. ));
  850. // return new balance
  851. balance.saturating_sub(available_balance)
  852. },
  853. );
  854. // update state
  855. Mutations::<T>::finish_reward_payments(new_balance, now);
  856. }
  857. /////////////////// Utils //////////////////////////////////////////////////
  858. // Construct a new candidate for council election.
  859. fn prepare_new_candidate(
  860. staking_account_id: T::AccountId,
  861. reward_account_id: T::AccountId,
  862. stake: Balance<T>,
  863. ) -> CandidateOf<T> {
  864. Candidate {
  865. staking_account_id,
  866. reward_account_id,
  867. cycle_id: AnnouncementPeriodNr::get(),
  868. stake,
  869. vote_power: 0.into(),
  870. note_hash: None,
  871. }
  872. }
  873. fn calculate_on_initialize_weight(mb_candidate_count: Option<u64>) -> Weight {
  874. // Minimum weight for progress stage
  875. let weight = CouncilWeightInfo::<T>::try_progress_stage_idle()
  876. .max(CouncilWeightInfo::<T>::try_progress_stage_announcing_restart());
  877. let weight = if let Some(candidate_count) = mb_candidate_count {
  878. // We can use the candidate count to calculate the worst case
  879. // if we are in announcement period without an additional storage access
  880. weight.max(
  881. CouncilWeightInfo::<T>::try_progress_stage_announcing_start_election(
  882. candidate_count.saturated_into(),
  883. ),
  884. )
  885. } else {
  886. // If we don't have the candidate count we only take into account the weight
  887. // of the functions that doesn't depend on it
  888. weight
  889. };
  890. // Total weight = try progress weight + try process budget weight
  891. CouncilWeightInfo::<T>::try_process_budget().saturating_add(weight)
  892. }
  893. }
  894. impl<T: Trait> ReferendumConnection<T> for Module<T> {
  895. // Process candidates' results recieved from the referendum.
  896. fn recieve_referendum_results(
  897. winners: &[OptionResult<
  898. <T as common::membership::MembershipTypes>::MemberId,
  899. VotePowerOf<T>,
  900. >],
  901. ) {
  902. //
  903. // == MUTATION SAFE ==
  904. //
  905. // conclude election
  906. Self::end_election_period(winners);
  907. }
  908. // Check that it is a proper time to release stake.
  909. fn can_unlock_vote_stake(vote: &CastVoteOf<T>) -> Result<(), Error<T>> {
  910. let current_voting_cycle_id = AnnouncementPeriodNr::get();
  911. // allow release for very old votes
  912. if current_voting_cycle_id > vote.cycle_id + 1 {
  913. return Ok(());
  914. }
  915. // allow release for current cycle only in idle stage
  916. if current_voting_cycle_id == vote.cycle_id
  917. && !matches!(Stage::<T>::get().stage, CouncilStage::Idle)
  918. {
  919. return Err(Error::CantReleaseStakeNow);
  920. }
  921. let voting_for_winner = CouncilMembers::<T>::get()
  922. .iter()
  923. .map(|council_member| council_member.membership_id)
  924. .any(|membership_id| vote.vote_for == Some(membership_id));
  925. // allow release for vote from previous elections only when not voted for winner
  926. if current_voting_cycle_id == vote.cycle_id + 1 {
  927. // ensure vote was not cast for the one of winning candidates / council members
  928. if voting_for_winner {
  929. return Err(Error::CantReleaseStakeNow);
  930. }
  931. return Ok(());
  932. }
  933. // at this point vote.cycle_id == current_voting_cycle_id
  934. // ensure election has ended and voter haven't voted for winner
  935. if voting_for_winner || !matches!(Stage::<T>::get().stage, CouncilStage::Idle) {
  936. return Err(Error::CantReleaseStakeNow);
  937. }
  938. Ok(())
  939. }
  940. // Checks that user is indeed candidating.
  941. fn is_valid_candidate_id(membership_id: &T::MemberId) -> bool {
  942. if !Candidates::<T>::contains_key(membership_id) {
  943. return false;
  944. }
  945. let candidate = Candidates::<T>::get(membership_id);
  946. candidate.cycle_id == AnnouncementPeriodNr::get()
  947. }
  948. // Return current voting power for a selected candidate.
  949. fn get_option_power(membership_id: &T::MemberId) -> VotePowerOf<T> {
  950. if !Candidates::<T>::contains_key(membership_id) {
  951. return 0.into();
  952. }
  953. let candidate = Candidates::<T>::get(membership_id);
  954. candidate.vote_power
  955. }
  956. // Recieve vote (power) for a selected candidate.
  957. fn increase_option_power(membership_id: &T::MemberId, amount: &VotePowerOf<T>) {
  958. if !Candidates::<T>::contains_key(membership_id) {
  959. return;
  960. }
  961. Candidates::<T>::mutate(membership_id, |candidate| candidate.vote_power += *amount);
  962. }
  963. }
  964. /////////////////// Calculations ///////////////////////////////////////////////
  965. struct Calculations<T: Trait> {
  966. _dummy: PhantomData<T>, // 0-sized data meant only to bound generic parameters
  967. }
  968. impl<T: Trait> Calculations<T> {
  969. // Calculate current reward for the recipient.
  970. fn get_current_reward(
  971. council_member: &CouncilMemberOf<T>,
  972. reward_per_block: Balance<T>,
  973. now: T::BlockNumber,
  974. ) -> Balance<T> {
  975. // calculate currently unpaid reward for elected council member
  976. // previously_unpaid_reward +
  977. // (current_block_number - last_payment_block_number) *
  978. // reward_per_block
  979. council_member.unpaid_reward.saturating_add(
  980. now.saturating_sub(council_member.last_payment_block)
  981. .saturated_into::<u64>()
  982. .saturating_mul(reward_per_block.saturated_into())
  983. .saturated_into(),
  984. )
  985. }
  986. // Retrieve current budget's balance and calculate missing balance for reward payment.
  987. fn payable_reward(
  988. budget_balance: &Balance<T>,
  989. reward_amount: &Balance<T>,
  990. ) -> (Balance<T>, Balance<T>) {
  991. // check if reward has enough balance
  992. if reward_amount <= budget_balance {
  993. return (*reward_amount, Zero::zero());
  994. }
  995. // calculate missing balance
  996. let missing_balance = reward_amount.saturating_sub(*budget_balance);
  997. (*budget_balance, missing_balance)
  998. }
  999. }
  1000. /////////////////// Mutations //////////////////////////////////////////////////
  1001. struct Mutations<T: Trait> {
  1002. _dummy: PhantomData<T>, // 0-sized data meant only to bound generic parameters
  1003. }
  1004. impl<T: Trait> Mutations<T> {
  1005. /////////////////// Election-related ///////////////////////////////////
  1006. // Change the council stage to candidacy announcing stage.
  1007. fn start_announcing_period() {
  1008. let stage_data = CouncilStageAnnouncing {
  1009. candidates_count: 0,
  1010. };
  1011. let block_number = <frame_system::Module<T>>::block_number();
  1012. // set stage
  1013. Stage::<T>::put(CouncilStageUpdate {
  1014. stage: CouncilStage::Announcing(stage_data),
  1015. changed_at: block_number,
  1016. });
  1017. // increase anouncement cycle id
  1018. AnnouncementPeriodNr::mutate(|value| *value += 1);
  1019. }
  1020. // Change the council stage from the announcing to the election stage.
  1021. fn finalize_announcing_period(stage_data: &CouncilStageAnnouncing) {
  1022. let extra_winning_target_count = T::CouncilSize::get() - 1;
  1023. // start referendum
  1024. T::Referendum::force_start(extra_winning_target_count, AnnouncementPeriodNr::get());
  1025. let block_number = <frame_system::Module<T>>::block_number();
  1026. // change council state
  1027. Stage::<T>::put(CouncilStageUpdate {
  1028. stage: CouncilStage::Election(CouncilStageElection {
  1029. candidates_count: stage_data.candidates_count,
  1030. }),
  1031. changed_at: block_number,
  1032. });
  1033. }
  1034. // Elect new council after successful election.
  1035. fn elect_new_council(elected_members: &[CouncilMemberOf<T>], now: T::BlockNumber) {
  1036. let block_number = <frame_system::Module<T>>::block_number();
  1037. // change council state
  1038. Stage::<T>::mutate(|value| {
  1039. *value = CouncilStageUpdate {
  1040. stage: CouncilStage::Idle,
  1041. changed_at: block_number, // set current block as the start of next phase
  1042. }
  1043. });
  1044. // try to pay any unpaid rewards (any unpaid rewards after this will be discarded call)
  1045. Module::<T>::pay_elected_member_rewards(now);
  1046. // release stakes for previous council members
  1047. for council_member in CouncilMembers::<T>::get() {
  1048. T::CouncilorLock::unlock(&council_member.staking_account_id);
  1049. }
  1050. // set new council
  1051. CouncilMembers::<T>::put(elected_members.to_vec());
  1052. // setup elected member lock for new council's members
  1053. for council_member in CouncilMembers::<T>::get() {
  1054. // lock council member stake
  1055. T::CouncilorLock::lock(&council_member.staking_account_id, council_member.stake);
  1056. }
  1057. }
  1058. // Announce user's candidacy.
  1059. fn announce_candidacy(
  1060. stage_data: &CouncilStageAnnouncing,
  1061. membership_id: &T::MemberId,
  1062. candidate: &CandidateOf<T>,
  1063. stake: &Balance<T>,
  1064. ) {
  1065. // insert candidate to candidate registery
  1066. Candidates::<T>::insert(membership_id, candidate.clone());
  1067. // prepare new stage
  1068. let new_stage_data = CouncilStageAnnouncing {
  1069. candidates_count: stage_data.candidates_count + 1,
  1070. };
  1071. // store new stage
  1072. Stage::<T>::mutate(|value| {
  1073. *value = CouncilStageUpdate {
  1074. stage: CouncilStage::Announcing(new_stage_data),
  1075. // keep changed_at (and other values) - stage phase haven't changed
  1076. ..*value
  1077. }
  1078. });
  1079. // lock candidacy stake
  1080. T::CandidacyLock::lock(&candidate.staking_account_id, *stake);
  1081. }
  1082. fn withdraw_candidacy(
  1083. stage_data: &CouncilStageAnnouncing,
  1084. membership_id: &T::MemberId,
  1085. candidate: &CandidateOf<T>,
  1086. ) {
  1087. // release candidacy stake
  1088. Self::release_candidacy_stake(&membership_id, &candidate.staking_account_id);
  1089. // prepare new stage
  1090. let new_stage_data = CouncilStageAnnouncing {
  1091. candidates_count: stage_data.candidates_count.saturating_sub(1),
  1092. };
  1093. // store new stage
  1094. Stage::<T>::mutate(|value| {
  1095. *value = CouncilStageUpdate {
  1096. stage: CouncilStage::Announcing(new_stage_data),
  1097. // keep changed_at (and other values) - stage phase haven't changed
  1098. ..*value
  1099. }
  1100. });
  1101. }
  1102. // Release user's stake that was used for candidacy.
  1103. fn release_candidacy_stake(membership_id: &T::MemberId, account_id: &T::AccountId) {
  1104. // release stake amount
  1105. T::CandidacyLock::unlock(&account_id);
  1106. // remove candidate record
  1107. Candidates::<T>::remove(membership_id);
  1108. }
  1109. // Set a new candidacy note for a candidate in the current election.
  1110. fn set_candidacy_note(membership_id: &T::MemberId, note_hash: &T::Hash) {
  1111. Candidates::<T>::mutate(membership_id, |value| value.note_hash = Some(*note_hash));
  1112. }
  1113. // Removes member's candidacy record.
  1114. fn clear_candidate(membership_id: &T::MemberId, candidate: &CandidateOf<T>) {
  1115. // unlock candidacy stake
  1116. T::CandidacyLock::unlock(&candidate.staking_account_id);
  1117. // clear candidate record
  1118. Candidates::<T>::remove(membership_id);
  1119. }
  1120. /////////////////// Budget-related /////////////////////////////////////////
  1121. // Set budget balance
  1122. fn set_budget(balance: Balance<T>) {
  1123. Budget::<T>::put(balance);
  1124. }
  1125. // Refill budget's balance.
  1126. fn refill_budget(refill_amount: Balance<T>) {
  1127. Budget::<T>::mutate(|balance| *balance = balance.saturating_add(refill_amount));
  1128. }
  1129. // Plan next budget refill.
  1130. fn plan_budget_refill(refill_at: &T::BlockNumber) {
  1131. NextBudgetRefill::<T>::put(refill_at);
  1132. }
  1133. // Set budget increment.
  1134. fn set_budget_increment(budget_increment: Balance<T>) {
  1135. BudgetIncrement::<T>::put(budget_increment);
  1136. }
  1137. // Set councilor reward.
  1138. fn set_councilor_reward(councilor_reward: Balance<T>) {
  1139. CouncilorReward::<T>::put(councilor_reward);
  1140. }
  1141. // Pay reward to a single elected council member.
  1142. fn pay_reward(
  1143. member_index: usize,
  1144. account_id: &T::AccountId,
  1145. amount: &Balance<T>,
  1146. missing_balance: &Balance<T>,
  1147. now: &T::BlockNumber,
  1148. ) {
  1149. // mint tokens into reward account
  1150. let _ = balances::Module::<T>::deposit_creating(account_id, *amount);
  1151. // update elected council member
  1152. CouncilMembers::<T>::mutate(|members| {
  1153. members[member_index].last_payment_block = *now;
  1154. members[member_index].unpaid_reward = *missing_balance;
  1155. });
  1156. }
  1157. // Save reward-payments-related changes and plan the next reward payout.
  1158. fn finish_reward_payments(new_balance: Balance<T>, now: T::BlockNumber) {
  1159. // update budget's balance
  1160. Budget::<T>::put(new_balance);
  1161. // plan next rewards payment
  1162. let next_reward_block = now + T::ElectedMemberRewardPeriod::get();
  1163. NextRewardPayments::<T>::put(next_reward_block);
  1164. }
  1165. }
  1166. /////////////////// Ensure checks //////////////////////////////////////////////
  1167. struct EnsureChecks<T: Trait> {
  1168. _dummy: PhantomData<T>, // 0-sized data meant only to bound generic parameters
  1169. }
  1170. impl<T: Trait> EnsureChecks<T> {
  1171. /////////////////// Common checks //////////////////////////////////////////
  1172. fn ensure_user_membership(
  1173. origin: T::Origin,
  1174. membership_id: &T::MemberId,
  1175. ) -> Result<T::AccountId, Error<T>> {
  1176. let account_id = T::MemberOriginValidator::ensure_member_controller_account_origin(
  1177. origin,
  1178. *membership_id,
  1179. )
  1180. .map_err(|_| Error::MemberIdNotMatchAccount)?;
  1181. Ok(account_id)
  1182. }
  1183. /////////////////// Action checks //////////////////////////////////////////
  1184. // Ensures there is no problem in announcing candidacy.
  1185. fn can_announce_candidacy(
  1186. origin: T::Origin,
  1187. membership_id: &T::MemberId,
  1188. staking_account_id: &T::AccountId,
  1189. stake: &Balance<T>,
  1190. ) -> Result<(CouncilStageAnnouncing, Option<T::AccountId>), Error<T>> {
  1191. // ensure user's membership
  1192. Self::ensure_user_membership(origin, membership_id)?;
  1193. // ensure staking account's membership
  1194. if !T::StakingAccountValidator::is_member_staking_account(
  1195. &membership_id,
  1196. &staking_account_id,
  1197. ) {
  1198. return Err(Error::MemberIdNotMatchAccount);
  1199. }
  1200. // ensure there are no conflicting stake types for the account
  1201. if !T::CandidacyLock::is_account_free_of_conflicting_stakes(&staking_account_id) {
  1202. return Err(Error::ConflictingStake);
  1203. }
  1204. let stage_data = match Stage::<T>::get().stage {
  1205. CouncilStage::Announcing(stage_data) => stage_data,
  1206. _ => return Err(Error::CantCandidateNow),
  1207. };
  1208. // when previous candidacy record is present, ensure user is not candidating twice &
  1209. // prepare old stake for unlocking
  1210. let mut existing_staking_account_id = None;
  1211. if Candidates::<T>::contains_key(membership_id) {
  1212. let candidate = Candidates::<T>::get(membership_id);
  1213. // prevent user from candidating twice in the same election
  1214. if candidate.cycle_id == AnnouncementPeriodNr::get() {
  1215. return Err(Error::CantCandidateTwice);
  1216. }
  1217. // remember old staking account
  1218. existing_staking_account_id = Some(candidate.staking_account_id);
  1219. }
  1220. // ensure stake is above minimal threshold
  1221. if stake < &T::MinCandidateStake::get() {
  1222. return Err(Error::CandidacyStakeTooLow);
  1223. }
  1224. // ensure user has enough balance - includes any already locked candidacy stake as it will
  1225. // be reused
  1226. if !T::CandidacyLock::is_enough_balance_for_stake(&staking_account_id, *stake) {
  1227. return Err(Error::InsufficientBalanceForStaking);
  1228. }
  1229. Ok((stage_data, existing_staking_account_id))
  1230. }
  1231. // Ensures there is no problem in releasing old candidacy stake.
  1232. fn can_release_candidacy_stake(
  1233. origin: T::Origin,
  1234. membership_id: &T::MemberId,
  1235. ) -> Result<T::AccountId, Error<T>> {
  1236. // ensure user's membership
  1237. Self::ensure_user_membership(origin, membership_id)?;
  1238. // escape when no previous candidacy stake is present
  1239. if !Candidates::<T>::contains_key(membership_id) {
  1240. return Err(Error::NoStake);
  1241. }
  1242. let candidate = Candidates::<T>::get(membership_id);
  1243. // prevent user from releasing candidacy stake during election
  1244. if candidate.cycle_id == AnnouncementPeriodNr::get()
  1245. && !matches!(Stage::<T>::get().stage, CouncilStage::Idle)
  1246. {
  1247. return Err(Error::StakeStillNeeded);
  1248. }
  1249. Ok(candidate.staking_account_id)
  1250. }
  1251. // Ensures there is no problem in withdrawing already announced candidacy.
  1252. fn can_withdraw_candidacy(
  1253. origin: T::Origin,
  1254. membership_id: &T::MemberId,
  1255. ) -> Result<(CouncilStageAnnouncing, CandidateOf<T>), Error<T>> {
  1256. // ensure user's membership
  1257. Self::ensure_user_membership(origin, membership_id)?;
  1258. // escape when no previous candidacy stake is present
  1259. if !Candidates::<T>::contains_key(membership_id) {
  1260. return Err(Error::NotCandidatingNow);
  1261. }
  1262. let candidate = Candidates::<T>::get(membership_id);
  1263. // ensure candidacy announcing period is running now
  1264. let stage_data = match Stage::<T>::get().stage {
  1265. CouncilStage::Announcing(stage_data) => {
  1266. // ensure candidacy was announced in current election cycle
  1267. if candidate.cycle_id != AnnouncementPeriodNr::get() {
  1268. return Err(Error::NotCandidatingNow);
  1269. }
  1270. stage_data
  1271. }
  1272. _ => return Err(Error::CantWithdrawCandidacyNow),
  1273. };
  1274. Ok((stage_data, candidate))
  1275. }
  1276. // Ensures there is no problem in setting new note for the candidacy.
  1277. fn can_set_candidacy_note(
  1278. origin: T::Origin,
  1279. membership_id: &T::MemberId,
  1280. ) -> Result<(), Error<T>> {
  1281. // ensure user's membership
  1282. Self::ensure_user_membership(origin, membership_id)?;
  1283. // escape when no previous candidacy stake is present
  1284. if !Candidates::<T>::contains_key(membership_id) {
  1285. return Err(Error::NotCandidatingNow);
  1286. }
  1287. let candidate = Candidates::<T>::get(membership_id);
  1288. // ensure candidacy was announced in current election cycle
  1289. if candidate.cycle_id != AnnouncementPeriodNr::get() {
  1290. return Err(Error::NotCandidatingNow);
  1291. }
  1292. // ensure election hasn't ended yet
  1293. if let CouncilStage::Idle = Stage::<T>::get().stage {
  1294. return Err(Error::NotCandidatingNow);
  1295. }
  1296. Ok(())
  1297. }
  1298. // Ensures there is no problem in setting the budget balance.
  1299. fn can_set_budget(origin: T::Origin) -> Result<(), Error<T>> {
  1300. ensure_root(origin)?;
  1301. Ok(())
  1302. }
  1303. // Ensures there is no problem in planning next budget refill.
  1304. fn can_plan_budget_refill(origin: T::Origin) -> Result<(), Error<T>> {
  1305. ensure_root(origin)?;
  1306. Ok(())
  1307. }
  1308. // Ensures there is no problem in setting the budget increment.
  1309. fn can_set_budget_increment(origin: T::Origin) -> Result<(), Error<T>> {
  1310. ensure_root(origin)?;
  1311. Ok(())
  1312. }
  1313. // Ensures there is no problem in setting the councilor reward.
  1314. fn can_set_councilor_reward(origin: T::Origin) -> Result<(), Error<T>> {
  1315. ensure_root(origin)?;
  1316. Ok(())
  1317. }
  1318. }
  1319. impl<T: Trait + common::membership::MembershipTypes>
  1320. CouncilOriginValidator<T::Origin, T::MemberId, T::AccountId> for Module<T>
  1321. {
  1322. fn ensure_member_consulate(origin: T::Origin, member_id: T::MemberId) -> DispatchResult {
  1323. EnsureChecks::<T>::ensure_user_membership(origin, &member_id)?;
  1324. let is_councilor = Self::council_members()
  1325. .iter()
  1326. .any(|council_member| council_member.member_id() == &member_id);
  1327. ensure!(is_councilor, Error::<T>::NotCouncilor);
  1328. Ok(())
  1329. }
  1330. }
  1331. impl<T: Trait + balances::Trait> common::council::CouncilBudgetManager<Balance<T>> for Module<T> {
  1332. fn get_budget() -> Balance<T> {
  1333. Self::budget()
  1334. }
  1335. fn set_budget(budget: Balance<T>) {
  1336. Mutations::<T>::set_budget(budget);
  1337. }
  1338. }