mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 13:21:01 +00:00
Introduce logic for deposits.
This commit is contained in:
@@ -72,15 +72,15 @@ impl VoteThreshold {
|
||||
// public proposals
|
||||
const PUBLIC_PROP_COUNT: &[u8] = b"dem:cou"; // PropIndex
|
||||
const PUBLIC_PROPS: &[u8] = b"dem:pub"; // Vec<(PropIndex, Proposal)>
|
||||
const LOCKED_FOR: &[u8] = b"dem:loc:"; // PropIndex -> Balance
|
||||
const DEPOSIT_OF: &[u8] = b"dem:dep:"; // PropIndex -> (Balance, Vec<AccountId>)
|
||||
const LAUNCH_PERIOD: &[u8] = b"dem:lau"; // BlockNumber
|
||||
|
||||
// referenda
|
||||
const VOTING_PERIOD: &[u8] = b"dem:per"; // BlockNumber
|
||||
const REFERENDUM_COUNT: &[u8] = b"dem:cou"; // ReferendumIndex
|
||||
const NEXT_TALLY: &[u8] = b"dem:nxt"; // ReferendumIndex
|
||||
const REFERENDUM_INFO_OF: &[u8] = b"dem:pro"; // ReferendumIndex -> (BlockNumber, Proposal, VoteThreshold)
|
||||
const VOTERS: &[u8] = b"dem:vtr:"; // ReferendumIndex -> Vec<AccountId>
|
||||
const REFERENDUM_INFO_OF: &[u8] = b"dem:pro:"; // ReferendumIndex -> (BlockNumber, Proposal, VoteThreshold)
|
||||
const VOTERS_FOR: &[u8] = b"dem:vtr:"; // ReferendumIndex -> Vec<AccountId>
|
||||
const VOTE_OF: &[u8] = b"dem:vot:"; // (ReferendumIndex, AccountId) -> bool
|
||||
|
||||
/// How often (in blocks) to check for new votes.
|
||||
@@ -96,14 +96,19 @@ pub fn launch_period() -> BlockNumber {
|
||||
}
|
||||
|
||||
/// The public proposals. Unsorted.
|
||||
pub fn public_props() -> Vec<(PropIndex, Proposal)> {
|
||||
pub fn public_props() -> Vec<(PropIndex, Proposal, Balance)> {
|
||||
storage::get_or_default(PUBLIC_PROPS)
|
||||
}
|
||||
|
||||
/// Those who have locked a deposit.
|
||||
pub fn deposit_lockers(proposal: PropIndex) -> Option<(Balance, Vec<AccountId>)> {
|
||||
storage::get(DEPOSIT_OF)
|
||||
}
|
||||
|
||||
/// Get the amount locked in support of `proposal`; false if proposal isn't a valid proposal
|
||||
/// index.
|
||||
pub fn locked_for(proposal: PropIndex) -> Option<Balance> {
|
||||
storage::get(&proposal.to_keyed_vec(LOCKED_FOR))
|
||||
deposit_lockers(proposal).map(|(d, l)| d * (l.len() as Balance))
|
||||
}
|
||||
|
||||
/// Return true if `ref_index` is an on-going referendum.
|
||||
@@ -113,7 +118,7 @@ pub fn is_active_referendum(ref_index: ReferendumIndex) -> bool {
|
||||
|
||||
/// Get the voters for the current proposal.
|
||||
pub fn voters_for(ref_index: ReferendumIndex) -> Vec<AccountId> {
|
||||
storage::get_or_default(&ref_index.to_keyed_vec(VOTERS))
|
||||
storage::get_or_default(&ref_index.to_keyed_vec(VOTERS_FOR))
|
||||
}
|
||||
|
||||
/// Get the vote, if Some, of `who`.
|
||||
@@ -153,15 +158,15 @@ pub mod public {
|
||||
use super::*;
|
||||
|
||||
/// Propose a sensitive action to be taken.
|
||||
pub fn propose(signed: &AccountId, proposal: &Proposal, lock: Balance) {
|
||||
pub fn propose(signed: &AccountId, proposal: &Proposal, value: Balance) {
|
||||
let b = staking::balance(signed);
|
||||
assert!(b >= lock);
|
||||
assert!(b >= value);
|
||||
|
||||
staking::internal::set_balance(signed, b - lock);
|
||||
staking::internal::set_balance(signed, b - value);
|
||||
|
||||
let index: PropIndex = storage::get_or_default(PUBLIC_PROP_COUNT);
|
||||
storage::put(PUBLIC_PROP_COUNT, &(index + 1));
|
||||
storage::put(&index.to_keyed_vec(LOCKED_FOR), &lock);
|
||||
storage::put(&index.to_keyed_vec(DEPOSIT_OF), &(value, vec![*signed]));
|
||||
|
||||
let mut props: Vec<(PropIndex, Proposal)> = storage::get_or_default(PUBLIC_PROPS);
|
||||
props.push((index, proposal.clone()));
|
||||
@@ -169,14 +174,15 @@ pub mod public {
|
||||
}
|
||||
|
||||
/// Propose a sensitive action to be taken.
|
||||
pub fn second(signed: &AccountId, proposal: PropIndex, lock: Balance) {
|
||||
pub fn second(signed: &AccountId, proposal: PropIndex) {
|
||||
let b = staking::balance(signed);
|
||||
assert!(b >= lock);
|
||||
let key = proposal.to_keyed_vec(LOCKED_FOR);
|
||||
let balance: Balance = storage::get(&key).expect("can only second an existing proposal");
|
||||
let key = proposal.to_keyed_vec(DEPOSIT_OF);
|
||||
let mut deposit: (Balance, Vec<AccountId>) = storage::get(&key).expect("can only second an existing proposal");
|
||||
assert!(b >= deposit.0);
|
||||
deposit.1.push(*signed);
|
||||
|
||||
staking::internal::set_balance(signed, b - lock);
|
||||
storage::put(&key, &(balance + lock));
|
||||
staking::internal::set_balance(signed, b - deposit.0);
|
||||
storage::put(&key, &deposit);
|
||||
}
|
||||
|
||||
/// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal;
|
||||
@@ -192,7 +198,7 @@ pub mod public {
|
||||
if !storage::exists(&key) {
|
||||
let mut voters = voters_for(ref_index);
|
||||
voters.push(signed.clone());
|
||||
storage::put(VOTERS, &voters);
|
||||
storage::put(&ref_index.to_keyed_vec(VOTERS_FOR), &voters);
|
||||
}
|
||||
storage::put(&key, &approve_proposal);
|
||||
}
|
||||
@@ -214,7 +220,7 @@ pub mod privileged {
|
||||
for v in voters_for(ref_index) {
|
||||
storage::kill(&(v, ref_index).to_keyed_vec(VOTE_OF));
|
||||
}
|
||||
storage::kill(&ref_index.to_keyed_vec(VOTERS));
|
||||
storage::kill(&ref_index.to_keyed_vec(VOTERS_FOR));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +240,8 @@ pub mod internal {
|
||||
.enumerate()
|
||||
.max_by_key(|x| locked_for((x.1).0))
|
||||
{
|
||||
let (_, proposal) = public_props.swap_remove(winner_index);
|
||||
let (prop_index, proposal, _) = public_props.swap_remove(winner_index);
|
||||
storage::kill(&prop_index.to_keyed_vec(DEPOSIT_OF));
|
||||
storage::put(PUBLIC_PROPS, &public_props);
|
||||
|
||||
inject_referendum(now + voting_period(), proposal, VoteThreshold::SuperMajorityApprove);
|
||||
@@ -259,7 +266,7 @@ fn inject_referendum(
|
||||
end: BlockNumber,
|
||||
proposal: Proposal,
|
||||
vote_threshold: VoteThreshold
|
||||
) {
|
||||
) -> ReferendumIndex {
|
||||
let ref_index: ReferendumIndex = storage::get_or_default(REFERENDUM_COUNT);
|
||||
if ref_index > 0 && referendum_info(ref_index - 1).map(|i| i.0 < end).unwrap_or(false) {
|
||||
panic!("Cannot inject a referendum that ends earlier than preceeding referendum");
|
||||
@@ -267,6 +274,7 @@ fn inject_referendum(
|
||||
|
||||
storage::put(REFERENDUM_COUNT, &(ref_index + 1));
|
||||
storage::put(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF), &(end, proposal, vote_threshold));
|
||||
ref_index
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -308,26 +316,39 @@ mod tests {
|
||||
twox_128(b"sta:tot").to_vec() => vec![].and(&210u64),
|
||||
twox_128(b"sta:spe").to_vec() => vec![].and(&1u64),
|
||||
twox_128(b"sta:vac").to_vec() => vec![].and(&3u64),
|
||||
twox_128(b"sta:era").to_vec() => vec![].and(&1u64)
|
||||
twox_128(b"sta:era").to_vec() => vec![].and(&1u64),
|
||||
twox_128(LAUNCH_PERIOD).to_vec() => vec![].and(&1u64),
|
||||
twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64)
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn params_should_work() {
|
||||
let mut t = new_test_ext();
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
assert_eq!(launch_period(), 1u64);
|
||||
assert_eq!(voting_period(), 1u64);
|
||||
assert_eq!(staking::sessions_per_era(), 1u64);
|
||||
assert_eq!(staking::total_stake(), 210u64);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_passing_should_work() {
|
||||
let alice = Keyring::Alice.to_raw_public();
|
||||
let mut t = new_test_ext();
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
assert_eq!(staking::era_length(), 1u64);
|
||||
assert_eq!(staking::total_stake(), 210u64);
|
||||
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&alice, &Proposal::StakingSetSessionsPerEra(2));
|
||||
public::vote(&alice, 1, true);
|
||||
let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove);
|
||||
public::vote(&alice, r, true);
|
||||
|
||||
assert_eq!(public::tally(), (10, 0));
|
||||
assert_eq!(voters_for(r), vec![alice.clone()]);
|
||||
assert_eq!(vote_of(&alice, r), Some(true));
|
||||
assert_eq!(tally(r), (10, 0));
|
||||
|
||||
democracy::internal::end_of_an_era();
|
||||
democracy::internal::end_block();
|
||||
staking::internal::check_new_era();
|
||||
|
||||
assert_eq!(staking::era_length(), 2u64);
|
||||
@@ -340,16 +361,15 @@ mod tests {
|
||||
let mut t = new_test_ext();
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
assert_eq!(staking::era_length(), 1u64);
|
||||
assert_eq!(staking::total_stake(), 210u64);
|
||||
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&alice, &Proposal::StakingSetSessionsPerEra(2));
|
||||
public::vote(&alice, 1, false);
|
||||
let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove);
|
||||
public::vote(&alice, r, false);
|
||||
|
||||
assert_eq!(public::tally(), (0, 10));
|
||||
assert_eq!(voters_for(r), vec![alice.clone()]);
|
||||
assert_eq!(vote_of(&alice, r), Some(false));
|
||||
assert_eq!(tally(r), (0, 10));
|
||||
|
||||
democracy::internal::end_of_an_era();
|
||||
democracy::internal::end_block();
|
||||
staking::internal::check_new_era();
|
||||
|
||||
assert_eq!(staking::era_length(), 1u64);
|
||||
@@ -368,27 +388,24 @@ mod tests {
|
||||
let mut t = new_test_ext();
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
assert_eq!(staking::era_length(), 1u64);
|
||||
assert_eq!(staking::total_stake(), 210u64);
|
||||
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&alice, &Proposal::StakingSetSessionsPerEra(2));
|
||||
public::vote(&alice, 1, true);
|
||||
public::vote(&bob, 1, false);
|
||||
public::vote(&charlie, 1, false);
|
||||
public::vote(&dave, 1, true);
|
||||
public::vote(&eve, 1, false);
|
||||
public::vote(&ferdie, 1, true);
|
||||
let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove);
|
||||
public::vote(&alice, r, true);
|
||||
public::vote(&bob, r, false);
|
||||
public::vote(&charlie, r, false);
|
||||
public::vote(&dave, r, true);
|
||||
public::vote(&eve, r, false);
|
||||
public::vote(&ferdie, r, true);
|
||||
|
||||
assert_eq!(public::tally(), (110, 100));
|
||||
assert_eq!(tally(r), (110, 100));
|
||||
|
||||
democracy::internal::end_of_an_era();
|
||||
democracy::internal::end_block();
|
||||
staking::internal::check_new_era();
|
||||
|
||||
assert_eq!(staking::era_length(), 2u64);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn controversial_low_turnout_voting_should_work() {
|
||||
let alice = Keyring::Alice.to_raw_public();
|
||||
@@ -446,5 +463,5 @@ mod tests {
|
||||
|
||||
assert_eq!(staking::era_length(), 2u64);
|
||||
});
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user