Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
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
1 change: 1 addition & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ impl pallet_democracy::Config for Runtime {
type EnactmentPeriod = EnactmentPeriod;
type LaunchPeriod = LaunchPeriod;
type VotingPeriod = VotingPeriod;
type VoteLockingPeriod = EnactmentPeriod; // Same as EnactmentPeriod
type MinimumDeposit = MinimumDeposit;
/// A straight majority of the council can decide what their next motion is.
type ExternalOrigin =
Expand Down
14 changes: 10 additions & 4 deletions frame/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,7 @@ pub mod pallet {
type Currency: ReservableCurrency<Self::AccountId>
+ LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;

/// The minimum period of locking and the period between a proposal being approved and
/// enacted.
/// The period between a proposal being approved and enacted.
///
/// It should generally be a little more than the unstake period to ensure that
/// voting stakers have an opportunity to remove themselves from the system in the case
Expand All @@ -280,6 +279,13 @@ pub mod pallet {
#[pallet::constant]
type VotingPeriod: Get<Self::BlockNumber>;

/// The minimum period of vote locking.
///
/// It should be no shorter than enactment period to ensure that in the case of an approval,
/// those successful voters are locked into the consequences that their votes entail.
#[pallet::constant]
type VoteLockingPeriod: Get<Self::BlockNumber>;

/// The minimum amount to be used as a deposit for a public referendum proposal.
#[pallet::constant]
type MinimumDeposit: Get<BalanceOf<Self>>;
Expand Down Expand Up @@ -1429,7 +1435,7 @@ impl<T: Config> Pallet<T> {
},
Some(ReferendumInfo::Finished { end, approved }) => {
if let Some((lock_periods, balance)) = votes[i].1.locked_if(approved) {
let unlock_at = end + T::EnactmentPeriod::get() * lock_periods.into();
let unlock_at = end + T::VoteLockingPeriod::get() * lock_periods.into();
let now = frame_system::Pallet::<T>::block_number();
if now < unlock_at {
ensure!(
Expand Down Expand Up @@ -1553,7 +1559,7 @@ impl<T: Config> Pallet<T> {
Self::reduce_upstream_delegation(&target, conviction.votes(balance));
let now = frame_system::Pallet::<T>::block_number();
let lock_periods = conviction.lock_periods().into();
prior.accumulate(now + T::EnactmentPeriod::get() * lock_periods, balance);
prior.accumulate(now + T::VoteLockingPeriod::get() * lock_periods, balance);
voting.set_common(delegations, prior);

Ok(votes)
Expand Down
2 changes: 2 additions & 0 deletions frame/democracy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ parameter_types! {
pub const FastTrackVotingPeriod: u64 = 2;
pub const MinimumDeposit: u64 = 1;
pub const EnactmentPeriod: u64 = 2;
pub const VoteLockingPeriod: u64 = 3;
pub const CooloffPeriod: u64 = 2;
pub const MaxVotes: u32 = 100;
pub const MaxProposals: u32 = MAX_PROPOSALS;
Expand Down Expand Up @@ -170,6 +171,7 @@ impl Config for Test {
type EnactmentPeriod = EnactmentPeriod;
type LaunchPeriod = LaunchPeriod;
type VotingPeriod = VotingPeriod;
type VoteLockingPeriod = VoteLockingPeriod;
type FastTrackVotingPeriod = FastTrackVotingPeriod;
type MinimumDeposit = MinimumDeposit;
type ExternalOrigin = EnsureSignedBy<Two, u64>;
Expand Down
88 changes: 44 additions & 44 deletions frame/democracy/src/tests/lock_voting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,37 +85,37 @@ fn lock_voting_should_work() {
assert_eq!(Balances::locks(5), vec![]);
assert_eq!(Balances::free_balance(42), 2);

fast_forward_to(5);
fast_forward_to(7);
// No change yet...
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 4, r),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(1), 4));
assert_eq!(Balances::locks(4), vec![the_lock(40)]);
fast_forward_to(6);
fast_forward_to(8);
// 4 should now be able to reap and unlock
assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 4, r));
assert_ok!(Democracy::unlock(Origin::signed(1), 4));
assert_eq!(Balances::locks(4), vec![]);

fast_forward_to(9);
fast_forward_to(13);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 3, r),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(1), 3));
assert_eq!(Balances::locks(3), vec![the_lock(30)]);
fast_forward_to(10);
fast_forward_to(14);
assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 3, r));
assert_ok!(Democracy::unlock(Origin::signed(1), 3));
assert_eq!(Balances::locks(3), vec![]);

// 2 doesn't need to reap_vote here because it was already done before.
fast_forward_to(17);
fast_forward_to(25);
assert_ok!(Democracy::unlock(Origin::signed(1), 2));
assert_eq!(Balances::locks(2), vec![the_lock(20)]);
fast_forward_to(18);
fast_forward_to(26);
assert_ok!(Democracy::unlock(Origin::signed(1), 2));
assert_eq!(Balances::locks(2), vec![]);
});
Expand Down Expand Up @@ -201,40 +201,40 @@ fn setup_three_referenda() -> (u32, u32, u32) {
fn prior_lockvotes_should_be_enforced() {
new_test_ext().execute_with(|| {
let r = setup_three_referenda();
// r.0 locked 10 until #18.
// r.1 locked 20 until #10.
// r.2 locked 50 until #6.
// r.0 locked 10 until 2 + 8 * 3 = #26
// r.1 locked 20 until 2 + 4 * 3 = #14
// r.2 locked 50 until 2 + 2 * 3 = #8

fast_forward_to(5);
fast_forward_to(7);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 5, r.2),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(50)]);
fast_forward_to(6);
fast_forward_to(8);
assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 5, r.2));
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(20)]);
fast_forward_to(9);
fast_forward_to(13);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 5, r.1),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(20)]);
fast_forward_to(10);
fast_forward_to(14);
assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 5, r.1));
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(10)]);
fast_forward_to(17);
fast_forward_to(25);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 5, r.0),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(10)]);
fast_forward_to(18);
fast_forward_to(26);
assert_ok!(Democracy::remove_other_vote(Origin::signed(1), 5, r.0));
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![]);
Expand All @@ -245,31 +245,31 @@ fn prior_lockvotes_should_be_enforced() {
fn single_consolidation_of_lockvotes_should_work_as_before() {
new_test_ext().execute_with(|| {
let r = setup_three_referenda();
// r.0 locked 10 until #18.
// r.1 locked 20 until #10.
// r.2 locked 50 until #6.
// r.0 locked 10 until 2 + 8 * 3 = #26
// r.1 locked 20 until 2 + 4 * 3 = #14
// r.2 locked 50 until 2 + 2 * 3 = #8

fast_forward_to(5);
fast_forward_to(7);
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.2));
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(50)]);
fast_forward_to(6);
fast_forward_to(8);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(20)]);

fast_forward_to(9);
fast_forward_to(13);
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.1));
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(20)]);
fast_forward_to(10);
fast_forward_to(14);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(10)]);

fast_forward_to(17);
fast_forward_to(25);
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.0));
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(10)]);
fast_forward_to(18);
fast_forward_to(26);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![]);
});
Expand All @@ -279,23 +279,23 @@ fn single_consolidation_of_lockvotes_should_work_as_before() {
fn multi_consolidation_of_lockvotes_should_be_conservative() {
new_test_ext().execute_with(|| {
let r = setup_three_referenda();
// r.0 locked 10 until #18.
// r.1 locked 20 until #10.
// r.2 locked 50 until #6.
// r.0 locked 10 until 2 + 8 * 3 = #26
// r.1 locked 20 until 2 + 4 * 3 = #14
// r.2 locked 50 until 2 + 2 * 3 = #8

assert_ok!(Democracy::remove_vote(Origin::signed(5), r.2));
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.1));
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.0));

fast_forward_to(6);
fast_forward_to(8);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 20);

fast_forward_to(10);
fast_forward_to(14);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 10);

fast_forward_to(18);
fast_forward_to(26);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![]);
});
Expand All @@ -314,28 +314,28 @@ fn locks_should_persist_from_voting_to_delegation() {
assert_ok!(Democracy::vote(Origin::signed(5), r, aye(4, 10)));
fast_forward_to(2);
assert_ok!(Democracy::remove_vote(Origin::signed(5), r));
// locked 10 until #18.
// locked 10 until #26.

assert_ok!(Democracy::delegate(Origin::signed(5), 1, Conviction::Locked3x, 20));
// locked 20.
assert!(Balances::locks(5)[0].amount == 20);

assert_ok!(Democracy::undelegate(Origin::signed(5)));
// locked 20 until #10
// locked 20 until #14

fast_forward_to(9);
fast_forward_to(13);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount == 20);

fast_forward_to(10);
fast_forward_to(14);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 10);

fast_forward_to(17);
fast_forward_to(25);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 10);

fast_forward_to(18);
fast_forward_to(26);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![]);
});
Expand All @@ -347,30 +347,30 @@ fn locks_should_persist_from_delegation_to_voting() {
System::set_block_number(0);
assert_ok!(Democracy::delegate(Origin::signed(5), 1, Conviction::Locked5x, 5));
assert_ok!(Democracy::undelegate(Origin::signed(5)));
// locked 5 until #32
// locked 5 until 16 * 3 = #48

let r = setup_three_referenda();
// r.0 locked 10 until #18.
// r.1 locked 20 until #10.
// r.2 locked 50 until #6.
// r.0 locked 10 until 2 + 8 * 3 = #26
// r.1 locked 20 until 2 + 4 * 3 = #14
// r.2 locked 50 until 2 + 2 * 3 = #8

assert_ok!(Democracy::remove_vote(Origin::signed(5), r.2));
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.1));
assert_ok!(Democracy::remove_vote(Origin::signed(5), r.0));

fast_forward_to(6);
fast_forward_to(8);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 20);

fast_forward_to(10);
fast_forward_to(14);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 10);

fast_forward_to(18);
fast_forward_to(26);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert!(Balances::locks(5)[0].amount >= 5);

fast_forward_to(32);
fast_forward_to(48);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![]);
});
Expand Down