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