Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Democracy.fast_track not allowed with zero voting period #11666

Merged
merged 7 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions frame/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ pub mod pallet {
MaxVotesReached,
/// Maximum number of proposals reached.
TooManyProposals,
/// Voting period too low
VotingPeriodLow,
}

#[pallet::hooks]
Expand Down Expand Up @@ -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.
///
Expand Down Expand Up @@ -830,7 +833,7 @@ pub mod pallet {
T::InstantOrigin::ensure_origin(ensure_instant)?;
ensure!(T::InstantAllowed::get(), Error::<T>::InstantNotAllowed);
}

ensure!(voting_period > T::BlockNumber::zero(), Error::<T>::VotingPeriodLow);
let (e_proposal_hash, threshold) =
<NextExternal<T>>::get().ok_or(Error::<T>::ProposalMissing)?;
ensure!(
Expand Down
58 changes: 58 additions & 0 deletions frame/democracy/src/tests/fast_tracking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ fn instant_referendum_works() {
Error::<Test>::InstantNotAllowed
);
INSTANT_ALLOWED.with(|v| *v.borrow_mut() = true);
assert_noop!(
Democracy::fast_track(Origin::signed(6), h, 0, 0),
Error::<Test>::VotingPeriodLow
);
assert_ok!(Democracy::fast_track(Origin::signed(6), h, 1, 0));
assert_eq!(
Democracy::referendum_status(0),
Expand All @@ -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 affect 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 backed with the start of the next block
next_block();

// assert no active referendums
assert_noop!(Democracy::referendum_status(0), Error::<Test>::ReferendumInvalid);
// the only referendum in the storage is finished and not approved
assert_eq!(
ReferendumInfoOf::<Test>::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(|| {
Expand Down