Skip to content
This repository has been 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 all 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 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::<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