diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index f12014a220..96c7bfa1e6 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -2484,7 +2484,7 @@ dependencies = [ "srml-contracts 2.0.0", "srml-contracts-rpc-runtime-api 2.0.0", "srml-democracy 2.0.0", - "srml-elections 2.0.0", + "srml-elections-phragmen 2.0.0", "srml-executive 2.0.0", "srml-finality-tracker 2.0.0", "srml-grandpa 2.0.0", diff --git a/substrate/node/cli/src/chain_spec.rs b/substrate/node/cli/src/chain_spec.rs index d81591290e..bc9f1e615f 100644 --- a/substrate/node/cli/src/chain_spec.rs +++ b/substrate/node/cli/src/chain_spec.rs @@ -235,11 +235,11 @@ pub fn testnet_genesis( members: vec![], phantom: Default::default(), }), - elections: Some(ElectionsConfig { - members: vec![], - presentation_duration: 1 * DAYS, + elections_phragmen: Some(ElectionsConfig { + members: endowed_accounts.iter().take(2).cloned().collect(), term_duration: 28 * DAYS, - desired_seats: 0, + desired_members: 4, + desired_runners_up: 1, }), contracts: Some(ContractsConfig { current_schedule: contracts::Schedule { diff --git a/substrate/node/primitives/src/lib.rs b/substrate/node/primitives/src/lib.rs index 431ba17c00..6b128db4f3 100644 --- a/substrate/node/primitives/src/lib.rs +++ b/substrate/node/primitives/src/lib.rs @@ -60,9 +60,6 @@ pub type DigestItem = generic::DigestItem; /// Header type. pub type Header = generic::Header; /// Block type. -pub type Block = generic::Block; +pub type Block = generic::Block; /// Block ID. pub type BlockId = generic::BlockId; - -/// Opaque, encoded, unchecked extrinsic. -pub type UncheckedExtrinsic = OpaqueExtrinsic; diff --git a/substrate/node/runtime/Cargo.toml b/substrate/node/runtime/Cargo.toml index d65112da24..252a7767ea 100644 --- a/substrate/node/runtime/Cargo.toml +++ b/substrate/node/runtime/Cargo.toml @@ -33,7 +33,7 @@ collective = { package = "srml-collective", path = "../../srml/collective", defa contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } contracts-rpc-runtime-api = { package = "srml-contracts-rpc-runtime-api", path = "../../srml/contracts/rpc/runtime-api/", default-features = false } democracy = { package = "srml-democracy", path = "../../srml/democracy", default-features = false } -elections = { package = "srml-elections", path = "../../srml/elections", default-features = false } +elections-phragmen = { package = "srml-elections-phragmen", path = "../../srml/elections-phragmen", default-features = false } executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } finality-tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } @@ -72,7 +72,7 @@ std = [ "contracts/std", "contracts-rpc-runtime-api/std", "democracy/std", - "elections/std", + "elections-phragmen/std", "executive/std", "finality-tracker/std", "grandpa/std", diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 1544ee9a4a..a198877552 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -45,7 +45,6 @@ use sr_primitives::traits::{ self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, }; use version::RuntimeVersion; -use elections::VoteIndex; #[cfg(any(feature = "std", test))] use version::NativeVersion; use primitives::OpaqueMetadata; @@ -84,8 +83,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 181, - impl_version: 183, + spec_version: 182, + impl_version: 182, apis: RUNTIME_API_VERSIONS, }; @@ -324,33 +323,18 @@ impl collective::Trait for Runtime { parameter_types! { pub const CandidacyBond: Balance = 10 * DOLLARS; pub const VotingBond: Balance = 1 * DOLLARS; - pub const VotingFee: Balance = 2 * DOLLARS; - pub const MinimumVotingLock: Balance = 1 * DOLLARS; - pub const PresentSlashPerVoter: Balance = 1 * CENTS; - pub const CarryCount: u32 = 6; - // one additional vote should go by before an inactive voter can be reaped. - pub const InactiveGracePeriod: VoteIndex = 1; - pub const ElectionsVotingPeriod: BlockNumber = 2 * DAYS; - pub const DecayRatio: u32 = 0; } -impl elections::Trait for Runtime { +impl elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type ChangeMembers = Council; + type CurrencyToVote = CurrencyToVoteHandler; type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; - type VotingFee = VotingFee; - type MinimumVotingLock = MinimumVotingLock; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = ElectionsVotingPeriod; - type DecayRatio = DecayRatio; + type LoserCandidate = (); + type BadReport = (); + type KickedMember = (); + type ChangeMembers = Council; } type TechnicalCollective = collective::Instance2; @@ -518,7 +502,7 @@ construct_runtime!( Democracy: democracy::{Module, Call, Storage, Config, Event}, Council: collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommittee: collective::::{Module, Call, Storage, Origin, Event, Config}, - Elections: elections::{Module, Call, Storage, Event, Config}, + Elections: elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: membership::::{Module, Call, Storage, Event, Config}, FinalityTracker: finality_tracker::{Module, Call, Inherent}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, diff --git a/substrate/node/testing/src/genesis.rs b/substrate/node/testing/src/genesis.rs index 35ff93d1a6..a9f55d86e3 100644 --- a/substrate/node/testing/src/genesis.rs +++ b/substrate/node/testing/src/genesis.rs @@ -94,7 +94,7 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig collective_Instance1: Some(Default::default()), collective_Instance2: Some(Default::default()), membership_Instance1: Some(Default::default()), - elections: Some(Default::default()), + elections_phragmen: Some(Default::default()), sudo: Some(Default::default()), } } diff --git a/substrate/srml/elections-phragmen/src/lib.rs b/substrate/srml/elections-phragmen/src/lib.rs index 781d506bd6..f56c5a4ec3 100644 --- a/substrate/srml/elections-phragmen/src/lib.rs +++ b/substrate/srml/elections-phragmen/src/lib.rs @@ -76,6 +76,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use rstd::prelude::*; use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; use sr_primitives::weights::SimpleDispatchInfo; use srml_support::{ @@ -136,7 +137,8 @@ decl_storage! { /// Number of runners_up to keep. pub DesiredRunnersUp get(fn desired_runners_up) config(): u32; /// How long each seat is kept. This defines the next block number at which an election - /// round will happen. + /// round will happen. If set to zero, no elections are ever triggered and the module will + /// be in passive mode. In that case only a member set defined in at genesis can exist. pub TermDuration get(fn term_duration) config(): T::BlockNumber; // ---- State @@ -470,8 +472,10 @@ impl Module { /// Runs phragmen election and cleans all the previous candidate state. The voter state is NOT /// cleaned and voters must themselves submit a transaction to retract. fn end_block(block_number: T::BlockNumber) -> dispatch::Result { - if (block_number % Self::term_duration()).is_zero() { - Self::do_phragmen(); + if !Self::term_duration().is_zero() { + if (block_number % Self::term_duration()).is_zero() { + Self::do_phragmen(); + } } Ok(()) } @@ -701,7 +705,9 @@ mod tests { pub struct ExtBuilder { balance_factor: u64, voter_bond: u64, + term_duration: u64, desired_runners_up: u32, + members: Vec, } impl Default for ExtBuilder { @@ -710,6 +716,8 @@ mod tests { balance_factor: 1, voter_bond: 2, desired_runners_up: 0, + term_duration: 5, + members: vec![], } } } @@ -723,6 +731,14 @@ mod tests { self.desired_runners_up = count; self } + pub fn term_duration(mut self, duration: u64) -> Self { + self.term_duration = duration; + self + } + pub fn members(mut self, members: Vec) -> Self { + self.members = members; + self + } pub fn build(self) -> runtime_io::TestExternalities { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); GenesisConfig { @@ -738,10 +754,10 @@ mod tests { vesting: vec![], }), elections: Some(elections::GenesisConfig::{ - members: vec![], + members: self.members, desired_members: 2, desired_runners_up: self.desired_runners_up, - term_duration: 5, + term_duration: self.term_duration, }), }.build_storage().unwrap().into() } @@ -781,6 +797,33 @@ mod tests { }); } + #[test] + fn passive_module_should_work() { + ExtBuilder::default() + .term_duration(0) + .members(vec![1, 2, 3]) + .build() + .execute_with(|| + { + System::set_block_number(1); + assert_eq!(Elections::term_duration(), 0); + assert_eq!(Elections::desired_members(), 2); + assert_eq!(Elections::election_rounds(), 0); + + assert_eq!(Elections::members(), vec![1, 2, 3]); + assert_eq!(Elections::runners_up(), vec![]); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(all_voters(), vec![]); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![1, 2, 3]); + assert_eq!(Elections::runners_up(), vec![]); + }); + } + #[test] fn simple_candidate_submission_should_work() { ExtBuilder::default().build().execute_with(|| {