mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-08 06:38:01 +00:00
Fix some semantics. Add Storable::take.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -21,7 +21,7 @@ use runtime_support::size_of;
|
||||
use slicable::Slicable;
|
||||
use joiner::Joiner;
|
||||
use streamreader::StreamReader;
|
||||
use runtime::staking;
|
||||
use runtime::{system, governance, staking};
|
||||
|
||||
/// Internal functions that can be dispatched to.
|
||||
#[cfg_attr(test, derive(PartialEq, Debug))]
|
||||
@@ -29,6 +29,7 @@ use runtime::staking;
|
||||
pub enum InternalFunction {
|
||||
SystemSetCode,
|
||||
StakingSetSessionsPerEra,
|
||||
GovernanceSetApprovalPpmRequired,
|
||||
}
|
||||
|
||||
impl InternalFunction {
|
||||
@@ -37,6 +38,7 @@ impl InternalFunction {
|
||||
match value {
|
||||
x if x == InternalFunction::SystemSetCode as u8 => Some(InternalFunction::SystemSetCode),
|
||||
x if x == InternalFunction::StakingSetSessionsPerEra as u8 => Some(InternalFunction::StakingSetSessionsPerEra),
|
||||
x if x == InternalFunction::GovernanceSetApprovalPpmRequired as u8 => Some(InternalFunction::GovernanceSetApprovalPpmRequired),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -77,13 +79,17 @@ impl Proposal {
|
||||
let mut params = StreamReader::new(&self.input_data);
|
||||
match self.function {
|
||||
InternalFunction::SystemSetCode => {
|
||||
let code = params.read().unwrap();
|
||||
staking::set_sessions_per_era(code);
|
||||
let code: Vec<u8> = params.read().unwrap();
|
||||
system::set_code(&code);
|
||||
}
|
||||
InternalFunction::StakingSetSessionsPerEra => {
|
||||
let value = params.read().unwrap();
|
||||
staking::set_sessions_per_era(value);
|
||||
}
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired => {
|
||||
let value = params.read().unwrap();
|
||||
governance::set_approval_ppm_required(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,16 @@ pub trait Storable {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Retrives and returns the serialised value of a key from storage, removing it immediately.
|
||||
fn take(key: &[u8]) -> Option<Self> where Self: Sized {
|
||||
if let Some(value) = Self::lookup(key) {
|
||||
kill(key);
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Place the value in storage under `key`.
|
||||
fn store(&self, key: &[u8]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user