diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 4e11c207657f0..443b8579116d0 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -600,6 +600,8 @@ pub mod pallet { MaxVotesReached, /// Maximum number of proposals reached. TooManyProposals, + /// Voting period too low + VotingPeriodLow, } #[pallet::hooks] @@ -800,8 +802,9 @@ pub mod pallet { /// The dispatch of this call must be `FastTrackOrigin`. /// /// - `proposal_hash`: The hash of the current external proposal. - /// - `voting_period`: The period that is allowed for voting on this proposal. Increased to - /// `FastTrackVotingPeriod` if too low. + /// - `voting_period`: The period that is allowed for voting on this proposal. + /// Must be always greater than zero. + /// For `FastTrackOrigin` must be equal or greater than `FastTrackVotingPeriod`. /// - `delay`: The number of block after voting has ended in approval and this should be /// enacted. This doesn't have a minimum amount. /// @@ -830,7 +833,7 @@ pub mod pallet { T::InstantOrigin::ensure_origin(ensure_instant)?; ensure!(T::InstantAllowed::get(), Error::::InstantNotAllowed); } - + ensure!(voting_period > T::BlockNumber::zero(), Error::::VotingPeriodLow); let (e_proposal_hash, threshold) = >::get().ok_or(Error::::ProposalMissing)?; ensure!( diff --git a/frame/democracy/src/tests/fast_tracking.rs b/frame/democracy/src/tests/fast_tracking.rs index 7a15bb8de4dac..caf83c6d46120 100644 --- a/frame/democracy/src/tests/fast_tracking.rs +++ b/frame/democracy/src/tests/fast_tracking.rs @@ -67,6 +67,10 @@ fn instant_referendum_works() { Error::::InstantNotAllowed ); INSTANT_ALLOWED.with(|v| *v.borrow_mut() = true); + assert_noop!( + Democracy::fast_track(Origin::signed(6), h, 0, 0), + Error::::VotingPeriodLow + ); assert_ok!(Democracy::fast_track(Origin::signed(6), h, 1, 0)); assert_eq!( Democracy::referendum_status(0), @@ -81,6 +85,60 @@ fn instant_referendum_works() { }); } +#[test] +fn instant_next_block_referendum_backed() { + new_test_ext().execute_with(|| { + // arrange + let start_block_number = 10; + let majority_origin_id = 3; + let instant_origin_id = 6; + let voting_period = 1; + let proposal_hash = set_balance_proposal_hash_and_note(2); + let delay = 2; // has no effect on test + + // init + System::set_block_number(start_block_number); + InstantAllowed::set(true); + + // propose with majority origin + assert_ok!(Democracy::external_propose_majority( + Origin::signed(majority_origin_id), + proposal_hash + )); + + // fast track with instant origin and voting period pointing to the next block + assert_ok!(Democracy::fast_track( + Origin::signed(instant_origin_id), + proposal_hash, + voting_period, + delay + )); + + // fetch the status of the only referendum at index 0 + assert_eq!( + Democracy::referendum_status(0), + Ok(ReferendumStatus { + end: start_block_number + voting_period, + proposal_hash, + threshold: VoteThreshold::SimpleMajority, + delay, + tally: Tally { ayes: 0, nays: 0, turnout: 0 }, + }) + ); + + // referendum expected to be baked with the start of the next block + next_block(); + + // assert no active referendums + assert_noop!(Democracy::referendum_status(0), Error::::ReferendumInvalid); + // the only referendum in the storage is finished and not approved + assert_eq!( + ReferendumInfoOf::::get(0).unwrap(), + ReferendumInfo::Finished { approved: false, end: start_block_number + voting_period } + ); + }); +} + #[test] fn fast_track_referendum_fails_when_no_simple_majority() { new_test_ext().execute_with(|| {