1use super::*;
21use crate::Pallet as Collective;
22
23use core::mem::size_of;
24use sp_runtime::traits::Bounded;
25
26use frame_benchmarking::{
27 v1::{account, whitelisted_caller},
28 v2::*,
29};
30use frame_system::{
31 pallet_prelude::BlockNumberFor, Call as SystemCall, Pallet as System, RawOrigin as SystemOrigin,
32};
33
34const SEED: u32 = 0;
35
36const MAX_BYTES: u32 = 1_024;
37
38fn assert_last_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) {
39 frame_system::Pallet::<T>::assert_last_event(generic_event.into());
40}
41
42fn assert_has_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) {
43 frame_system::Pallet::<T>::assert_has_event(generic_event.into());
44}
45
46fn id_to_remark_data(id: u32, length: usize) -> Vec<u8> {
47 id.to_le_bytes().into_iter().cycle().take(length).collect()
48}
49
50#[instance_benchmarks(where T: Config<I>, I: 'static)]
51mod benchmarks {
52 use super::*;
53
54 #[benchmark]
55 fn set_members(
56 m: Linear<0, { T::MaxMembers::get() }>,
57 n: Linear<0, { T::MaxMembers::get() }>,
58 p: Linear<0, { T::MaxProposals::get() }>,
59 ) -> Result<(), BenchmarkError> {
60 let mut old_members = vec![];
63 for i in 0..m {
64 let old_member = account::<T::AccountId>("old member", i, SEED);
65 old_members.push(old_member);
66 }
67
68 Collective::<T, I>::set_members(
69 SystemOrigin::Root.into(),
70 old_members.clone(),
71 old_members.last().cloned(),
72 T::MaxMembers::get(),
73 )?;
74
75 if m > 0 {
77 let caller = old_members.last().unwrap().clone();
78 let threshold = m.max(2);
80 let length = 100;
82 for i in 0..p {
83 T::Consideration::ensure_successful(&caller, i);
84 let proposal: T::Proposal =
86 SystemCall::<T>::remark { remark: id_to_remark_data(i, length) }.into();
87 Collective::<T, I>::propose(
88 SystemOrigin::Signed(caller.clone()).into(),
89 threshold,
90 Box::new(proposal.clone()),
91 MAX_BYTES,
92 )?;
93 let hash = T::Hashing::hash_of(&proposal);
94 for j in 2..m - 1 {
98 let voter = &old_members[j as usize];
99 let approve = true;
100 Collective::<T, I>::vote(
101 SystemOrigin::Signed(voter.clone()).into(),
102 hash,
103 i,
104 approve,
105 )?;
106 }
107 }
108 }
109
110 let mut new_members = vec![];
113 for i in 0..n {
114 let member = account::<T::AccountId>("member", i, SEED);
115 new_members.push(member);
116 }
117 #[extrinsic_call]
118 _(
119 SystemOrigin::Root,
120 new_members.clone(),
121 new_members.last().cloned(),
122 T::MaxMembers::get(),
123 );
124
125 new_members.sort();
126 assert_eq!(Members::<T, I>::get(), new_members);
127 Ok(())
128 }
129
130 #[benchmark]
131 fn execute(
132 b: Linear<2, MAX_BYTES>,
133 m: Linear<1, { T::MaxMembers::get() }>,
134 ) -> Result<(), BenchmarkError> {
135 let bytes_in_storage = b + size_of::<u32>() as u32;
136
137 let mut members = vec![];
139 for i in 0..m - 1 {
140 let member = account::<T::AccountId>("member", i, SEED);
141 members.push(member);
142 }
143
144 let caller: T::AccountId = whitelisted_caller();
145 members.push(caller.clone());
146
147 Collective::<T, I>::set_members(
148 SystemOrigin::Root.into(),
149 members,
150 None,
151 T::MaxMembers::get(),
152 )?;
153
154 let proposal: T::Proposal =
155 SystemCall::<T>::remark { remark: id_to_remark_data(1, b as usize) }.into();
156
157 #[extrinsic_call]
158 _(SystemOrigin::Signed(caller), Box::new(proposal.clone()), bytes_in_storage);
159
160 let proposal_hash = T::Hashing::hash_of(&proposal);
161 assert_last_event::<T, I>(Event::MemberExecuted { proposal_hash, result: Ok(()) }.into());
163 Ok(())
164 }
165
166 #[benchmark]
168 fn propose_execute(
169 b: Linear<2, MAX_BYTES>,
170 m: Linear<1, { T::MaxMembers::get() }>,
171 ) -> Result<(), BenchmarkError> {
172 let bytes_in_storage = b + size_of::<u32>() as u32;
173
174 let mut members = vec![];
176 for i in 0..m - 1 {
177 let member = account::<T::AccountId>("member", i, SEED);
178 members.push(member);
179 }
180
181 let caller: T::AccountId = whitelisted_caller();
182 members.push(caller.clone());
183
184 Collective::<T, I>::set_members(
185 SystemOrigin::Root.into(),
186 members,
187 None,
188 T::MaxMembers::get(),
189 )?;
190
191 let proposal: T::Proposal =
192 SystemCall::<T>::remark { remark: id_to_remark_data(1, b as usize) }.into();
193 let threshold = 1;
194
195 #[extrinsic_call]
196 propose(
197 SystemOrigin::Signed(caller),
198 threshold,
199 Box::new(proposal.clone()),
200 bytes_in_storage,
201 );
202
203 let proposal_hash = T::Hashing::hash_of(&proposal);
204 assert_last_event::<T, I>(Event::Executed { proposal_hash, result: Ok(()) }.into());
206 Ok(())
207 }
208
209 #[benchmark]
211 fn propose_proposed(
212 b: Linear<2, MAX_BYTES>,
213 m: Linear<2, { T::MaxMembers::get() }>,
214 p: Linear<1, { T::MaxProposals::get() }>,
215 ) -> Result<(), BenchmarkError> {
216 let bytes_in_storage = b + size_of::<u32>() as u32;
217
218 let mut members = vec![];
220 for i in 0..m - 1 {
221 let member = account::<T::AccountId>("member", i, SEED);
222 members.push(member);
223 }
224 let caller: T::AccountId = whitelisted_caller();
225 members.push(caller.clone());
226 Collective::<T, I>::set_members(
227 SystemOrigin::Root.into(),
228 members,
229 None,
230 T::MaxMembers::get(),
231 )?;
232
233 let threshold = m;
234 for i in 0..p - 1 {
236 T::Consideration::ensure_successful(&caller, i);
237 let proposal: T::Proposal =
239 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
240 Collective::<T, I>::propose(
241 SystemOrigin::Signed(caller.clone()).into(),
242 threshold,
243 Box::new(proposal),
244 bytes_in_storage,
245 )?;
246 }
247
248 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
249
250 T::Consideration::ensure_successful(&caller, p);
251
252 let proposal: T::Proposal =
253 SystemCall::<T>::remark { remark: id_to_remark_data(p, b as usize) }.into();
254 #[extrinsic_call]
255 propose(
256 SystemOrigin::Signed(caller.clone()),
257 threshold,
258 Box::new(proposal.clone()),
259 bytes_in_storage,
260 );
261
262 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
264 let proposal_hash = T::Hashing::hash_of(&proposal);
265 assert_last_event::<T, I>(
266 Event::Proposed { account: caller, proposal_index: p - 1, proposal_hash, threshold }
267 .into(),
268 );
269 Ok(())
270 }
271
272 #[benchmark]
273 fn vote(m: Linear<5, { T::MaxMembers::get() }>) -> Result<(), BenchmarkError> {
275 let p = T::MaxProposals::get();
276 let b = MAX_BYTES;
277 let bytes_in_storage = b + size_of::<u32>() as u32;
278
279 let mut members = vec![];
281 let proposer: T::AccountId = account::<T::AccountId>("proposer", 0, SEED);
282 members.push(proposer.clone());
283 for i in 1..m - 1 {
284 let member = account::<T::AccountId>("member", i, SEED);
285 members.push(member);
286 }
287 let voter: T::AccountId = account::<T::AccountId>("voter", 0, SEED);
288 members.push(voter.clone());
289 Collective::<T, I>::set_members(
290 SystemOrigin::Root.into(),
291 members.clone(),
292 None,
293 T::MaxMembers::get(),
294 )?;
295
296 let threshold = m - 1;
298
299 let mut last_hash = T::Hash::default();
301 for i in 0..p {
302 T::Consideration::ensure_successful(&proposer, i);
303 let proposal: T::Proposal =
305 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
306 Collective::<T, I>::propose(
307 SystemOrigin::Signed(proposer.clone()).into(),
308 threshold,
309 Box::new(proposal.clone()),
310 bytes_in_storage,
311 )?;
312 last_hash = T::Hashing::hash_of(&proposal);
313 }
314
315 let index = p - 1;
316 for j in 0..m - 3 {
318 let voter = &members[j as usize];
319 let approve = true;
320 Collective::<T, I>::vote(
321 SystemOrigin::Signed(voter.clone()).into(),
322 last_hash,
323 index,
324 approve,
325 )?;
326 }
327 let approve = true;
329 Collective::<T, I>::vote(
330 SystemOrigin::Signed(voter.clone()).into(),
331 last_hash,
332 index,
333 approve,
334 )?;
335
336 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
337
338 let approve = false;
340
341 let voter_key = frame_system::Account::<T>::hashed_key_for(&voter);
343 frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into());
344
345 #[extrinsic_call]
346 _(SystemOrigin::Signed(voter), last_hash, index, approve);
347
348 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
350 let voting = Voting::<T, I>::get(&last_hash).ok_or("Proposal Missing")?;
351 assert_eq!(voting.ayes.len(), (m - 3) as usize);
352 assert_eq!(voting.nays.len(), 1);
353 Ok(())
354 }
355
356 #[benchmark]
358 fn close_early_disapproved(
359 m: Linear<4, { T::MaxMembers::get() }>,
360 p: Linear<1, { T::MaxProposals::get() }>,
361 ) -> Result<(), BenchmarkError> {
362 let bytes = 100;
363 let bytes_in_storage = bytes + size_of::<u32>() as u32;
364
365 let mut members = vec![];
367 let proposer = account::<T::AccountId>("proposer", 0, SEED);
368 members.push(proposer.clone());
369 for i in 1..m - 1 {
370 let member = account::<T::AccountId>("member", i, SEED);
371 members.push(member);
372 }
373 let voter = account::<T::AccountId>("voter", 0, SEED);
374 members.push(voter.clone());
375 Collective::<T, I>::set_members(
376 SystemOrigin::Root.into(),
377 members.clone(),
378 None,
379 T::MaxMembers::get(),
380 )?;
381
382 let threshold = m;
384
385 let mut last_hash = T::Hash::default();
387 for i in 0..p {
388 T::Consideration::ensure_successful(&proposer, i);
389 let proposal: T::Proposal =
391 SystemCall::<T>::remark { remark: id_to_remark_data(i, bytes as usize) }.into();
392 Collective::<T, I>::propose(
393 SystemOrigin::Signed(proposer.clone()).into(),
394 threshold,
395 Box::new(proposal.clone()),
396 bytes_in_storage,
397 )?;
398 last_hash = T::Hashing::hash_of(&proposal);
399 }
400
401 let index = p - 1;
402 for j in 0..m - 2 {
404 let voter = &members[j as usize];
405 let approve = true;
406 Collective::<T, I>::vote(
407 SystemOrigin::Signed(voter.clone()).into(),
408 last_hash,
409 index,
410 approve,
411 )?;
412 }
413 let approve = true;
415 Collective::<T, I>::vote(
416 SystemOrigin::Signed(voter.clone()).into(),
417 last_hash,
418 index,
419 approve,
420 )?;
421
422 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
423
424 let approve = false;
426 Collective::<T, I>::vote(
427 SystemOrigin::Signed(voter.clone()).into(),
428 last_hash,
429 index,
430 approve,
431 )?;
432
433 let voter_key = frame_system::Account::<T>::hashed_key_for(&voter);
435 frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into());
436
437 #[extrinsic_call]
438 close(SystemOrigin::Signed(voter), last_hash, index, Weight::MAX, bytes_in_storage);
439
440 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
442 assert_last_event::<T, I>(Event::Disapproved { proposal_hash: last_hash }.into());
443 Ok(())
444 }
445
446 #[benchmark]
448 fn close_early_approved(
449 b: Linear<2, MAX_BYTES>,
450 m: Linear<4, { T::MaxMembers::get() }>,
451 p: Linear<1, { T::MaxProposals::get() }>,
452 ) -> Result<(), BenchmarkError> {
453 let bytes_in_storage = b + size_of::<u32>() as u32;
454
455 let mut members = vec![];
457 for i in 0..m - 1 {
458 let member = account::<T::AccountId>("member", i, SEED);
459 members.push(member);
460 }
461 let caller: T::AccountId = whitelisted_caller();
462 members.push(caller.clone());
463 Collective::<T, I>::set_members(
464 SystemOrigin::Root.into(),
465 members.clone(),
466 None,
467 T::MaxMembers::get(),
468 )?;
469
470 let threshold = 2;
472
473 let mut last_hash = T::Hash::default();
475 for i in 0..p {
476 T::Consideration::ensure_successful(&caller, i);
477 let proposal: T::Proposal =
479 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
480 Collective::<T, I>::propose(
481 SystemOrigin::Signed(caller.clone()).into(),
482 threshold,
483 Box::new(proposal.clone()),
484 bytes_in_storage,
485 )?;
486 last_hash = T::Hashing::hash_of(&proposal);
487 }
488
489 Collective::<T, I>::vote(
492 SystemOrigin::Signed(caller.clone()).into(),
493 last_hash,
494 p - 1,
495 false,
496 )?;
497
498 for j in 2..m - 1 {
500 let voter = &members[j as usize];
501 let approve = false;
502 Collective::<T, I>::vote(
503 SystemOrigin::Signed(voter.clone()).into(),
504 last_hash,
505 p - 1,
506 approve,
507 )?;
508 }
509
510 Collective::<T, I>::vote(
512 SystemOrigin::Signed(members[0].clone()).into(),
513 last_hash,
514 p - 1,
515 true,
516 )?;
517
518 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
519
520 let index = p - 1;
522 let approve = true;
523 Collective::<T, I>::vote(
524 SystemOrigin::Signed(caller.clone()).into(),
525 last_hash,
526 index,
527 approve,
528 )?;
529
530 #[extrinsic_call]
531 close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage);
532
533 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
535 assert_last_event::<T, I>(
536 Event::Executed { proposal_hash: last_hash, result: Ok(()) }.into(),
537 );
538 Ok(())
539 }
540
541 #[benchmark]
543 fn close_disapproved(
544 m: Linear<4, { T::MaxMembers::get() }>,
545 p: Linear<1, { T::MaxProposals::get() }>,
546 ) -> Result<(), BenchmarkError> {
547 let bytes = 100;
548 let bytes_in_storage = bytes + size_of::<u32>() as u32;
549
550 let mut members = vec![];
552 for i in 0..m - 1 {
553 let member = account::<T::AccountId>("member", i, SEED);
554 members.push(member);
555 }
556 let caller: T::AccountId = whitelisted_caller();
557 members.push(caller.clone());
558 Collective::<T, I>::set_members(
559 SystemOrigin::Root.into(),
560 members.clone(),
561 Some(caller.clone()),
562 T::MaxMembers::get(),
563 )?;
564
565 let threshold = m - 1;
567
568 let mut last_hash = T::Hash::default();
570 for i in 0..p {
571 T::Consideration::ensure_successful(&caller, i);
572 let proposal: T::Proposal =
574 SystemCall::<T>::remark { remark: id_to_remark_data(i, bytes as usize) }.into();
575 Collective::<T, I>::propose(
576 SystemOrigin::Signed(caller.clone()).into(),
577 threshold,
578 Box::new(proposal.clone()),
579 bytes_in_storage,
580 )?;
581 last_hash = T::Hashing::hash_of(&proposal);
582 }
583
584 let index = p - 1;
585 let mut yes_votes: MemberCount = 0;
588 for j in 2..m - 1 {
589 let voter = &members[j as usize];
590 let approve = true;
591 yes_votes += 1;
592 if <<T as Config<I>>::DefaultVote as DefaultVote>::default_vote(
594 Some(false),
595 yes_votes,
596 0,
597 m,
598 ) {
599 break;
600 }
601 Collective::<T, I>::vote(
602 SystemOrigin::Signed(voter.clone()).into(),
603 last_hash,
604 index,
605 approve,
606 )?;
607 }
608
609 Collective::<T, I>::vote(
611 SystemOrigin::Signed(caller.clone()).into(),
612 last_hash,
613 index,
614 false,
615 )?;
616
617 System::<T>::set_block_number(BlockNumberFor::<T>::max_value());
618 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
619
620 #[extrinsic_call]
622 close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage);
623
624 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
625 assert_last_event::<T, I>(Event::Disapproved { proposal_hash: last_hash }.into());
626 Ok(())
627 }
628
629 #[benchmark]
631 fn close_approved(
632 b: Linear<2, MAX_BYTES>,
633 m: Linear<4, { T::MaxMembers::get() }>,
634 p: Linear<1, { T::MaxProposals::get() }>,
635 ) -> Result<(), BenchmarkError> {
636 let bytes_in_storage = b + size_of::<u32>() as u32;
637
638 let mut members = vec![];
640 for i in 0..m - 1 {
641 let member = account::<T::AccountId>("member", i, SEED);
642 members.push(member);
643 }
644 let caller: T::AccountId = whitelisted_caller();
645 members.push(caller.clone());
646 Collective::<T, I>::set_members(
647 SystemOrigin::Root.into(),
648 members.clone(),
649 Some(caller.clone()),
650 T::MaxMembers::get(),
651 )?;
652
653 let threshold = 2;
655
656 let mut last_hash = T::Hash::default();
658 for i in 0..p {
659 T::Consideration::ensure_successful(&caller, i);
660 let proposal: T::Proposal =
662 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
663 Collective::<T, I>::propose(
664 SystemOrigin::Signed(caller.clone()).into(),
665 threshold,
666 Box::new(proposal.clone()),
667 bytes_in_storage,
668 )?;
669 last_hash = T::Hashing::hash_of(&proposal);
670 }
671
672 Collective::<T, _>::vote(
674 SystemOrigin::Signed(caller.clone()).into(),
675 last_hash,
676 p - 1,
677 true, )?;
679
680 for j in 2..m - 1 {
683 let voter = &members[j as usize];
684 let approve = false;
685 Collective::<T, I>::vote(
686 SystemOrigin::Signed(voter.clone()).into(),
687 last_hash,
688 p - 1,
689 approve,
690 )?;
691 }
692
693 System::<T>::set_block_number(BlockNumberFor::<T>::max_value());
695 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
696
697 #[extrinsic_call]
699 close(SystemOrigin::Signed(caller), last_hash, p - 1, Weight::MAX, bytes_in_storage);
700
701 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
702 assert_last_event::<T, I>(
703 Event::Executed { proposal_hash: last_hash, result: Ok(()) }.into(),
704 );
705 Ok(())
706 }
707
708 #[benchmark]
709 fn disapprove_proposal(p: Linear<1, { T::MaxProposals::get() }>) -> Result<(), BenchmarkError> {
710 let m = 3;
711 let b = MAX_BYTES;
712 let bytes_in_storage = b + size_of::<u32>() as u32;
713
714 let mut members = vec![];
716 for i in 0..m - 1 {
717 let member = account::<T::AccountId>("member", i, SEED);
718 members.push(member);
719 }
720 let caller = account::<T::AccountId>("caller", 0, SEED);
721 members.push(caller.clone());
722 Collective::<T, I>::set_members(
723 SystemOrigin::Root.into(),
724 members.clone(),
725 Some(caller.clone()),
726 T::MaxMembers::get(),
727 )?;
728
729 let threshold = m - 1;
731
732 let mut last_hash = T::Hash::default();
734 for i in 0..p {
735 T::Consideration::ensure_successful(&caller, i);
736 let proposal: T::Proposal =
738 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
739 Collective::<T, I>::propose(
740 SystemOrigin::Signed(caller.clone()).into(),
741 threshold,
742 Box::new(proposal.clone()),
743 bytes_in_storage,
744 )?;
745 last_hash = T::Hashing::hash_of(&proposal);
746 }
747
748 System::<T>::set_block_number(BlockNumberFor::<T>::max_value());
749 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
750
751 let origin =
752 T::DisapproveOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
753
754 #[extrinsic_call]
755 _(origin as <T as frame_system::Config>::RuntimeOrigin, last_hash);
756
757 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
758 assert_last_event::<T, I>(Event::Disapproved { proposal_hash: last_hash }.into());
759 Ok(())
760 }
761
762 #[benchmark]
764 fn kill(
765 d: Linear<0, 1>,
766 p: Linear<1, { T::MaxProposals::get() }>,
767 ) -> Result<(), BenchmarkError> {
768 let m = 3;
769 let b = MAX_BYTES;
770 let bytes_in_storage = b + size_of::<u32>() as u32;
771
772 let mut members = vec![];
774 for i in 0..m - 1 {
775 let member = account::<T::AccountId>("member", i, SEED);
776 members.push(member);
777 }
778 let caller = account::<T::AccountId>("caller", 0, SEED);
779 members.push(caller.clone());
780 Collective::<T, I>::set_members(
781 SystemOrigin::Root.into(),
782 members.clone(),
783 Some(caller.clone()),
784 T::MaxMembers::get(),
785 )?;
786
787 let threshold = m - 1;
789
790 let mut last_hash = T::Hash::default();
792 for i in 0..p {
793 T::Consideration::ensure_successful(&caller, i);
794
795 let proposal: T::Proposal =
797 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
798 Collective::<T, I>::propose(
799 SystemOrigin::Signed(caller.clone()).into(),
800 threshold,
801 Box::new(proposal.clone()),
802 bytes_in_storage,
803 )?;
804 last_hash = T::Hashing::hash_of(&proposal);
805 }
806
807 System::<T>::set_block_number(BlockNumberFor::<T>::max_value());
808 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
809
810 if d == 0 {
811 CostOf::<T, I>::remove(last_hash);
812 }
813 let cost_present = CostOf::<T, I>::get(last_hash).is_some();
814
815 let origin =
816 T::KillOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
817
818 #[extrinsic_call]
819 _(origin as <T as frame_system::Config>::RuntimeOrigin, last_hash);
820
821 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
822 assert_last_event::<T, I>(Event::Killed { proposal_hash: last_hash }.into());
823 if cost_present {
824 assert_has_event::<T, I>(
825 Event::ProposalCostBurned { proposal_hash: last_hash, who: caller }.into(),
826 );
827 }
828 Ok(())
829 }
830
831 #[benchmark]
832 fn release_proposal_cost() -> Result<(), BenchmarkError> {
833 let m = 3;
834 let p = T::MaxProposals::get();
835 let b = MAX_BYTES;
836 let bytes_in_storage = b + size_of::<u32>() as u32;
837
838 let mut members = vec![];
840 for i in 0..m - 1 {
841 let member = account::<T::AccountId>("member", i, SEED);
842 members.push(member);
843 }
844 let caller = account::<T::AccountId>("caller", 0, SEED);
845 members.push(caller.clone());
846 Collective::<T, I>::set_members(
847 SystemOrigin::Root.into(),
848 members.clone(),
849 Some(caller.clone()),
850 T::MaxMembers::get(),
851 )?;
852
853 let threshold = 2;
855 let mut last_hash = T::Hash::default();
856 for i in 0..p {
857 T::Consideration::ensure_successful(&caller, i);
858
859 let proposal: T::Proposal =
861 SystemCall::<T>::remark { remark: id_to_remark_data(i, b as usize) }.into();
862 Collective::<T, I>::propose(
863 SystemOrigin::Signed(caller.clone()).into(),
864 threshold,
865 Box::new(proposal.clone()),
866 bytes_in_storage,
867 )?;
868 last_hash = T::Hashing::hash_of(&proposal);
869 }
870
871 System::<T>::set_block_number(BlockNumberFor::<T>::max_value());
872 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
873
874 assert_eq!(Proposals::<T, I>::get().len(), p as usize);
875 let _ = Collective::<T, I>::remove_proposal(last_hash);
876 assert_eq!(Proposals::<T, I>::get().len(), (p - 1) as usize);
877
878 let cost_present = CostOf::<T, I>::get(last_hash).is_some();
879
880 #[extrinsic_call]
881 _(SystemOrigin::Signed(caller.clone()), last_hash);
882
883 assert_eq!(CostOf::<T, I>::get(last_hash), None);
884 if cost_present {
885 assert_last_event::<T, I>(
886 Event::ProposalCostReleased { proposal_hash: last_hash, who: caller }.into(),
887 );
888 }
889 Ok(())
890 }
891
892 impl_benchmark_test_suite!(
893 Collective,
894 crate::tests::ExtBuilder::default().build(),
895 crate::tests::Test
896 );
897}