Cleanups and introduce all dispatchable endpoints.

This commit is contained in:
Gav
2018-03-12 10:15:30 +01:00
parent 873b579726
commit 550ec8cdf5
7 changed files with 154 additions and 138 deletions
+1 -1
View File
@@ -49,7 +49,7 @@ pub mod transaction;
pub use self::block::{Header, Block, Log, Digest};
pub use self::block::Number as BlockNumber;
pub use self::transaction::{Transaction, UncheckedTransaction, Function, Proposal};
pub use self::transaction::{Transaction, UncheckedTransaction, Function, Proposal, VoteThreshold};
/// Alias to Ed25519 pubkey that identifies an account on the relay chain. This will almost
/// certainly continue to be the same as the substrate's `AuthorityId`.
+62 -17
View File
@@ -17,7 +17,7 @@
//! Transaction type.
use rstd::vec::Vec;
use codec::{Input, Slicable};
use codec::{Input, Slicable, NonTrivialSlicable};
use {AccountId, SessionKey};
#[cfg(feature = "std")]
@@ -29,24 +29,26 @@ use block::Number as BlockNumber;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[repr(u8)]
enum InternalFunctionId {
/// Set the system's code.
SystemSetCode = 0x00,
/// Set the session length.
SessionSetLength = 0x10,
/// Force a new session.
SessionForceNewSession = 0x11,
/// Set the number of sessions per era.
StakingSetSessionsPerEra = 0x20,
/// Set the minimum bonding duration for staking.
StakingSetBondingDuration = 0x21,
/// Set the validator count for staking.
StakingSetValidatorCount = 0x22,
/// Force a new staking era.
StakingForceNewEra = 0x23,
/// See below.
DemocracyCancelReferendum = 0x30,
DemocracyStartReferendum = 0x31,
CouncilSetDesiredSeats = 0x40,
CouncilRemoveMember = 0x41,
CouncilSetPresentationDuration = 0x42,
CouncilSetTermDuration = 0x43,
CouncilVoteSetCooloffPeriod = 0x50,
CouncilVoteSetVotingPeriod = 0x51,
}
impl InternalFunctionId {
@@ -66,26 +68,57 @@ impl InternalFunctionId {
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub enum VoteThreshold {
/// A supermajority of approvals is needed to pass this vote.
SuperMajorityApprove,
/// A supermajority of rejects is needed to fail this vote.
SuperMajorityAgainst,
/// A simple majority of approvals is needed to pass this vote.
SimpleMajority,
}
impl Slicable for VoteThreshold {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
u8::decode(input).and_then(|v| match v {
0 => Some(VoteThreshold::SuperMajorityApprove),
1 => Some(VoteThreshold::SuperMajorityAgainst),
2 => Some(VoteThreshold::SimpleMajority),
_ => None,
})
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
match *self {
VoteThreshold::SuperMajorityApprove => 0u8,
VoteThreshold::SuperMajorityAgainst => 1u8,
VoteThreshold::SimpleMajority => 2u8,
}.using_encoded(f)
}
}
impl NonTrivialSlicable for VoteThreshold {}
/// Internal functions that can be dispatched to.
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[allow(missing_docs)]
pub enum Proposal {
/// Set the system's code.
SystemSetCode(Vec<u8>),
/// Set the session length.
SessionSetLength(BlockNumber),
/// Force a new session.
SessionForceNewSession,
/// Set the number of sessions per era.
StakingSetSessionsPerEra(BlockNumber),
/// Set the minimum bonding duration for staking.
StakingSetBondingDuration(BlockNumber),
/// Set the validator count for staking.
StakingSetValidatorCount(u32),
/// Force a new staking era.
StakingForceNewEra,
/// Cancel a referendum.
DemocracyStartReferendum(Box<Proposal>, VoteThreshold),
DemocracyCancelReferendum(u32),
CouncilSetDesiredSeats(u32),
CouncilRemoveMember(AccountId),
CouncilSetPresentationDuration(BlockNumber),
CouncilSetTermDuration(BlockNumber),
CouncilVoteSetCooloffPeriod(BlockNumber),
CouncilVoteSetVotingPeriod(BlockNumber),
}
impl Slicable for Proposal {
@@ -104,7 +137,18 @@ impl Slicable for Proposal {
InternalFunctionId::StakingSetValidatorCount =>
Proposal::StakingSetValidatorCount(Slicable::decode(input)?),
InternalFunctionId::StakingForceNewEra => Proposal::StakingForceNewEra,
InternalFunctionId::DemocracyStartReferendum => {
let a = Slicable::decode(input)?;
let b = Slicable::decode(input)?;
Proposal::DemocracyStartReferendum(Box::new(a), b)
}
InternalFunctionId::DemocracyCancelReferendum => Proposal::DemocracyCancelReferendum(Slicable::decode(input)?),
InternalFunctionId::CouncilSetDesiredSeats => Proposal::CouncilSetDesiredSeats(Slicable::decode(input)?),
InternalFunctionId::CouncilRemoveMember => Proposal::CouncilRemoveMember(Slicable::decode(input)?),
InternalFunctionId::CouncilSetPresentationDuration => Proposal::CouncilSetPresentationDuration(Slicable::decode(input)?),
InternalFunctionId::CouncilSetTermDuration => Proposal::CouncilSetTermDuration(Slicable::decode(input)?),
InternalFunctionId::CouncilVoteSetCooloffPeriod => Proposal::CouncilVoteSetCooloffPeriod(Slicable::decode(input)?),
InternalFunctionId::CouncilVoteSetVotingPeriod => Proposal::CouncilVoteSetVotingPeriod(Slicable::decode(input)?),
};
Some(function)
@@ -143,6 +187,7 @@ impl Slicable for Proposal {
(InternalFunctionId::DemocracyCancelReferendum as u8).using_encoded(|s| v.extend(s));
data.using_encoded(|s| v.extend(s));
}
_ => { unimplemented!() }
}
v
+75 -28
View File
@@ -14,36 +14,83 @@
// You should have received a copy of the GNU General Public License
// along with Substrate Demo. If not, see <http://www.gnu.org/licenses/>.
//! Democratic system: Handles administration of general stakeholder voting.
//! Dispatch system. Just dispatches calls.
use demo_primitives::Proposal;
use runtime::{staking, system, session, democracy};
use demo_primitives::{Function, Proposal, AccountId};
use runtime::{staking, system, session, democracy, council, council_vote, timestamp};
pub fn enact_proposal(proposal: Proposal) {
/// Dispatch a proposal.
pub fn proposal(proposal: Proposal) {
match proposal {
Proposal::SystemSetCode(code) => {
system::privileged::set_code(&code);
}
Proposal::SessionSetLength(value) => {
session::privileged::set_length(value);
}
Proposal::SessionForceNewSession => {
session::privileged::force_new_session();
}
Proposal::StakingSetSessionsPerEra(value) => {
staking::privileged::set_sessions_per_era(value);
}
Proposal::StakingSetBondingDuration(value) => {
staking::privileged::set_bonding_duration(value);
}
Proposal::StakingSetValidatorCount(value) => {
staking::privileged::set_validator_count(value);
}
Proposal::StakingForceNewEra => {
staking::privileged::force_new_era()
}
Proposal::DemocracyCancelReferendum(ref_index) => {
democracy::privileged::cancel_referendum(ref_index)
}
Proposal::SystemSetCode(ref a) =>
system::privileged::set_code(a),
Proposal::SessionSetLength(a) =>
session::privileged::set_length(a),
Proposal::SessionForceNewSession =>
session::privileged::force_new_session(),
Proposal::StakingSetSessionsPerEra(a) =>
staking::privileged::set_sessions_per_era(a),
Proposal::StakingSetBondingDuration(a) =>
staking::privileged::set_bonding_duration(a),
Proposal::StakingSetValidatorCount(a) =>
staking::privileged::set_validator_count(a),
Proposal::StakingForceNewEra =>
staking::privileged::force_new_era(),
Proposal::DemocracyCancelReferendum(a) =>
democracy::privileged::cancel_referendum(a),
Proposal::DemocracyStartReferendum(a, b) =>
democracy::privileged::start_referendum(*a, b),
Proposal::DemocracyCancelReferendum(a) =>
democracy::privileged::cancel_referendum(a),
Proposal::CouncilSetDesiredSeats(a) =>
council::privileged::set_desired_seats(a),
Proposal::CouncilRemoveMember(a) =>
council::privileged::remove_member(&a),
Proposal::CouncilSetPresentationDuration(a) =>
council::privileged::set_presentation_duration(a),
Proposal::CouncilSetTermDuration(a) =>
council::privileged::set_term_duration(a),
Proposal::CouncilVoteSetCooloffPeriod(a) =>
council_vote::privileged::set_cooloff_period(a),
Proposal::CouncilVoteSetVotingPeriod(a) =>
council_vote::privileged::set_voting_period(a),
}
}
/// Dispatch a function.
pub fn function(function: &Function, transactor: &AccountId) {
match *function {
Function::StakingStake =>
staking::public::stake(transactor),
Function::StakingUnstake =>
staking::public::unstake(transactor),
Function::StakingTransfer(dest, value) =>
staking::public::transfer(transactor, &dest, value),
Function::SessionSetKey(session) =>
session::public::set_key(transactor, &session),
Function::TimestampSet(t) =>
timestamp::public::set(t),
Function::CouncilVotePropose(ref a) =>
council_vote::public::propose(transactor, a),
Function::CouncilVoteVote(ref a, b) =>
council_vote::public::vote(transactor, a, b),
Function::CouncilVoteVeto(ref a) =>
council_vote::public::veto(transactor, a),
Function::CouncilSetApprovals(ref a, b) =>
council::public::set_approvals(transactor, a, b),
Function::CouncilReapInactiveVoter(a, ref b, c, d) =>
council::public::reap_inactive_voter(transactor, a, b, c, d),
Function::CouncilRetractVoter(a) =>
council::public::retract_voter(transactor, a),
Function::CouncilSubmitCandidacy(a) =>
council::public::submit_candidacy(transactor, a),
Function::CouncilPresentWinner(ref a, b, c) =>
council::public::present_winner(transactor, a, b, c),
Function::DemocracyPropose(ref a, b) =>
democracy::public::propose(transactor, a, b),
Function::DemocracySecond(a) =>
democracy::public::second(transactor, a),
Function::DemocracyVote(a, b) =>
democracy::public::vote(transactor, a, b),
}
}
@@ -434,7 +434,6 @@ pub mod privileged {
pub mod internal {
use super::*;
use demo_primitives::Proposal;
use dispatch::enact_proposal;
/// Check there's nothing to do this block
pub fn end_block() {
@@ -184,8 +184,8 @@ pub mod privileged {
pub mod internal {
use super::*;
use runtime::democracy::VoteThreshold;
use runtime::democracy::privileged::start_referendum;
use demo_primitives::VoteThreshold;
pub fn end_block(now: BlockNumber) {
while let Some((proposal, proposal_hash)) = take_proposal_if_expiring_at(now) {
@@ -240,9 +240,8 @@ mod tests {
use codec::{KeyedVec, Joiner};
use keyring::Keyring::{Alice, Bob, Charlie, Dave};
use environment::with_env;
use demo_primitives::{AccountId, Proposal};
use demo_primitives::{AccountId, Proposal, VoteThreshold};
use runtime::{staking, council, democracy};
use runtime::democracy::VoteThreshold;
fn new_test_ext() -> TestExternalities {
testing::externalities()
+12 -33
View File
@@ -20,46 +20,25 @@ use rstd::prelude::*;
use integer_sqrt::IntegerSquareRoot;
use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable};
use runtime_support::storage;
use demo_primitives::{Proposal, AccountId, Hash, BlockNumber};
use demo_primitives::{Proposal, AccountId, Hash, BlockNumber, VoteThreshold};
use runtime::{staking, system, session};
use runtime::staking::Balance;
pub type PropIndex = u32;
pub type ReferendumIndex = u32;
#[cfg_attr(test, derive(Debug))]
#[derive(Clone, Copy, PartialEq)]
pub enum VoteThreshold {
SuperMajorityApprove,
SuperMajorityAgainst,
SimpleMajority,
}
impl Slicable for VoteThreshold {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
u8::decode(input).and_then(|v| match v {
0 => Some(VoteThreshold::SuperMajorityApprove),
1 => Some(VoteThreshold::SuperMajorityAgainst),
2 => Some(VoteThreshold::SimpleMajority),
_ => None,
})
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
match *self {
VoteThreshold::SuperMajorityApprove => 0u8,
VoteThreshold::SuperMajorityAgainst => 1u8,
VoteThreshold::SimpleMajority => 2u8,
}.using_encoded(f)
}
}
impl NonTrivialSlicable for VoteThreshold {}
impl VoteThreshold {
trait Approved {
/// Given `approve` votes for and `against` votes against from a total electorate size of
/// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the
/// overall outcome is in favour of approval.
pub fn approved(&self, approve: Balance, against: Balance, electorate: Balance) -> bool {
fn approved(&self, approve: Balance, against: Balance, electorate: Balance) -> bool;
}
impl Approved for VoteThreshold {
/// Given `approve` votes for and `against` votes against from a total electorate size of
/// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the
/// overall outcome is in favour of approval.
fn approved(&self, approve: Balance, against: Balance, electorate: Balance) -> bool {
let voters = approve + against;
match *self {
VoteThreshold::SuperMajorityApprove =>
@@ -236,7 +215,7 @@ pub mod privileged {
pub mod internal {
use super::*;
use demo_primitives::Proposal;
use dispatch::enact_proposal;
use dispatch;
/// Current era is ending; we should finish up any proposals.
pub fn end_block(now: BlockNumber) {
@@ -266,7 +245,7 @@ pub mod internal {
let total_stake = staking::total_stake();
clear_referendum(index);
if vote_threshold.approved(approve, against, total_stake) {
enact_proposal(proposal);
dispatch::proposal(proposal);
}
storage::put(NEXT_TALLY, &(index + 1));
}
+2 -55
View File
@@ -26,6 +26,7 @@ use environment::with_env;
use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Block, Header,
UncheckedTransaction, Function, Log};
use runtime::{staking, session};
use dispatch;
pub const NONCE_OF: &[u8] = b"sys:non:";
pub const BLOCK_HASH_AT: &[u8] = b"sys:old:";
@@ -125,60 +126,6 @@ pub mod internal {
header
}
/// Dispatch a function.
pub fn dispatch_function(function: &Function, transactor: &AccountId) {
match *function {
Function::StakingStake => {
::runtime::staking::public::stake(transactor);
}
Function::StakingUnstake => {
::runtime::staking::public::unstake(transactor);
}
Function::StakingTransfer(dest, value) => {
::runtime::staking::public::transfer(transactor, &dest, value);
}
Function::SessionSetKey(session) => {
::runtime::session::public::set_key(transactor, &session);
}
Function::TimestampSet(t) => {
::runtime::timestamp::public::set(t);
}
Function::CouncilVotePropose(ref a) => {
::runtime::council_vote::public::propose(transactor, a);
}
Function::CouncilVoteVote(ref a, b) => {
::runtime::council_vote::public::vote(transactor, a, b);
}
Function::CouncilVoteVeto(ref a) => {
::runtime::council_vote::public::veto(transactor, a);
}
Function::CouncilSetApprovals(ref a, b) => {
::runtime::council::public::set_approvals(transactor, a, b);
}
Function::CouncilReapInactiveVoter(a, ref b, c, d) => {
::runtime::council::public::reap_inactive_voter(transactor, a, b, c, d);
}
Function::CouncilRetractVoter(a) => {
::runtime::council::public::retract_voter(transactor, a);
}
Function::CouncilSubmitCandidacy(a) => {
::runtime::council::public::submit_candidacy(transactor, a);
}
Function::CouncilPresentWinner(ref a, b, c) => {
::runtime::council::public::present_winner(transactor, a, b, c);
}
Function::DemocracyPropose(ref a, b) => {
::runtime::democracy::public::propose(transactor, a, b);
}
Function::DemocracySecond(a) => {
::runtime::democracy::public::second(transactor, a);
}
Function::DemocracyVote(a, b) => {
::runtime::democracy::public::vote(transactor, a, b);
}
}
}
}
fn execute_transaction(utx: UncheckedTransaction) {
@@ -199,7 +146,7 @@ fn execute_transaction(utx: UncheckedTransaction) {
storage::put(&nonce_key, &(expected_nonce + 1));
// decode parameters and dispatch
internal::dispatch_function(&tx.function, &tx.signed);
dispatch::function(&tx.function, &tx.signed);
}
fn initial_checks(block: &Block) {