lib.rs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. //! # Proposals codex module
  2. //! Proposals `codex` module for the Joystream platform. Version 2.
  3. //! Component of the proposals system. It contains preset proposal types.
  4. //!
  5. //! ## Overview
  6. //!
  7. //! The proposals codex module serves as a facade and entry point of the proposals system. It uses
  8. //! proposals `engine` module to maintain a lifecycle of the proposal and to execute proposals.
  9. //! During the proposal creation, `codex` also create a discussion thread using the `discussion`
  10. //! proposals module. `Codex` uses predefined parameters (eg.:`voting_period`) for each proposal and
  11. //! encodes extrinsic calls from dependency modules in order to create proposals inside the `engine`
  12. //! module. For each proposal, [its crucial details](./enum.ProposalDetails.html) are saved to the
  13. //! `ProposalDetailsByProposalId` map.
  14. //!
  15. //! ### Supported extrinsics (proposal types)
  16. //! - [create_text_proposal](./struct.Module.html#method.create_text_proposal)
  17. //! - [create_runtime_upgrade_proposal](./struct.Module.html#method.create_runtime_upgrade_proposal)
  18. //! - [create_set_election_parameters_proposal](./struct.Module.html#method.create_set_election_parameters_proposal)
  19. //! - [create_set_content_working_group_mint_capacity_proposal](./struct.Module.html#method.create_set_content_working_group_mint_capacity_proposal)
  20. //! - [create_spending_proposal](./struct.Module.html#method.create_spending_proposal)
  21. //! - [create_set_lead_proposal](./struct.Module.html#method.create_set_lead_proposal)
  22. //! - [create_evict_storage_provider_proposal](./struct.Module.html#method.create_evict_storage_provider_proposal)
  23. //! - [create_set_validator_count_proposal](./struct.Module.html#method.create_set_validator_count_proposal)
  24. //! - [create_set_storage_role_parameters_proposal](./struct.Module.html#method.create_set_storage_role_parameters_proposal)
  25. //!
  26. //! ### Proposal implementations of this module
  27. //! - execute_text_proposal - prints the proposal to the log
  28. //! - execute_runtime_upgrade_proposal - sets the runtime code
  29. //!
  30. //! ### Dependencies:
  31. //! - [proposals engine](../substrate_proposals_engine_module/index.html)
  32. //! - [proposals discussion](../substrate_proposals_discussion_module/index.html)
  33. //! - [membership](../substrate_membership_module/index.html)
  34. //! - [governance](../substrate_governance_module/index.html)
  35. //! - [content_working_group](../substrate_content_working_group_module/index.html)
  36. //!
  37. //! ### Notes
  38. //! The module uses [ProposalEncoder](./trait.ProposalEncoder.html) to encode the proposal using
  39. //! its details. Encoded byte vector is passed to the _proposals engine_ as serialized executable code.
  40. // Clippy linter warning. TODO: remove after the Constaninople release
  41. #![allow(clippy::type_complexity)]
  42. // disable it because of possible frontend API break
  43. // Clippy linter warning. TODO: refactor "this function has too many argument"
  44. #![allow(clippy::too_many_arguments)] // disable it because of possible API break
  45. // Ensure we're `no_std` when compiling for Wasm.
  46. #![cfg_attr(not(feature = "std"), no_std)]
  47. // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
  48. // #![warn(missing_docs)]
  49. mod proposal_types;
  50. #[cfg(test)]
  51. mod tests;
  52. use common::origin_validator::ActorOriginValidator;
  53. use governance::election_params::ElectionParameters;
  54. use proposal_engine::ProposalParameters;
  55. use roles::actors::RoleParameters;
  56. use rstd::clone::Clone;
  57. use rstd::prelude::*;
  58. use rstd::str::from_utf8;
  59. use rstd::vec::Vec;
  60. use sr_primitives::traits::Zero;
  61. use srml_support::dispatch::DispatchResult;
  62. use srml_support::traits::{Currency, Get};
  63. use srml_support::{decl_error, decl_module, decl_storage, ensure, print};
  64. use system::{ensure_root, RawOrigin};
  65. pub use crate::proposal_types::ProposalsConfigParameters;
  66. pub use proposal_types::{ProposalDetails, ProposalDetailsOf, ProposalEncoder};
  67. // 'Set working group mint capacity' proposal limit
  68. const CONTENT_WORKING_GROUP_MINT_CAPACITY_MAX_VALUE: u32 = 1_000_000;
  69. // Max allowed value for 'spending' proposal
  70. const MAX_SPENDING_PROPOSAL_VALUE: u32 = 2_000_000_u32;
  71. // Max validator count for the 'set validator count' proposal
  72. const MAX_VALIDATOR_COUNT: u32 = 100;
  73. // min_actors min value for the 'set storage role parameters' proposal
  74. const ROLE_PARAMETERS_MIN_ACTORS_MAX_VALUE: u32 = 2;
  75. // max_actors min value for the 'set storage role parameters' proposal
  76. const ROLE_PARAMETERS_MAX_ACTORS_MIN_VALUE: u32 = 2;
  77. // max_actors max value for the 'set storage role parameters' proposal
  78. const ROLE_PARAMETERS_MAX_ACTORS_MAX_VALUE: u32 = 100;
  79. // reward_period min value for the 'set storage role parameters' proposal
  80. const ROLE_PARAMETERS_REWARD_PERIOD_MIN_VALUE: u32 = 600;
  81. // reward_period max value for the 'set storage role parameters' proposal
  82. const ROLE_PARAMETERS_REWARD_PERIOD_MAX_VALUE: u32 = 3600;
  83. // bonding_period min value for the 'set storage role parameters' proposal
  84. const ROLE_PARAMETERS_BONDING_PERIOD_MIN_VALUE: u32 = 600;
  85. // bonding_period max value for the 'set storage role parameters' proposal
  86. const ROLE_PARAMETERS_BONDING_PERIOD_MAX_VALUE: u32 = 28800;
  87. // unbonding_period min value for the 'set storage role parameters' proposal
  88. const ROLE_PARAMETERS_UNBONDING_PERIOD_MIN_VALUE: u32 = 600;
  89. // unbonding_period max value for the 'set storage role parameters' proposal
  90. const ROLE_PARAMETERS_UNBONDING_PERIOD_MAX_VALUE: u32 = 28800;
  91. // min_service_period min value for the 'set storage role parameters' proposal
  92. const ROLE_PARAMETERS_MIN_SERVICE_PERIOD_MIN_VALUE: u32 = 600;
  93. // min_service_period max value for the 'set storage role parameters' proposal
  94. const ROLE_PARAMETERS_MIN_SERVICE_PERIOD_MAX_VALUE: u32 = 28800;
  95. // startup_grace_period min value for the 'set storage role parameters' proposal
  96. const ROLE_PARAMETERS_STARTUP_GRACE_PERIOD_MIN_VALUE: u32 = 600;
  97. // startup_grace_period max value for the 'set storage role parameters' proposal
  98. const ROLE_PARAMETERS_STARTUP_GRACE_PERIOD_MAX_VALUE: u32 = 28800;
  99. // min_stake min value for the 'set storage role parameters' proposal
  100. const ROLE_PARAMETERS_MIN_STAKE_MIN_VALUE: u32 = 0;
  101. // min_stake max value for the 'set storage role parameters' proposal
  102. const ROLE_PARAMETERS_MIN_STAKE_MAX_VALUE: u32 = 10_000_000;
  103. // entry_request_fee min value for the 'set storage role parameters' proposal
  104. const ROLE_PARAMETERS_ENTRY_REQUEST_FEE_MIN_VALUE: u32 = 0;
  105. // entry_request_fee max value for the 'set storage role parameters' proposal
  106. const ROLE_PARAMETERS_ENTRY_REQUEST_FEE_MAX_VALUE: u32 = 100_000;
  107. // reward min value for the 'set storage role parameters' proposal
  108. const ROLE_PARAMETERS_REWARD_MIN_VALUE: u32 = 0;
  109. // reward max value for the 'set storage role parameters' proposal
  110. const ROLE_PARAMETERS_REWARD_MAX_VALUE: u32 = 1000;
  111. // council_size min value for the 'set election parameters' proposal
  112. const ELECTION_PARAMETERS_COUNCIL_SIZE_MIN_VALUE: u32 = 4;
  113. // council_size max value for the 'set election parameters' proposal
  114. const ELECTION_PARAMETERS_COUNCIL_SIZE_MAX_VALUE: u32 = 20;
  115. // candidacy_limit min value for the 'set election parameters' proposal
  116. const ELECTION_PARAMETERS_CANDIDACY_LIMIT_MIN_VALUE: u32 = 25;
  117. // candidacy_limit max value for the 'set election parameters' proposal
  118. const ELECTION_PARAMETERS_CANDIDACY_LIMIT_MAX_VALUE: u32 = 100;
  119. // min_voting_stake min value for the 'set election parameters' proposal
  120. const ELECTION_PARAMETERS_MIN_STAKE_MIN_VALUE: u32 = 1;
  121. // min_voting_stake max value for the 'set election parameters' proposal
  122. const ELECTION_PARAMETERS_MIN_STAKE_MAX_VALUE: u32 = 100_000_u32;
  123. // new_term_duration min value for the 'set election parameters' proposal
  124. const ELECTION_PARAMETERS_NEW_TERM_DURATION_MIN_VALUE: u32 = 14400;
  125. // new_term_duration max value for the 'set election parameters' proposal
  126. const ELECTION_PARAMETERS_NEW_TERM_DURATION_MAX_VALUE: u32 = 432_000;
  127. // revealing_period min value for the 'set election parameters' proposal
  128. const ELECTION_PARAMETERS_REVEALING_PERIOD_MIN_VALUE: u32 = 14400;
  129. // revealing_period max value for the 'set election parameters' proposal
  130. const ELECTION_PARAMETERS_REVEALING_PERIOD_MAX_VALUE: u32 = 28800;
  131. // voting_period min value for the 'set election parameters' proposal
  132. const ELECTION_PARAMETERS_VOTING_PERIOD_MIN_VALUE: u32 = 14400;
  133. // voting_period max value for the 'set election parameters' proposal
  134. const ELECTION_PARAMETERS_VOTING_PERIOD_MAX_VALUE: u32 = 28800;
  135. // announcing_period min value for the 'set election parameters' proposal
  136. const ELECTION_PARAMETERS_ANNOUNCING_PERIOD_MIN_VALUE: u32 = 14400;
  137. // announcing_period max value for the 'set election parameters' proposal
  138. const ELECTION_PARAMETERS_ANNOUNCING_PERIOD_MAX_VALUE: u32 = 43200;
  139. // min_council_stake min value for the 'set election parameters' proposal
  140. const ELECTION_PARAMETERS_MIN_COUNCIL_STAKE_MIN_VALUE: u32 = 1;
  141. // min_council_stake max value for the 'set election parameters' proposal
  142. const ELECTION_PARAMETERS_MIN_COUNCIL_STAKE_MAX_VALUE: u32 = 100_000_u32;
  143. /// 'Proposals codex' substrate module Trait
  144. pub trait Trait:
  145. system::Trait
  146. + proposal_engine::Trait
  147. + proposal_discussion::Trait
  148. + membership::members::Trait
  149. + governance::election::Trait
  150. + content_working_group::Trait
  151. + roles::actors::Trait
  152. + staking::Trait
  153. {
  154. /// Defines max allowed text proposal length.
  155. type TextProposalMaxLength: Get<u32>;
  156. /// Defines max wasm code length of the runtime upgrade proposal.
  157. type RuntimeUpgradeWasmProposalMaxLength: Get<u32>;
  158. /// Validates member id and origin combination
  159. type MembershipOriginValidator: ActorOriginValidator<
  160. Self::Origin,
  161. MemberId<Self>,
  162. Self::AccountId,
  163. >;
  164. /// Encodes the proposal usint its details
  165. type ProposalEncoder: ProposalEncoder<Self>;
  166. }
  167. /// Balance alias for `stake` module
  168. pub type BalanceOf<T> =
  169. <<T as stake::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
  170. /// Currency alias for `stake` module
  171. pub type CurrencyOf<T> = <T as stake::Trait>::Currency;
  172. /// Balance alias for GovernanceCurrency from `common` module. TODO: replace with BalanceOf
  173. pub type BalanceOfGovernanceCurrency<T> =
  174. <<T as common::currency::GovernanceCurrency>::Currency as Currency<
  175. <T as system::Trait>::AccountId,
  176. >>::Balance;
  177. /// Balance alias for token mint balance from `token mint` module. TODO: replace with BalanceOf
  178. pub type BalanceOfMint<T> =
  179. <<T as mint::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
  180. /// Negative imbalance alias for staking
  181. pub type NegativeImbalance<T> =
  182. <<T as stake::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
  183. type MemberId<T> = <T as membership::members::Trait>::MemberId;
  184. decl_error! {
  185. /// Codex module predefined errors
  186. pub enum Error {
  187. /// The size of the provided text for text proposal exceeded the limit
  188. TextProposalSizeExceeded,
  189. /// Provided text for text proposal is empty
  190. TextProposalIsEmpty,
  191. /// The size of the provided WASM code for the runtime upgrade proposal exceeded the limit
  192. RuntimeProposalSizeExceeded,
  193. /// Provided WASM code for the runtime upgrade proposal is empty
  194. RuntimeProposalIsEmpty,
  195. /// Invalid balance value for the spending proposal
  196. InvalidSpendingProposalBalance,
  197. /// Invalid validator count for the 'set validator count' proposal
  198. InvalidValidatorCount,
  199. /// Require root origin in extrinsics
  200. RequireRootOrigin,
  201. /// Invalid storage role parameter - min_actors
  202. InvalidStorageRoleParameterMinActors,
  203. /// Invalid storage role parameter - max_actors
  204. InvalidStorageRoleParameterMaxActors,
  205. /// Invalid storage role parameter - reward_period
  206. InvalidStorageRoleParameterRewardPeriod,
  207. /// Invalid storage role parameter - bonding_period
  208. InvalidStorageRoleParameterBondingPeriod,
  209. /// Invalid storage role parameter - unbonding_period
  210. InvalidStorageRoleParameterUnbondingPeriod,
  211. /// Invalid storage role parameter - min_service_period
  212. InvalidStorageRoleParameterMinServicePeriod,
  213. /// Invalid storage role parameter - startup_grace_period
  214. InvalidStorageRoleParameterStartupGracePeriod,
  215. /// Invalid council election parameter - council_size
  216. InvalidCouncilElectionParameterCouncilSize,
  217. /// Invalid council election parameter - candidacy-limit
  218. InvalidCouncilElectionParameterCandidacyLimit,
  219. /// Invalid council election parameter - min-voting_stake
  220. InvalidCouncilElectionParameterMinVotingStake,
  221. /// Invalid council election parameter - new_term_duration
  222. InvalidCouncilElectionParameterNewTermDuration,
  223. /// Invalid council election parameter - min_council_stake
  224. InvalidCouncilElectionParameterMinCouncilStake,
  225. /// Invalid council election parameter - revealing_period
  226. InvalidCouncilElectionParameterRevealingPeriod,
  227. /// Invalid council election parameter - voting_period
  228. InvalidCouncilElectionParameterVotingPeriod,
  229. /// Invalid council election parameter - announcing_period
  230. InvalidCouncilElectionParameterAnnouncingPeriod,
  231. /// Invalid council election parameter - min_stake
  232. InvalidStorageRoleParameterMinStake,
  233. /// Invalid council election parameter - reward
  234. InvalidStorageRoleParameterReward,
  235. /// Invalid council election parameter - entry_request_fee
  236. InvalidStorageRoleParameterEntryRequestFee,
  237. /// Invalid working group mint capacity parameter
  238. InvalidStorageWorkingGroupMintCapacity,
  239. /// Invalid 'set lead proposal' parameter - proposed lead cannot be a councilor
  240. InvalidSetLeadParameterCannotBeCouncilor
  241. }
  242. }
  243. impl From<system::Error> for Error {
  244. fn from(error: system::Error) -> Self {
  245. match error {
  246. system::Error::Other(msg) => Error::Other(msg),
  247. system::Error::RequireRootOrigin => Error::RequireRootOrigin,
  248. _ => Error::Other(error.into()),
  249. }
  250. }
  251. }
  252. impl From<proposal_engine::Error> for Error {
  253. fn from(error: proposal_engine::Error) -> Self {
  254. match error {
  255. proposal_engine::Error::Other(msg) => Error::Other(msg),
  256. proposal_engine::Error::RequireRootOrigin => Error::RequireRootOrigin,
  257. _ => Error::Other(error.into()),
  258. }
  259. }
  260. }
  261. impl From<proposal_discussion::Error> for Error {
  262. fn from(error: proposal_discussion::Error) -> Self {
  263. match error {
  264. proposal_discussion::Error::Other(msg) => Error::Other(msg),
  265. proposal_discussion::Error::RequireRootOrigin => Error::RequireRootOrigin,
  266. _ => Error::Other(error.into()),
  267. }
  268. }
  269. }
  270. // Storage for the proposals codex module
  271. decl_storage! {
  272. pub trait Store for Module<T: Trait> as ProposalCodex{
  273. /// Map proposal id to its discussion thread id
  274. pub ThreadIdByProposalId get(fn thread_id_by_proposal_id):
  275. map T::ProposalId => T::ThreadId;
  276. /// Map proposal id to proposal details
  277. pub ProposalDetailsByProposalId get(fn proposal_details_by_proposal_id):
  278. map T::ProposalId => ProposalDetails<
  279. BalanceOfMint<T>,
  280. BalanceOfGovernanceCurrency<T>,
  281. T::BlockNumber,
  282. T::AccountId,
  283. T::MemberId
  284. >;
  285. /// Voting period for the 'set validator count' proposal
  286. pub SetValidatorCountProposalVotingPeriod get(set_validator_count_proposal_voting_period)
  287. config(): T::BlockNumber;
  288. /// Grace period for the 'set validator count' proposal
  289. pub SetValidatorCountProposalGracePeriod get(set_validator_count_proposal_grace_period)
  290. config(): T::BlockNumber;
  291. /// Voting period for the 'runtime upgrade' proposal
  292. pub RuntimeUpgradeProposalVotingPeriod get(runtime_upgrade_proposal_voting_period)
  293. config(): T::BlockNumber;
  294. /// Grace period for the 'runtime upgrade' proposal
  295. pub RuntimeUpgradeProposalGracePeriod get(runtime_upgrade_proposal_grace_period)
  296. config(): T::BlockNumber;
  297. /// Voting period for the 'set election parameters' proposal
  298. pub SetElectionParametersProposalVotingPeriod get(set_election_parameters_proposal_voting_period)
  299. config(): T::BlockNumber;
  300. /// Grace period for the 'set election parameters' proposal
  301. pub SetElectionParametersProposalGracePeriod get(set_election_parameters_proposal_grace_period)
  302. config(): T::BlockNumber;
  303. /// Voting period for the 'text' proposal
  304. pub TextProposalVotingPeriod get(text_proposal_voting_period) config(): T::BlockNumber;
  305. /// Grace period for the 'text' proposal
  306. pub TextProposalGracePeriod get(text_proposal_grace_period) config(): T::BlockNumber;
  307. /// Voting period for the 'set content working group mint capacity' proposal
  308. pub SetContentWorkingGroupMintCapacityProposalVotingPeriod get(set_content_working_group_mint_capacity_proposal_voting_period)
  309. config(): T::BlockNumber;
  310. /// Grace period for the 'set content working group mint capacity' proposal
  311. pub SetContentWorkingGroupMintCapacityProposalGracePeriod get(set_content_working_group_mint_capacity_proposal_grace_period)
  312. config(): T::BlockNumber;
  313. /// Voting period for the 'set lead' proposal
  314. pub SetLeadProposalVotingPeriod get(set_lead_proposal_voting_period)
  315. config(): T::BlockNumber;
  316. /// Grace period for the 'set lead' proposal
  317. pub SetLeadProposalGracePeriod get(set_lead_proposal_grace_period)
  318. config(): T::BlockNumber;
  319. /// Voting period for the 'spending' proposal
  320. pub SpendingProposalVotingPeriod get(spending_proposal_voting_period) config(): T::BlockNumber;
  321. /// Grace period for the 'spending' proposal
  322. pub SpendingProposalGracePeriod get(spending_proposal_grace_period) config(): T::BlockNumber;
  323. /// Voting period for the 'evict storage provider' proposal
  324. pub EvictStorageProviderProposalVotingPeriod get(evict_storage_provider_proposal_voting_period)
  325. config(): T::BlockNumber;
  326. /// Grace period for the 'evict storage provider' proposal
  327. pub EvictStorageProviderProposalGracePeriod get(evict_storage_provider_proposal_grace_period)
  328. config(): T::BlockNumber;
  329. /// Voting period for the 'set storage role parameters' proposal
  330. pub SetStorageRoleParametersProposalVotingPeriod get(set_storage_role_parameters_proposal_voting_period)
  331. config(): T::BlockNumber;
  332. /// Grace period for the 'set storage role parameters' proposal
  333. pub SetStorageRoleParametersProposalGracePeriod get(set_storage_role_parameters_proposal_grace_period)
  334. config(): T::BlockNumber;
  335. }
  336. }
  337. decl_module! {
  338. /// Proposal codex substrate module Call
  339. pub struct Module<T: Trait> for enum Call where origin: T::Origin {
  340. /// Predefined errors
  341. type Error = Error;
  342. /// Exports max allowed text proposal length const.
  343. const TextProposalMaxLength: u32 = T::TextProposalMaxLength::get();
  344. /// Exports max wasm code length of the runtime upgrade proposal const.
  345. const RuntimeUpgradeWasmProposalMaxLength: u32 = T::RuntimeUpgradeWasmProposalMaxLength::get();
  346. /// Create 'Text (signal)' proposal type.
  347. pub fn create_text_proposal(
  348. origin,
  349. member_id: MemberId<T>,
  350. title: Vec<u8>,
  351. description: Vec<u8>,
  352. stake_balance: Option<BalanceOf<T>>,
  353. text: Vec<u8>,
  354. ) {
  355. ensure!(!text.is_empty(), Error::TextProposalIsEmpty);
  356. ensure!(text.len() as u32 <= T::TextProposalMaxLength::get(),
  357. Error::TextProposalSizeExceeded);
  358. let proposal_parameters = proposal_types::parameters::text_proposal::<T>();
  359. let proposal_details = ProposalDetails::<BalanceOfMint<T>, BalanceOfGovernanceCurrency<T>, T::BlockNumber, T::AccountId, MemberId<T>>::Text(text);
  360. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  361. Self::create_proposal(
  362. origin,
  363. member_id,
  364. title,
  365. description,
  366. stake_balance,
  367. proposal_code,
  368. proposal_parameters,
  369. proposal_details,
  370. )?;
  371. }
  372. /// Create 'Runtime upgrade' proposal type. Runtime upgrade can be initiated only by
  373. /// members from the hardcoded list `RuntimeUpgradeProposalAllowedProposers`
  374. pub fn create_runtime_upgrade_proposal(
  375. origin,
  376. member_id: MemberId<T>,
  377. title: Vec<u8>,
  378. description: Vec<u8>,
  379. stake_balance: Option<BalanceOf<T>>,
  380. wasm: Vec<u8>,
  381. ) {
  382. ensure!(!wasm.is_empty(), Error::RuntimeProposalIsEmpty);
  383. ensure!(wasm.len() as u32 <= T::RuntimeUpgradeWasmProposalMaxLength::get(),
  384. Error::RuntimeProposalSizeExceeded);
  385. let proposal_parameters = proposal_types::parameters::runtime_upgrade_proposal::<T>();
  386. let proposal_details = ProposalDetails::RuntimeUpgrade(wasm);
  387. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  388. Self::create_proposal(
  389. origin,
  390. member_id,
  391. title,
  392. description,
  393. stake_balance,
  394. proposal_code,
  395. proposal_parameters,
  396. proposal_details,
  397. )?;
  398. }
  399. /// Create 'Set election parameters' proposal type. This proposal uses `set_election_parameters()`
  400. /// extrinsic from the `governance::election module`.
  401. pub fn create_set_election_parameters_proposal(
  402. origin,
  403. member_id: MemberId<T>,
  404. title: Vec<u8>,
  405. description: Vec<u8>,
  406. stake_balance: Option<BalanceOf<T>>,
  407. election_parameters: ElectionParameters<BalanceOfGovernanceCurrency<T>, T::BlockNumber>,
  408. ) {
  409. election_parameters.ensure_valid()?;
  410. Self::ensure_council_election_parameters_valid(&election_parameters)?;
  411. let proposal_details = ProposalDetails::SetElectionParameters(election_parameters);
  412. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  413. let proposal_parameters =
  414. proposal_types::parameters::set_election_parameters_proposal::<T>();
  415. Self::create_proposal(
  416. origin,
  417. member_id,
  418. title,
  419. description,
  420. stake_balance,
  421. proposal_code,
  422. proposal_parameters,
  423. proposal_details,
  424. )?;
  425. }
  426. /// Create 'Set content working group mint capacity' proposal type.
  427. /// This proposal uses `set_mint_capacity()` extrinsic from the `content-working-group` module.
  428. pub fn create_set_content_working_group_mint_capacity_proposal(
  429. origin,
  430. member_id: MemberId<T>,
  431. title: Vec<u8>,
  432. description: Vec<u8>,
  433. stake_balance: Option<BalanceOf<T>>,
  434. mint_balance: BalanceOfMint<T>,
  435. ) {
  436. ensure!(
  437. mint_balance <= <BalanceOfMint<T>>::from(CONTENT_WORKING_GROUP_MINT_CAPACITY_MAX_VALUE),
  438. Error::InvalidStorageWorkingGroupMintCapacity
  439. );
  440. let proposal_parameters =
  441. proposal_types::parameters::set_content_working_group_mint_capacity_proposal::<T>();
  442. let proposal_details = ProposalDetails::SetContentWorkingGroupMintCapacity(mint_balance);
  443. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  444. Self::create_proposal(
  445. origin,
  446. member_id,
  447. title,
  448. description,
  449. stake_balance,
  450. proposal_code,
  451. proposal_parameters,
  452. proposal_details,
  453. )?;
  454. }
  455. /// Create 'Spending' proposal type.
  456. /// This proposal uses `spend_from_council_mint()` extrinsic from the `governance::council` module.
  457. pub fn create_spending_proposal(
  458. origin,
  459. member_id: MemberId<T>,
  460. title: Vec<u8>,
  461. description: Vec<u8>,
  462. stake_balance: Option<BalanceOf<T>>,
  463. balance: BalanceOfMint<T>,
  464. destination: T::AccountId,
  465. ) {
  466. ensure!(balance != BalanceOfMint::<T>::zero(), Error::InvalidSpendingProposalBalance);
  467. ensure!(
  468. balance <= <BalanceOfMint<T>>::from(MAX_SPENDING_PROPOSAL_VALUE),
  469. Error::InvalidSpendingProposalBalance
  470. );
  471. let proposal_parameters =
  472. proposal_types::parameters::spending_proposal::<T>();
  473. let proposal_details = ProposalDetails::Spending(balance, destination);
  474. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  475. Self::create_proposal(
  476. origin,
  477. member_id,
  478. title,
  479. description,
  480. stake_balance,
  481. proposal_code,
  482. proposal_parameters,
  483. proposal_details,
  484. )?;
  485. }
  486. /// Create 'Set lead' proposal type.
  487. /// This proposal uses `replace_lead()` extrinsic from the `content_working_group` module.
  488. pub fn create_set_lead_proposal(
  489. origin,
  490. member_id: MemberId<T>,
  491. title: Vec<u8>,
  492. description: Vec<u8>,
  493. stake_balance: Option<BalanceOf<T>>,
  494. new_lead: Option<(T::MemberId, T::AccountId)>
  495. ) {
  496. if let Some(lead) = new_lead.clone() {
  497. let account_id = lead.1;
  498. ensure!(
  499. !<governance::council::Module<T>>::is_councilor(&account_id),
  500. Error::InvalidSetLeadParameterCannotBeCouncilor
  501. );
  502. }
  503. let proposal_parameters =
  504. proposal_types::parameters::set_lead_proposal::<T>();
  505. let proposal_details = ProposalDetails::SetLead(new_lead);
  506. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  507. Self::create_proposal(
  508. origin,
  509. member_id,
  510. title,
  511. description,
  512. stake_balance,
  513. proposal_code,
  514. proposal_parameters,
  515. proposal_details,
  516. )?;
  517. }
  518. /// Create 'Evict storage provider' proposal type.
  519. /// This proposal uses `remove_actor()` extrinsic from the `roles::actors` module.
  520. pub fn create_evict_storage_provider_proposal(
  521. origin,
  522. member_id: MemberId<T>,
  523. title: Vec<u8>,
  524. description: Vec<u8>,
  525. stake_balance: Option<BalanceOf<T>>,
  526. actor_account: T::AccountId,
  527. ) {
  528. let proposal_parameters =
  529. proposal_types::parameters::evict_storage_provider_proposal::<T>();
  530. let proposal_details = ProposalDetails::EvictStorageProvider(actor_account);
  531. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  532. Self::create_proposal(
  533. origin,
  534. member_id,
  535. title,
  536. description,
  537. stake_balance,
  538. proposal_code,
  539. proposal_parameters,
  540. proposal_details,
  541. )?;
  542. }
  543. /// Create 'Evict storage provider' proposal type.
  544. /// This proposal uses `set_validator_count()` extrinsic from the Substrate `staking` module.
  545. pub fn create_set_validator_count_proposal(
  546. origin,
  547. member_id: MemberId<T>,
  548. title: Vec<u8>,
  549. description: Vec<u8>,
  550. stake_balance: Option<BalanceOf<T>>,
  551. new_validator_count: u32,
  552. ) {
  553. ensure!(
  554. new_validator_count >= <staking::Module<T>>::minimum_validator_count(),
  555. Error::InvalidValidatorCount
  556. );
  557. ensure!(
  558. new_validator_count <= MAX_VALIDATOR_COUNT,
  559. Error::InvalidValidatorCount
  560. );
  561. let proposal_parameters =
  562. proposal_types::parameters::set_validator_count_proposal::<T>();
  563. let proposal_details = ProposalDetails::SetValidatorCount(new_validator_count);
  564. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  565. Self::create_proposal(
  566. origin,
  567. member_id,
  568. title,
  569. description,
  570. stake_balance,
  571. proposal_code,
  572. proposal_parameters,
  573. proposal_details,
  574. )?;
  575. }
  576. /// Create 'Set storage roles parameters' proposal type.
  577. /// This proposal uses `set_role_parameters()` extrinsic from the Substrate `roles::actors` module.
  578. pub fn create_set_storage_role_parameters_proposal(
  579. origin,
  580. member_id: MemberId<T>,
  581. title: Vec<u8>,
  582. description: Vec<u8>,
  583. stake_balance: Option<BalanceOf<T>>,
  584. role_parameters: RoleParameters<BalanceOfGovernanceCurrency<T>, T::BlockNumber>
  585. ) {
  586. Self::ensure_storage_role_parameters_valid(&role_parameters)?;
  587. let proposal_parameters =
  588. proposal_types::parameters::set_storage_role_parameters_proposal::<T>();
  589. let proposal_details = ProposalDetails::SetStorageRoleParameters(role_parameters);
  590. let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
  591. Self::create_proposal(
  592. origin,
  593. member_id,
  594. title,
  595. description,
  596. stake_balance,
  597. proposal_code,
  598. proposal_parameters,
  599. proposal_details,
  600. )?;
  601. }
  602. // *************** Extrinsic to execute
  603. /// Text proposal extrinsic. Should be used as callable object to pass to the `engine` module.
  604. pub fn execute_text_proposal(
  605. origin,
  606. text: Vec<u8>,
  607. ) {
  608. ensure_root(origin)?;
  609. print("Text proposal: ");
  610. let text_string_result = from_utf8(text.as_slice());
  611. if let Ok(text_string) = text_string_result{
  612. print(text_string);
  613. }
  614. }
  615. /// Runtime upgrade proposal extrinsic.
  616. /// Should be used as callable object to pass to the `engine` module.
  617. pub fn execute_runtime_upgrade_proposal(
  618. origin,
  619. wasm: Vec<u8>,
  620. ) {
  621. let (cloned_origin1, cloned_origin2) = Self::double_origin(origin);
  622. ensure_root(cloned_origin1)?;
  623. print("Runtime upgrade proposal execution started.");
  624. <system::Module<T>>::set_code(cloned_origin2, wasm)?;
  625. print("Runtime upgrade proposal execution finished.");
  626. }
  627. }
  628. }
  629. impl<T: Trait> Module<T> {
  630. // Multiplies the T::Origin.
  631. // In our current substrate version system::Origin doesn't support clone(),
  632. // but it will be supported in latest up-to-date substrate version.
  633. // TODO: delete when T::Origin will support the clone()
  634. fn double_origin(origin: T::Origin) -> (T::Origin, T::Origin) {
  635. let coerced_origin = origin.into().ok().unwrap_or(RawOrigin::None);
  636. let (cloned_origin1, cloned_origin2) = match coerced_origin {
  637. RawOrigin::None => (RawOrigin::None, RawOrigin::None),
  638. RawOrigin::Root => (RawOrigin::Root, RawOrigin::Root),
  639. RawOrigin::Signed(account_id) => (
  640. RawOrigin::Signed(account_id.clone()),
  641. RawOrigin::Signed(account_id),
  642. ),
  643. };
  644. (cloned_origin1.into(), cloned_origin2.into())
  645. }
  646. // Generic template proposal builder
  647. fn create_proposal(
  648. origin: T::Origin,
  649. member_id: MemberId<T>,
  650. title: Vec<u8>,
  651. description: Vec<u8>,
  652. stake_balance: Option<BalanceOf<T>>,
  653. proposal_code: Vec<u8>,
  654. proposal_parameters: ProposalParameters<T::BlockNumber, BalanceOf<T>>,
  655. proposal_details: ProposalDetails<
  656. BalanceOfMint<T>,
  657. BalanceOfGovernanceCurrency<T>,
  658. T::BlockNumber,
  659. T::AccountId,
  660. T::MemberId,
  661. >,
  662. ) -> DispatchResult<Error> {
  663. let account_id = T::MembershipOriginValidator::ensure_actor_origin(origin, member_id)?;
  664. <proposal_engine::Module<T>>::ensure_create_proposal_parameters_are_valid(
  665. &proposal_parameters,
  666. &title,
  667. &description,
  668. stake_balance,
  669. )?;
  670. <proposal_discussion::Module<T>>::ensure_can_create_thread(member_id, &title)?;
  671. let discussion_thread_id =
  672. <proposal_discussion::Module<T>>::create_thread(member_id, title.clone())?;
  673. let proposal_id = <proposal_engine::Module<T>>::create_proposal(
  674. account_id,
  675. member_id,
  676. proposal_parameters,
  677. title,
  678. description,
  679. stake_balance,
  680. proposal_code,
  681. )?;
  682. <ThreadIdByProposalId<T>>::insert(proposal_id, discussion_thread_id);
  683. <ProposalDetailsByProposalId<T>>::insert(proposal_id, proposal_details);
  684. Ok(())
  685. }
  686. // validates storage role parameters for the 'Set storage role parameters' proposal
  687. fn ensure_storage_role_parameters_valid(
  688. role_parameters: &RoleParameters<BalanceOfGovernanceCurrency<T>, T::BlockNumber>,
  689. ) -> Result<(), Error> {
  690. ensure!(
  691. role_parameters.min_actors < ROLE_PARAMETERS_MIN_ACTORS_MAX_VALUE,
  692. Error::InvalidStorageRoleParameterMinActors
  693. );
  694. ensure!(
  695. role_parameters.max_actors >= ROLE_PARAMETERS_MAX_ACTORS_MIN_VALUE,
  696. Error::InvalidStorageRoleParameterMaxActors
  697. );
  698. ensure!(
  699. role_parameters.max_actors < ROLE_PARAMETERS_MAX_ACTORS_MAX_VALUE,
  700. Error::InvalidStorageRoleParameterMaxActors
  701. );
  702. ensure!(
  703. role_parameters.reward_period
  704. >= T::BlockNumber::from(ROLE_PARAMETERS_REWARD_PERIOD_MIN_VALUE),
  705. Error::InvalidStorageRoleParameterRewardPeriod
  706. );
  707. ensure!(
  708. role_parameters.reward_period
  709. <= T::BlockNumber::from(ROLE_PARAMETERS_REWARD_PERIOD_MAX_VALUE),
  710. Error::InvalidStorageRoleParameterRewardPeriod
  711. );
  712. ensure!(
  713. role_parameters.bonding_period
  714. >= T::BlockNumber::from(ROLE_PARAMETERS_BONDING_PERIOD_MIN_VALUE),
  715. Error::InvalidStorageRoleParameterBondingPeriod
  716. );
  717. ensure!(
  718. role_parameters.bonding_period
  719. <= T::BlockNumber::from(ROLE_PARAMETERS_BONDING_PERIOD_MAX_VALUE),
  720. Error::InvalidStorageRoleParameterBondingPeriod
  721. );
  722. ensure!(
  723. role_parameters.unbonding_period
  724. >= T::BlockNumber::from(ROLE_PARAMETERS_UNBONDING_PERIOD_MIN_VALUE),
  725. Error::InvalidStorageRoleParameterUnbondingPeriod
  726. );
  727. ensure!(
  728. role_parameters.unbonding_period
  729. <= T::BlockNumber::from(ROLE_PARAMETERS_UNBONDING_PERIOD_MAX_VALUE),
  730. Error::InvalidStorageRoleParameterUnbondingPeriod
  731. );
  732. ensure!(
  733. role_parameters.min_service_period
  734. >= T::BlockNumber::from(ROLE_PARAMETERS_MIN_SERVICE_PERIOD_MIN_VALUE),
  735. Error::InvalidStorageRoleParameterMinServicePeriod
  736. );
  737. ensure!(
  738. role_parameters.min_service_period
  739. <= T::BlockNumber::from(ROLE_PARAMETERS_MIN_SERVICE_PERIOD_MAX_VALUE),
  740. Error::InvalidStorageRoleParameterMinServicePeriod
  741. );
  742. ensure!(
  743. role_parameters.startup_grace_period
  744. >= T::BlockNumber::from(ROLE_PARAMETERS_STARTUP_GRACE_PERIOD_MIN_VALUE),
  745. Error::InvalidStorageRoleParameterStartupGracePeriod
  746. );
  747. ensure!(
  748. role_parameters.startup_grace_period
  749. <= T::BlockNumber::from(ROLE_PARAMETERS_STARTUP_GRACE_PERIOD_MAX_VALUE),
  750. Error::InvalidStorageRoleParameterStartupGracePeriod
  751. );
  752. ensure!(
  753. role_parameters.min_stake
  754. > <BalanceOfGovernanceCurrency<T>>::from(ROLE_PARAMETERS_MIN_STAKE_MIN_VALUE),
  755. Error::InvalidStorageRoleParameterMinStake
  756. );
  757. ensure!(
  758. role_parameters.min_stake
  759. <= <BalanceOfGovernanceCurrency<T>>::from(ROLE_PARAMETERS_MIN_STAKE_MAX_VALUE),
  760. Error::InvalidStorageRoleParameterMinStake
  761. );
  762. ensure!(
  763. role_parameters.entry_request_fee
  764. > <BalanceOfGovernanceCurrency<T>>::from(
  765. ROLE_PARAMETERS_ENTRY_REQUEST_FEE_MIN_VALUE
  766. ),
  767. Error::InvalidStorageRoleParameterEntryRequestFee
  768. );
  769. ensure!(
  770. role_parameters.entry_request_fee
  771. <= <BalanceOfGovernanceCurrency<T>>::from(
  772. ROLE_PARAMETERS_ENTRY_REQUEST_FEE_MAX_VALUE
  773. ),
  774. Error::InvalidStorageRoleParameterEntryRequestFee
  775. );
  776. ensure!(
  777. role_parameters.reward
  778. > <BalanceOfGovernanceCurrency<T>>::from(ROLE_PARAMETERS_REWARD_MIN_VALUE),
  779. Error::InvalidStorageRoleParameterReward
  780. );
  781. ensure!(
  782. role_parameters.reward
  783. < <BalanceOfGovernanceCurrency<T>>::from(ROLE_PARAMETERS_REWARD_MAX_VALUE),
  784. Error::InvalidStorageRoleParameterReward
  785. );
  786. Ok(())
  787. }
  788. /*
  789. entry_request_fee [tJOY] >0 <1% NA
  790. * Not enforced by runtime. Should not be displayed in the UI, or at least grayed out.
  791. ** Should not be displayed in the UI, or at least grayed out.
  792. */
  793. // validates council election parameters for the 'Set election parameters' proposal
  794. pub(crate) fn ensure_council_election_parameters_valid(
  795. election_parameters: &ElectionParameters<BalanceOfGovernanceCurrency<T>, T::BlockNumber>,
  796. ) -> Result<(), Error> {
  797. ensure!(
  798. election_parameters.council_size >= ELECTION_PARAMETERS_COUNCIL_SIZE_MIN_VALUE,
  799. Error::InvalidCouncilElectionParameterCouncilSize
  800. );
  801. ensure!(
  802. election_parameters.council_size <= ELECTION_PARAMETERS_COUNCIL_SIZE_MAX_VALUE,
  803. Error::InvalidCouncilElectionParameterCouncilSize
  804. );
  805. ensure!(
  806. election_parameters.candidacy_limit >= ELECTION_PARAMETERS_CANDIDACY_LIMIT_MIN_VALUE,
  807. Error::InvalidCouncilElectionParameterCandidacyLimit
  808. );
  809. ensure!(
  810. election_parameters.candidacy_limit <= ELECTION_PARAMETERS_CANDIDACY_LIMIT_MAX_VALUE,
  811. Error::InvalidCouncilElectionParameterCandidacyLimit
  812. );
  813. ensure!(
  814. election_parameters.min_voting_stake
  815. >= <BalanceOfGovernanceCurrency<T>>::from(ELECTION_PARAMETERS_MIN_STAKE_MIN_VALUE),
  816. Error::InvalidCouncilElectionParameterMinVotingStake
  817. );
  818. ensure!(
  819. election_parameters.min_voting_stake
  820. <= <BalanceOfGovernanceCurrency<T>>::from(ELECTION_PARAMETERS_MIN_STAKE_MAX_VALUE),
  821. Error::InvalidCouncilElectionParameterMinVotingStake
  822. );
  823. ensure!(
  824. election_parameters.new_term_duration
  825. >= T::BlockNumber::from(ELECTION_PARAMETERS_NEW_TERM_DURATION_MIN_VALUE),
  826. Error::InvalidCouncilElectionParameterNewTermDuration
  827. );
  828. ensure!(
  829. election_parameters.new_term_duration
  830. <= T::BlockNumber::from(ELECTION_PARAMETERS_NEW_TERM_DURATION_MAX_VALUE),
  831. Error::InvalidCouncilElectionParameterNewTermDuration
  832. );
  833. ensure!(
  834. election_parameters.revealing_period
  835. >= T::BlockNumber::from(ELECTION_PARAMETERS_REVEALING_PERIOD_MIN_VALUE),
  836. Error::InvalidCouncilElectionParameterRevealingPeriod
  837. );
  838. ensure!(
  839. election_parameters.revealing_period
  840. <= T::BlockNumber::from(ELECTION_PARAMETERS_REVEALING_PERIOD_MAX_VALUE),
  841. Error::InvalidCouncilElectionParameterRevealingPeriod
  842. );
  843. ensure!(
  844. election_parameters.voting_period
  845. >= T::BlockNumber::from(ELECTION_PARAMETERS_VOTING_PERIOD_MIN_VALUE),
  846. Error::InvalidCouncilElectionParameterVotingPeriod
  847. );
  848. ensure!(
  849. election_parameters.voting_period
  850. <= T::BlockNumber::from(ELECTION_PARAMETERS_VOTING_PERIOD_MAX_VALUE),
  851. Error::InvalidCouncilElectionParameterVotingPeriod
  852. );
  853. ensure!(
  854. election_parameters.announcing_period
  855. >= T::BlockNumber::from(ELECTION_PARAMETERS_ANNOUNCING_PERIOD_MIN_VALUE),
  856. Error::InvalidCouncilElectionParameterAnnouncingPeriod
  857. );
  858. ensure!(
  859. election_parameters.announcing_period
  860. <= T::BlockNumber::from(ELECTION_PARAMETERS_ANNOUNCING_PERIOD_MAX_VALUE),
  861. Error::InvalidCouncilElectionParameterAnnouncingPeriod
  862. );
  863. ensure!(
  864. election_parameters.min_council_stake
  865. >= <BalanceOfGovernanceCurrency<T>>::from(
  866. ELECTION_PARAMETERS_MIN_COUNCIL_STAKE_MIN_VALUE
  867. ),
  868. Error::InvalidCouncilElectionParameterMinCouncilStake
  869. );
  870. ensure!(
  871. election_parameters.min_council_stake
  872. <= <BalanceOfGovernanceCurrency<T>>::from(
  873. ELECTION_PARAMETERS_MIN_COUNCIL_STAKE_MAX_VALUE
  874. ),
  875. Error::InvalidCouncilElectionParameterMinCouncilStake
  876. );
  877. Ok(())
  878. }
  879. /// Sets default config values for the proposals.
  880. /// Should be called on the migration to the new runtime version.
  881. pub fn set_default_config_values() {
  882. let p = ProposalsConfigParameters::default();
  883. <SetValidatorCountProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  884. p.set_validator_count_proposal_voting_period,
  885. ));
  886. <SetValidatorCountProposalGracePeriod<T>>::put(T::BlockNumber::from(
  887. p.set_validator_count_proposal_grace_period,
  888. ));
  889. <RuntimeUpgradeProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  890. p.runtime_upgrade_proposal_voting_period,
  891. ));
  892. <RuntimeUpgradeProposalGracePeriod<T>>::put(T::BlockNumber::from(
  893. p.runtime_upgrade_proposal_grace_period,
  894. ));
  895. <TextProposalVotingPeriod<T>>::put(T::BlockNumber::from(p.text_proposal_voting_period));
  896. <TextProposalGracePeriod<T>>::put(T::BlockNumber::from(p.text_proposal_grace_period));
  897. <SetElectionParametersProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  898. p.set_election_parameters_proposal_voting_period,
  899. ));
  900. <SetElectionParametersProposalGracePeriod<T>>::put(T::BlockNumber::from(
  901. p.set_election_parameters_proposal_grace_period,
  902. ));
  903. <SetContentWorkingGroupMintCapacityProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  904. p.set_content_working_group_mint_capacity_proposal_voting_period,
  905. ));
  906. <SetContentWorkingGroupMintCapacityProposalGracePeriod<T>>::put(T::BlockNumber::from(
  907. p.set_content_working_group_mint_capacity_proposal_grace_period,
  908. ));
  909. <SetLeadProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  910. p.set_lead_proposal_voting_period,
  911. ));
  912. <SetLeadProposalGracePeriod<T>>::put(T::BlockNumber::from(
  913. p.set_lead_proposal_grace_period,
  914. ));
  915. <SpendingProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  916. p.spending_proposal_voting_period,
  917. ));
  918. <SpendingProposalGracePeriod<T>>::put(T::BlockNumber::from(
  919. p.spending_proposal_grace_period,
  920. ));
  921. <EvictStorageProviderProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  922. p.evict_storage_provider_proposal_voting_period,
  923. ));
  924. <EvictStorageProviderProposalGracePeriod<T>>::put(T::BlockNumber::from(
  925. p.evict_storage_provider_proposal_grace_period,
  926. ));
  927. <SetStorageRoleParametersProposalVotingPeriod<T>>::put(T::BlockNumber::from(
  928. p.set_storage_role_parameters_proposal_voting_period,
  929. ));
  930. <SetStorageRoleParametersProposalGracePeriod<T>>::put(T::BlockNumber::from(
  931. p.set_storage_role_parameters_proposal_grace_period,
  932. ));
  933. }
  934. }