Redesign Democracy pallet (#5294)

* Repot a bit of democracy code

* Basic logic is drafted

* Lazy democracy builds.

* Add non-locked split-voting and instant-scheduling.

* Introduce delegation that works.

* Builds again.

* Indentation

* Building.

* Docs and migration

* Fix half of the tests

* Fix up & repot tests

* Fix runtime build

* Update docs

* Docs

* Nits.

* Turnout counts full capital

* Delegations could towards capital

* proxy delegation & proxy unvoting

* Fix

* Tests for split-voting

* Add missing file

* Persistent locking.
This commit is contained in:
Gavin Wood
2020-03-21 16:08:48 +01:00
committed by GitHub
parent 40f57f8ffa
commit 22f88bf9d1
19 changed files with 3080 additions and 1821 deletions
+113
View File
@@ -0,0 +1,113 @@
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! The conviction datatype.
use sp_std::{result::Result, convert::TryFrom};
use sp_runtime::{RuntimeDebug, traits::{Zero, Bounded, CheckedMul, CheckedDiv}};
use codec::{Encode, Decode};
use crate::types::Delegations;
/// A value denoting the strength of conviction of a vote.
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)]
pub enum Conviction {
/// 0.1x votes, unlocked.
None,
/// 1x votes, locked for an enactment period following a successful vote.
Locked1x,
/// 2x votes, locked for 2x enactment periods following a successful vote.
Locked2x,
/// 3x votes, locked for 4x...
Locked3x,
/// 4x votes, locked for 8x...
Locked4x,
/// 5x votes, locked for 16x...
Locked5x,
/// 6x votes, locked for 32x...
Locked6x,
}
impl Default for Conviction {
fn default() -> Self {
Conviction::None
}
}
impl From<Conviction> for u8 {
fn from(c: Conviction) -> u8 {
match c {
Conviction::None => 0,
Conviction::Locked1x => 1,
Conviction::Locked2x => 2,
Conviction::Locked3x => 3,
Conviction::Locked4x => 4,
Conviction::Locked5x => 5,
Conviction::Locked6x => 6,
}
}
}
impl TryFrom<u8> for Conviction {
type Error = ();
fn try_from(i: u8) -> Result<Conviction, ()> {
Ok(match i {
0 => Conviction::None,
1 => Conviction::Locked1x,
2 => Conviction::Locked2x,
3 => Conviction::Locked3x,
4 => Conviction::Locked4x,
5 => Conviction::Locked5x,
6 => Conviction::Locked6x,
_ => return Err(()),
})
}
}
impl Conviction {
/// The amount of time (in number of periods) that our conviction implies a successful voter's
/// balance should be locked for.
pub fn lock_periods(self) -> u32 {
match self {
Conviction::None => 0,
Conviction::Locked1x => 1,
Conviction::Locked2x => 2,
Conviction::Locked3x => 4,
Conviction::Locked4x => 8,
Conviction::Locked5x => 16,
Conviction::Locked6x => 32,
}
}
/// The votes of a voter of the given `balance` with our conviction.
pub fn votes<
B: From<u8> + Zero + Copy + CheckedMul + CheckedDiv + Bounded
>(self, capital: B) -> Delegations<B> {
let votes = match self {
Conviction::None => capital.checked_div(&10u8.into()).unwrap_or_else(Zero::zero),
x => capital.checked_mul(&u8::from(x).into()).unwrap_or_else(B::max_value),
};
Delegations { votes, capital }
}
}
impl Bounded for Conviction {
fn min_value() -> Self {
Conviction::None
}
fn max_value() -> Self {
Conviction::Locked6x
}
}