Fix some semantics. Add Storable::take.

This commit is contained in:
Gav
2018-01-21 22:57:50 +01:00
parent b615df2be6
commit 3788e47ce9
3 changed files with 40 additions and 24 deletions
@@ -16,6 +16,13 @@
//! Governance system: Handles administration and dispatch of sensitive operations including
//! setting new code, minting new tokens and changing parameters.
//!
//! For now this is limited to a simple qualified majority vote (whose parameter is retrieved from
//! storage) between validators. A single vote may be proposed per era, and at most one approval
//! vote may be cast by each validator. The tally is maintained
//!
//!
//!
use runtime_support::Vec;
use keyedvec::KeyedVec;
@@ -34,27 +41,29 @@ pub fn propose(transactor: &AccountID, proposal: &Proposal) {
approve(transactor, staking::current_era());
}
pub fn approve(transactor: &AccountID, era_index: BlockNumber) {
pub fn approve(validator: &AccountID, era_index: BlockNumber) {
if era_index != staking::current_era() {
panic!("approval vote applied on non-current era.")
}
if Proposal::lookup(b"gov:pro").is_none() {
panic!("there must be a proposal in order to approve.");
}
let key = transactor.to_keyed_vec(b"gov:app:");
if session::validators().into_iter().position(|v| &v == validator).is_none() {
panic!("transactor must be a validator to approve.");
}
let key = validator.to_keyed_vec(b"gov:app:");
if bool::lookup(&key).is_some() {
panic!("transactor may not approve a proposal twice in one era.");
}
true.store(&key);
(approval_count() + 1).store(b"gov:app");
}
pub fn set_approval_ppm_required(ppm: u32) {
ppm.store(b"gov:apr");
}
// INSPECTION API
pub fn approval_count() -> u32 {
Storable::lookup_default(b"gov:app")
}
pub fn approval_ppm_required() -> u32 {
Storable::lookup(b"gov:apr").unwrap_or(1000)
}
@@ -69,12 +78,11 @@ pub fn approvals_required() -> u32 {
pub fn end_of_an_era() {
// tally up votes for the current proposal, if any. enact if there are sufficient approvals.
if let Some(proposal) = Proposal::lookup(b"gov:pro") {
let enact = approval_count() >= approvals_required();
// clear proposal
reset_proposal();
if enact {
kill(b"gov:pro");
let approved: u32 = session::validators().into_iter()
.map(|v| bool::take(&v.to_keyed_vec(b"gov:app:")).map(|_| 1).unwrap_or(0))
.sum();
if approved >= approvals_required() {
proposal.enact();
}
}
@@ -82,14 +90,6 @@ pub fn end_of_an_era() {
// PRIVATE API
fn reset_proposal() {
session::validators().into_iter().for_each(|v| {
kill(&v.to_keyed_vec(b"gov:app:"));
});
kill(b"gov:pro");
kill(b"gov:app");
}
#[cfg(test)]
mod tests {
// TODO