diff --git a/substrate/frame/democracy/src/lib.rs b/substrate/frame/democracy/src/lib.rs index 11e42db..de1bad3 100644 --- a/substrate/frame/democracy/src/lib.rs +++ b/substrate/frame/democracy/src/lib.rs @@ -780,6 +780,12 @@ pub mod pallet { recipient: T::AccountId, deposit: BalanceOf, }, + /// Referendum threshold was updated. + ReferendumThresholdUpdated { + ref_index: ReferendumIndex, + old_threshold: VoteThreshold, + new_threshold: VoteThreshold, + }, } #[pallet::error] @@ -1610,6 +1616,37 @@ pub mod pallet { } .into()) } + + /// Sets new threshold for the ongoing referendum. + #[pallet::weight(T::DbWeight::get().writes(1))] + pub fn set_referendum_threshold( + origin: OriginFor, + ref_index: ReferendumIndex, + new_threshold: VoteThreshold, + ) -> DispatchResult { + ensure_root(origin)?; + + ReferendumInfoOf::::try_mutate(ref_index, |info_opt| { + let status = info_opt + .as_mut() + .and_then(|info| match info { + ReferendumInfo::Ongoing(status) => Some(status), + _ => None, + }) + .ok_or(Error::::ReferendumInvalid)?; + + let old_threshold = status.threshold; + status.threshold = new_threshold; + + Self::deposit_event(Event::::ReferendumThresholdUpdated { + ref_index, + old_threshold, + new_threshold, + }); + + Ok(()) + }) + } } } diff --git a/substrate/frame/democracy/src/tests/voting.rs b/substrate/frame/democracy/src/tests/voting.rs index 5995fba..f933850 100644 --- a/substrate/frame/democracy/src/tests/voting.rs +++ b/substrate/frame/democracy/src/tests/voting.rs @@ -17,6 +17,8 @@ //! The tests for normal voting functionality. +use frame_system::RawOrigin; + use super::*; #[test] @@ -155,6 +157,50 @@ fn controversial_voting_should_work() { }); } +#[test] +fn set_threshold_should_work() { + new_test_ext().execute_with(|| { + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityAgainst, + 0, + ); + + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + assert_ok!(Democracy::vote(Origin::signed(2), r, nay(2))); + assert_ok!(Democracy::vote(Origin::signed(3), r, nay(3))); + assert_ok!(Democracy::vote(Origin::signed(4), r, aye(4))); + + assert_eq!( + tally(r), + Tally { + ayes: 5, + nays: 5, + turnout: 100 + } + ); + assert_ok!(Democracy::set_referendum_threshold( + RawOrigin::Root.into(), + r, + VoteThreshold::SuperMajorityApprove + )); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(42), 0); + assert_noop!( + Democracy::set_referendum_threshold( + RawOrigin::Root.into(), + r, + VoteThreshold::SuperMajorityApprove + ), + Error::::ReferendumInvalid + ); + }); +} + #[test] fn controversial_low_turnout_voting_should_work() { new_test_ext().execute_with(|| {