From 70b4bf60df80213f4ef4a7dbef888f7457c263c7 Mon Sep 17 00:00:00 2001 From: Michal Lustyk <MichalLustykNeti> Date: Mon, 2 Oct 2023 15:50:19 +0200 Subject: [PATCH 1/2] BLOCKCHAIN-176 Added proposal fee and updated tests BLOCKCHAIN-176 Added proposal fee and updated tests BLOCKCHAIN-176 Added proposal fee and tests BLOCKCHAIN-176 Added proposal fee and updated tests Update bin/node/runtime/src/lib.rs Co-authored-by: kacperzuk-neti <117277751+kacperzuk-neti@users.noreply.github.com> BLOCKCHAIN-176 added test that ensure proposal creation fee is valid BLOCKCHAIN-176 added check of total account balance BLOCKCHAIN-176 added check of total account balance --- bin/node/runtime/src/lib.rs | 4 ++ frame/democracy/src/lib.rs | 11 ++++- frame/democracy/src/tests.rs | 2 + frame/democracy/src/tests/delegation.rs | 26 +++++----- frame/democracy/src/tests/public_proposals.rs | 47 ++++++++++++------- frame/democracy/src/tests/voting.rs | 5 +- 6 files changed, 62 insertions(+), 33 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index c62c871eba..9af3d6db0e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -806,6 +806,7 @@ parameter_types! { pub const MinimumDeposit: Balance = 10 * GRAINS_IN_LLM; pub const CooloffPeriod: BlockNumber = 7 * DAYS; pub const MaxProposals: u32 = 100; + pub const ProposalFeeAmount: Balance = 100 * DOLLARS; } impl pallet_democracy::Config for Runtime { @@ -870,6 +871,9 @@ impl pallet_democracy::Config for Runtime { type MaxDeposits = ConstU32<100>; type MaxBlacklisted = ConstU32<100>; type DelegateeFilter = ContainsMember<Runtime, CouncilCollective>; + + type ProposalFee = Treasury; + type ProposalFeeAmount = ProposalFeeAmount; } parameter_types! { diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 92255cd958..2b56b4d19f 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -166,7 +166,7 @@ use frame_support::{ schedule::{v3::Named as ScheduleNamed, DispatchTime}, Bounded, Currency, Get, Hash as PreimageHash, LockIdentifier, LockableCurrency, QueryPreimage, ReservableCurrency, StorePreimage, - Contains, + Contains, OnUnbalanced }, pallet_prelude::{MaxEncodedLen, TypeInfo}, BoundedVec, @@ -322,6 +322,9 @@ pub mod pallet { #[pallet::constant] type MaxAdditionalFields: Get<u32>; + #[pallet::constant] + type ProposalFeeAmount: Get<BalanceOf<Self>>; + /// Origin from which the next tabled referendum may be forced; this allows for the tabling /// of a negative-turnout-bias (default-carries) referendum. type ExternalDefaultOrigin: EnsureOrigin<Self::RuntimeOrigin>; @@ -360,6 +363,8 @@ pub mod pallet { type LLM: LLM<Self::AccountId, BalanceOf<Self>>; type DelegateeFilter: Contains<Self::AccountId>; type LLInitializer: LLInitializer<Self::AccountId>; + + type ProposalFee: OnUnbalanced<<<Self as Config>::Currency as Currency<<Self as frame_system::Config>::AccountId>>::NegativeImbalance>; } /// The number of (public) proposals that have been made so far. @@ -1237,7 +1242,9 @@ impl<T: Config> Pallet<T> { fn do_propose(who: T::AccountId, proposal: BoundedCallOf<T>, value: BalanceOf<T>, dispatch_origin: DispatchOrigin) -> DispatchResult { T::Citizenship::ensure_politics_allowed(&who)?; - ensure!(value >= T::MinimumDeposit::get(), Error::<T>::ValueLow); + ensure!(T::Currency::can_slash(&who, T::ProposalFeeAmount::get()), Error::<T>::InsufficientFunds); + + T::ProposalFee::on_unbalanced(T::Currency::slash(&who, T::ProposalFeeAmount::get()).0); let index = Self::public_prop_count(); let real_prop_count = PublicProps::<T>::decode_len().unwrap_or(0) as u32; diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 0e901162a5..b0ab7b9c99 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -326,6 +326,8 @@ impl Config for Test { type LLM = LLM; type LLInitializer = LiberlandInitializer; type DelegateeFilter = Everything; + type ProposalFee = (); + type ProposalFeeAmount = ConstU64<10>; } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/frame/democracy/src/tests/delegation.rs b/frame/democracy/src/tests/delegation.rs index 2e71ff4623..b320648587 100644 --- a/frame/democracy/src/tests/delegation.rs +++ b/frame/democracy/src/tests/delegation.rs @@ -36,19 +36,19 @@ fn single_proposal_should_work_with_delegation() { assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 20)); let r = 0; assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); - assert_eq!(tally(r), Tally { ayes: 30, nays: 0, turnout: 30, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); // Delegate a second vote. assert_ok!(Democracy::delegate(RuntimeOrigin::signed(3), 1, Conviction::None, 30)); - assert_eq!(tally(r), Tally { ayes: 60, nays: 0, turnout: 60, aye_voters: 30000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 50, nays: 0, turnout: 50, aye_voters: 30000, nay_voters: 0 }); // Reduce first vote. assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 10)); - assert_eq!(tally(r), Tally { ayes: 50, nays: 0, turnout: 50, aye_voters: 30000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 40, nays: 0, turnout: 40, aye_voters: 30000, nay_voters: 0 }); // Second vote delegates to first; we don't do tiered delegation, so it doesn't get used. assert_ok!(Democracy::delegate(RuntimeOrigin::signed(3), 2, Conviction::None, 30)); - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 20000, nay_voters: 0 }); // Main voter cancels their vote assert_ok!(Democracy::remove_vote(RuntimeOrigin::signed(1), r)); @@ -60,7 +60,7 @@ fn single_proposal_should_work_with_delegation() { // Main voter reinstates their vote assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 20000, nay_voters: 0 }); }); } @@ -94,7 +94,7 @@ fn cyclic_delegation_should_unwind() { assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, nay(1))); // Delegated vote is counted. - assert_eq!(tally(r), Tally { ayes: 30, nays: 30, turnout: 60, aye_voters: 10000, nay_voters: 20000 }); + assert_eq!(tally(r), Tally { ayes: 30, nays: 20, turnout: 50, aye_voters: 10000, nay_voters: 20000 }); }); } @@ -111,13 +111,13 @@ fn single_proposal_should_work_with_vote_and_delegation() { let r = 0; assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); assert_ok!(Democracy::vote(RuntimeOrigin::signed(2), r, nay(2))); - assert_eq!(tally(r), Tally { ayes: 10, nays: 20, turnout: 30, aye_voters: 10000, nay_voters: 10000 }); + assert_eq!(tally(r), Tally { ayes: 0, nays: 20, turnout: 20, aye_voters: 10000, nay_voters: 10000 }); // Delegate vote. assert_ok!(Democracy::remove_vote(RuntimeOrigin::signed(2), r)); assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 20)); // Delegated vote replaces the explicit vote. - assert_eq!(tally(r), Tally { ayes: 30, nays: 0, turnout: 30 , aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20 , aye_voters: 20000, nay_voters: 0 }); }); } @@ -137,7 +137,7 @@ fn single_proposal_should_work_with_undelegation() { assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); // Delegated vote is not counted. - assert_eq!(tally(r), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 10000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0, aye_voters: 10000, nay_voters: 0 }); }); } @@ -149,11 +149,11 @@ fn single_proposal_should_work_with_delegation_and_vote() { // Delegate, undelegate and vote. assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 20)); - assert_eq!(tally(r), Tally { ayes: 30, nays: 0, turnout: 30, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); assert_ok!(Democracy::undelegate(RuntimeOrigin::signed(2))); assert_ok!(Democracy::vote(RuntimeOrigin::signed(2), r, aye(2))); // Delegated vote is not counted. - assert_eq!(tally(r), Tally { ayes: 30, nays: 0, turnout: 30, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); }); } @@ -166,7 +166,7 @@ fn conviction_should_be_honored_in_delegation() { assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::Locked6x, 20)); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); // Delegated vote is huge. - assert_eq!(tally(r), Tally { ayes: 30, nays: 0, turnout: 30, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); }); } @@ -195,7 +195,7 @@ fn redelegation_keeps_lock() { assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::Locked6x, 20)); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); // Delegated vote is huge. - assert_eq!(tally(r), Tally { ayes: 30, nays: 0, turnout: 30, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); let mut prior_lock = vote::PriorLock::default(); diff --git a/frame/democracy/src/tests/public_proposals.rs b/frame/democracy/src/tests/public_proposals.rs index 1e70a82ffa..b68cd44b39 100644 --- a/frame/democracy/src/tests/public_proposals.rs +++ b/frame/democracy/src/tests/public_proposals.rs @@ -26,9 +26,9 @@ use super::*; #[test] fn backing_for_should_work() { new_test_ext().execute_with(|| { - assert_ok!(propose_set_balance(1, 2, 2)); - assert_ok!(propose_set_balance(1, 4, 4)); - assert_ok!(propose_set_balance(1, 3, 3)); + assert_ok!(propose_set_balance(3, 2, 2)); + assert_ok!(propose_set_balance(3, 4, 4)); + assert_ok!(propose_set_balance(3, 3, 3)); assert_eq!(Democracy::backing_for(0), Some(2)); assert_eq!(Democracy::backing_for(1), Some(4)); assert_eq!(Democracy::backing_for(2), Some(3)); @@ -45,7 +45,7 @@ fn deposit_for_proposals_should_be_taken() { assert_ok!(Democracy::second(RuntimeOrigin::signed(5), 0)); // liberland specific - free balance shouldn't change, seconds shouldn't // lock anything - assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(1), 0); assert_eq!(Balances::free_balance(2), 20); assert_eq!(Balances::free_balance(5), 50); }); @@ -60,16 +60,31 @@ fn deposit_for_proposals_should_be_returned() { assert_ok!(Democracy::second(RuntimeOrigin::signed(5), 0)); assert_ok!(Democracy::second(RuntimeOrigin::signed(5), 0)); fast_forward_to(3); - assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(1), 0); assert_eq!(Balances::free_balance(2), 20); assert_eq!(Balances::free_balance(5), 50); }); } #[test] -fn proposal_with_deposit_below_minimum_should_not_work() { +fn proposal_with_funds_below_minimum_should_not_work() { new_test_ext().execute_with(|| { - assert_noop!(propose_set_balance(1, 2, 0), Error::<Test>::ValueLow); + assert_ok!(propose_set_balance(1, 2, 5)); + + assert_noop!(propose_set_balance(1, 2, 0), Error::<Test>::InsufficientFunds); + }); +} + +#[test] +fn creating_proposal_takes_fee() { + new_test_ext().execute_with(|| { + System::set_block_number(0); + assert_eq!(Balances::total_balance(&1), 10); + + assert_ok!(propose_set_balance(1, 2, 5)); + + assert_eq!(Balances::total_balance(&1), 0); + }); } @@ -94,12 +109,12 @@ fn poor_seconder_should_not_work() { #[test] fn cancel_proposal_should_work() { new_test_ext().execute_with(|| { - assert_ok!(propose_set_balance(1, 2, 2)); - assert_ok!(propose_set_balance(1, 4, 4)); + assert_ok!(propose_set_balance(2, 2, 2)); + assert_ok!(propose_set_balance(2, 4, 4)); assert_noop!(Democracy::cancel_proposal(RuntimeOrigin::signed(1), 0), BadOrigin); let hash = note_preimage(1); assert_ok!(Democracy::set_metadata( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(2), MetadataOwner::Proposal(0), Some(hash) )); @@ -122,8 +137,8 @@ fn blacklisting_should_work() { System::set_block_number(0); let hash = set_balance_proposal(2).hash(); - assert_ok!(propose_set_balance(1, 2, 2)); - assert_ok!(propose_set_balance(1, 4, 4)); + assert_ok!(propose_set_balance(3, 2, 2)); + assert_ok!(propose_set_balance(3, 4, 4)); assert_noop!(Democracy::blacklist(RuntimeOrigin::signed(1), hash, None), BadOrigin); assert_ok!(Democracy::blacklist(RuntimeOrigin::root(), hash, None)); @@ -131,7 +146,7 @@ fn blacklisting_should_work() { assert_eq!(Democracy::backing_for(0), None); assert_eq!(Democracy::backing_for(1), Some(4)); - assert_noop!(propose_set_balance(1, 2, 2), Error::<Test>::ProposalBlacklisted); + assert_noop!(propose_set_balance(3, 2, 2), Error::<Test>::ProposalBlacklisted); fast_forward_to(2); @@ -146,9 +161,9 @@ fn blacklisting_should_work() { fn runners_up_should_come_after() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 2)); - assert_ok!(propose_set_balance(1, 4, 4)); - assert_ok!(propose_set_balance(1, 3, 3)); + assert_ok!(propose_set_balance(3, 2, 2)); + assert_ok!(propose_set_balance(3, 4, 4)); + assert_ok!(propose_set_balance(3, 3, 3)); fast_forward_to(2); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), 0, aye(1))); fast_forward_to(4); diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs index 5dd0fdbe33..89a2d8e659 100644 --- a/frame/democracy/src/tests/voting.rs +++ b/frame/democracy/src/tests/voting.rs @@ -73,7 +73,7 @@ fn single_proposal_should_work() { // start of 2 => next referendum scheduled. fast_forward_to(2); - assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); + assert_ok!(Democracy::vote(RuntimeOrigin::signed(2), r, aye(2))); assert_eq!(Democracy::referendum_count(), 1); assert_eq!( @@ -84,7 +84,7 @@ fn single_proposal_should_work() { dispatch_origin: DispatchOrigin::Root, threshold: VoteThreshold::SuperMajorityApprove, delay: 2, - tally: Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 10000, nay_voters: 0 }, + tally: Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 10000, nay_voters: 0 }, }) ); @@ -97,6 +97,7 @@ fn single_proposal_should_work() { fast_forward_to(4); assert_noop!(Democracy::referendum_status(0), Error::<Test>::ReferendumInvalid); + assert!(pallet_scheduler::Agenda::<Test>::get(6)[0].is_some()); // referendum passes and wait another two blocks for enactment. From b2981df4af303cfbd12a5ed1e35d02f6151a2fa5 Mon Sep 17 00:00:00 2001 From: Michal Lustyk <MichalLustykNeti> Date: Fri, 17 Nov 2023 11:10:18 +0100 Subject: [PATCH 2/2] BLOCKCHAIN-176 hanged slash to withdraw --- frame/democracy/src/lib.rs | 13 +++++-- frame/democracy/src/tests.rs | 5 ++- frame/democracy/src/tests/delegation.rs | 27 +++++++------- frame/democracy/src/tests/public_proposals.rs | 37 ++++++++++++++----- frame/democracy/src/tests/scheduling.rs | 10 ++--- frame/democracy/src/tests/voting.rs | 6 +-- 6 files changed, 61 insertions(+), 37 deletions(-) diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 2b56b4d19f..c19e06c3c1 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -166,7 +166,7 @@ use frame_support::{ schedule::{v3::Named as ScheduleNamed, DispatchTime}, Bounded, Currency, Get, Hash as PreimageHash, LockIdentifier, LockableCurrency, QueryPreimage, ReservableCurrency, StorePreimage, - Contains, OnUnbalanced + Contains, OnUnbalanced, tokens::{ExistenceRequirement, WithdrawReasons} }, pallet_prelude::{MaxEncodedLen, TypeInfo}, BoundedVec, @@ -1242,9 +1242,14 @@ impl<T: Config> Pallet<T> { fn do_propose(who: T::AccountId, proposal: BoundedCallOf<T>, value: BalanceOf<T>, dispatch_origin: DispatchOrigin) -> DispatchResult { T::Citizenship::ensure_politics_allowed(&who)?; - ensure!(T::Currency::can_slash(&who, T::ProposalFeeAmount::get()), Error::<T>::InsufficientFunds); - - T::ProposalFee::on_unbalanced(T::Currency::slash(&who, T::ProposalFeeAmount::get()).0); + T::ProposalFee::on_unbalanced( + T::Currency::withdraw( + &who, + T::ProposalFeeAmount::get(), + WithdrawReasons::FEE, + ExistenceRequirement::KeepAlive + )? + ); let index = Self::public_prop_count(); let real_prop_count = PublicProps::<T>::decode_len().unwrap_or(0) as u32; diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index b0ab7b9c99..0e3155c426 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -332,7 +332,7 @@ impl Config for Test { pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap(); - let balances = vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; + let balances = vec![(1, 100), (2, 200), (3, 300), (4, 400), (5, 500), (6, 600)]; let mut llm_balances: Vec<(u64, u64, u64)> = balances.iter().map(|(id, _)| (*id, 6000, 5000)).collect(); llm_balances.push((7, 1000, 1000)); @@ -360,7 +360,7 @@ fn params_should_work() { new_test_ext().execute_with(|| { assert_eq!(Democracy::referendum_count(), 0); assert_eq!(Balances::free_balance(42), 0); - assert_eq!(Balances::total_issuance(), 210); + assert_eq!(Balances::total_issuance(), 2100); }); } @@ -396,6 +396,7 @@ fn fast_forward_to(n: u64) { fn begin_referendum() -> ReferendumIndex { System::set_block_number(0); + Balances::make_free_balance_be(&1, 100); assert_ok!(propose_set_balance(1, 2, 1)); fast_forward_to(2); 0 diff --git a/frame/democracy/src/tests/delegation.rs b/frame/democracy/src/tests/delegation.rs index b320648587..90091edf9e 100644 --- a/frame/democracy/src/tests/delegation.rs +++ b/frame/democracy/src/tests/delegation.rs @@ -36,19 +36,19 @@ fn single_proposal_should_work_with_delegation() { assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 20)); let r = 0; assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 110, nays: 0, turnout: 110, aye_voters: 20000, nay_voters: 0 }); // Delegate a second vote. assert_ok!(Democracy::delegate(RuntimeOrigin::signed(3), 1, Conviction::None, 30)); - assert_eq!(tally(r), Tally { ayes: 50, nays: 0, turnout: 50, aye_voters: 30000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 140, nays: 0, turnout: 140, aye_voters: 30000, nay_voters: 0 }); // Reduce first vote. assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 10)); - assert_eq!(tally(r), Tally { ayes: 40, nays: 0, turnout: 40, aye_voters: 30000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 130, nays: 0, turnout: 130, aye_voters: 30000, nay_voters: 0 }); // Second vote delegates to first; we don't do tiered delegation, so it doesn't get used. assert_ok!(Democracy::delegate(RuntimeOrigin::signed(3), 2, Conviction::None, 30)); - assert_eq!(tally(r), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 100, nays: 0, turnout: 100, aye_voters: 20000, nay_voters: 0 }); // Main voter cancels their vote assert_ok!(Democracy::remove_vote(RuntimeOrigin::signed(1), r)); @@ -60,7 +60,7 @@ fn single_proposal_should_work_with_delegation() { // Main voter reinstates their vote assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); - assert_eq!(tally(r), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 100, nays: 0, turnout: 100, aye_voters: 20000, nay_voters: 0 }); }); } @@ -78,7 +78,6 @@ fn self_delegation_not_allowed() { fn cyclic_delegation_should_unwind() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); fast_forward_to(2); @@ -94,7 +93,7 @@ fn cyclic_delegation_should_unwind() { assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, nay(1))); // Delegated vote is counted. - assert_eq!(tally(r), Tally { ayes: 30, nays: 20, turnout: 50, aye_voters: 10000, nay_voters: 20000 }); + assert_eq!(tally(r), Tally { ayes: 300, nays: 110, turnout: 410, aye_voters: 10000, nay_voters: 20000 }); }); } @@ -111,13 +110,13 @@ fn single_proposal_should_work_with_vote_and_delegation() { let r = 0; assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); assert_ok!(Democracy::vote(RuntimeOrigin::signed(2), r, nay(2))); - assert_eq!(tally(r), Tally { ayes: 0, nays: 20, turnout: 20, aye_voters: 10000, nay_voters: 10000 }); + assert_eq!(tally(r), Tally { ayes: 90, nays: 200, turnout: 290, aye_voters: 10000, nay_voters: 10000 }); // Delegate vote. assert_ok!(Democracy::remove_vote(RuntimeOrigin::signed(2), r)); assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 20)); // Delegated vote replaces the explicit vote. - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20 , aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 110, nays: 0, turnout: 110 , aye_voters: 20000, nay_voters: 0 }); }); } @@ -137,7 +136,7 @@ fn single_proposal_should_work_with_undelegation() { assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); // Delegated vote is not counted. - assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0, aye_voters: 10000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 90, nays: 0, turnout: 90, aye_voters: 10000, nay_voters: 0 }); }); } @@ -149,11 +148,11 @@ fn single_proposal_should_work_with_delegation_and_vote() { // Delegate, undelegate and vote. assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::None, 20)); - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 110, nays: 0, turnout: 110, aye_voters: 20000, nay_voters: 0 }); assert_ok!(Democracy::undelegate(RuntimeOrigin::signed(2))); assert_ok!(Democracy::vote(RuntimeOrigin::signed(2), r, aye(2))); // Delegated vote is not counted. - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 290, nays: 0, turnout: 290, aye_voters: 20000, nay_voters: 0 }); }); } @@ -166,7 +165,7 @@ fn conviction_should_be_honored_in_delegation() { assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::Locked6x, 20)); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); // Delegated vote is huge. - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 110, nays: 0, turnout: 110, aye_voters: 20000, nay_voters: 0 }); }); } @@ -195,7 +194,7 @@ fn redelegation_keeps_lock() { assert_ok!(Democracy::delegate(RuntimeOrigin::signed(2), 1, Conviction::Locked6x, 20)); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); // Delegated vote is huge. - assert_eq!(tally(r), Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 20000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 110, nays: 0, turnout: 110, aye_voters: 20000, nay_voters: 0 }); let mut prior_lock = vote::PriorLock::default(); diff --git a/frame/democracy/src/tests/public_proposals.rs b/frame/democracy/src/tests/public_proposals.rs index b68cd44b39..e3ae7f9016 100644 --- a/frame/democracy/src/tests/public_proposals.rs +++ b/frame/democracy/src/tests/public_proposals.rs @@ -45,9 +45,9 @@ fn deposit_for_proposals_should_be_taken() { assert_ok!(Democracy::second(RuntimeOrigin::signed(5), 0)); // liberland specific - free balance shouldn't change, seconds shouldn't // lock anything - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::free_balance(2), 20); - assert_eq!(Balances::free_balance(5), 50); + assert_eq!(Balances::free_balance(1), 90); + assert_eq!(Balances::free_balance(2), 200); + assert_eq!(Balances::free_balance(5), 500); }); } @@ -60,9 +60,23 @@ fn deposit_for_proposals_should_be_returned() { assert_ok!(Democracy::second(RuntimeOrigin::signed(5), 0)); assert_ok!(Democracy::second(RuntimeOrigin::signed(5), 0)); fast_forward_to(3); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::free_balance(2), 20); - assert_eq!(Balances::free_balance(5), 50); + assert_eq!(Balances::free_balance(1), 90); + assert_eq!(Balances::free_balance(2), 200); + assert_eq!(Balances::free_balance(5), 500); + }); +} + +#[test] +fn proposal_with_funds_below_save_value_should_not_work() { + new_test_ext().execute_with(|| { + assert_ok!(propose_set_balance(1, 2, 5)); + + Balances::make_free_balance_be(&1, 0); + + assert_noop!( + propose_set_balance(1, 2, 0), + pallet_balances::Error::<Test, _>::InsufficientBalance, + ); }); } @@ -71,7 +85,12 @@ fn proposal_with_funds_below_minimum_should_not_work() { new_test_ext().execute_with(|| { assert_ok!(propose_set_balance(1, 2, 5)); - assert_noop!(propose_set_balance(1, 2, 0), Error::<Test>::InsufficientFunds); + Balances::make_free_balance_be(&1, 10); + + assert_noop!( + propose_set_balance(1, 2, 0), + pallet_balances::pallet::Error::<Test>::Expendability + ); }); } @@ -79,11 +98,11 @@ fn proposal_with_funds_below_minimum_should_not_work() { fn creating_proposal_takes_fee() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_eq!(Balances::total_balance(&1), 10); + assert_eq!(Balances::total_balance(&1), 100); assert_ok!(propose_set_balance(1, 2, 5)); - assert_eq!(Balances::total_balance(&1), 0); + assert_eq!(Balances::total_balance(&1), 90); }); } diff --git a/frame/democracy/src/tests/scheduling.rs b/frame/democracy/src/tests/scheduling.rs index c158f796bc..0f8556f2e9 100644 --- a/frame/democracy/src/tests/scheduling.rs +++ b/frame/democracy/src/tests/scheduling.rs @@ -34,7 +34,7 @@ fn simple_passing_should_work() { 0, ); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, aye(1))); - assert_eq!(tally(r), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 10000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 100, nays: 0, turnout: 100, aye_voters: 10000, nay_voters: 0 }); assert_eq!(Democracy::lowest_unbaked(), 0); next_block(); next_block(); @@ -54,7 +54,7 @@ fn simple_failing_should_work() { 0, ); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r, nay(1))); - assert_eq!(tally(r), Tally { ayes: 0, nays: 10, turnout: 10, aye_voters: 00000, nay_voters: 10000 }); + assert_eq!(tally(r), Tally { ayes: 0, nays: 100, turnout: 100, aye_voters: 00000, nay_voters: 10000 }); next_block(); next_block(); @@ -82,12 +82,12 @@ fn ooo_inject_referendums_should_work() { ); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r2, aye(1))); - assert_eq!(tally(r2), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 10000, nay_voters: 0 }); + assert_eq!(tally(r2), Tally { ayes: 100, nays: 0, turnout: 100, aye_voters: 10000, nay_voters: 0 }); next_block(); assert_ok!(Democracy::vote(RuntimeOrigin::signed(1), r1, aye(1))); - assert_eq!(tally(r1), Tally { ayes: 10, nays: 0, turnout: 10, aye_voters: 10000, nay_voters: 0 }); + assert_eq!(tally(r1), Tally { ayes: 100, nays: 0, turnout: 100, aye_voters: 10000, nay_voters: 0 }); next_block(); assert_eq!(Balances::free_balance(42), 2); @@ -114,7 +114,7 @@ fn delayed_enactment_should_work() { assert_ok!(Democracy::vote(RuntimeOrigin::signed(5), r, aye(5))); assert_ok!(Democracy::vote(RuntimeOrigin::signed(6), r, aye(6))); - assert_eq!(tally(r), Tally { ayes: 210, nays: 0, turnout: 210, aye_voters: 60000, nay_voters: 0 }); + assert_eq!(tally(r), Tally { ayes: 2100, nays: 0, turnout: 2100, aye_voters: 60000, nay_voters: 0 }); next_block(); assert_eq!(Balances::free_balance(42), 0); diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs index 89a2d8e659..dc005ae4df 100644 --- a/frame/democracy/src/tests/voting.rs +++ b/frame/democracy/src/tests/voting.rs @@ -84,7 +84,7 @@ fn single_proposal_should_work() { dispatch_origin: DispatchOrigin::Root, threshold: VoteThreshold::SuperMajorityApprove, delay: 2, - tally: Tally { ayes: 20, nays: 0, turnout: 20, aye_voters: 10000, nay_voters: 0 }, + tally: Tally { ayes: 200, nays: 0, turnout: 200, aye_voters: 10000, nay_voters: 0 }, }) ); @@ -147,7 +147,7 @@ fn controversial_low_turnout_voting_should_work() { assert_ok!(Democracy::vote(RuntimeOrigin::signed(5), r, big_nay(5))); assert_ok!(Democracy::vote(RuntimeOrigin::signed(6), r, big_aye(6))); - assert_eq!(tally(r), Tally { ayes: 60, nays: 50, turnout: 110, aye_voters: 10000, nay_voters: 10000 }); + assert_eq!(tally(r), Tally { ayes: 600, nays: 500, turnout: 1100, aye_voters: 10000, nay_voters: 10000 }); next_block(); next_block(); @@ -160,7 +160,7 @@ fn controversial_low_turnout_voting_should_work() { fn passing_low_turnout_voting_should_work() { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); - assert_eq!(Balances::total_issuance(), 210); + assert_eq!(Balances::total_issuance(), 2100); let r = Democracy::inject_referendum( 2,