1
// Copyright (C) Parity Technologies (UK) Ltd.
2
// This file is part of Polkadot.
3

            
4
// Polkadot is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Polkadot is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! Track configurations for governance.
18

            
19
use super::*;
20
use sp_runtime::str_array as s;
21
const fn percent(x: u128) -> sp_arithmetic::FixedI64 {
22
    sp_arithmetic::FixedI64::from_rational(x, 100)
23
}
24
use pallet_referenda::Curve;
25

            
26
const APP_ROOT: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
27
const SUP_ROOT: Curve = Curve::make_linear(28, 28, percent(20), percent(50));
28
const APP_WHITELISTED: Curve =
29
    Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100));
30
const SUP_WHITELISTED: Curve =
31
    Curve::make_reciprocal(1, 14 * 24, percent(1), percent(0), percent(2));
32

            
33
const TRACKS_DATA: [pallet_referenda::Track<u16, Balance, BlockNumber>; 2] = [
34
    pallet_referenda::Track {
35
        id: 0,
36
        info: pallet_referenda::TrackInfo {
37
            name: s("root"),
38
            max_deciding: 1,
39
            decision_deposit: 500 * GRAND,
40
            prepare_period: 8 * MINUTES,
41
            decision_period: 20 * MINUTES,
42
            confirm_period: 12 * MINUTES,
43
            min_enactment_period: 5 * MINUTES,
44
            min_approval: APP_ROOT,
45
            min_support: SUP_ROOT,
46
        },
47
    },
48
    pallet_referenda::Track {
49
        id: 1,
50
        info: pallet_referenda::TrackInfo {
51
            name: s("whitelisted_caller"),
52
            max_deciding: 100,
53
            decision_deposit: 500 * GRAND,
54
            prepare_period: 10 * MINUTES,
55
            decision_period: 14 * DAYS,
56
            confirm_period: 10 * MINUTES,
57
            min_enactment_period: 30 * MINUTES,
58
            min_approval: APP_WHITELISTED,
59
            min_support: SUP_WHITELISTED,
60
        },
61
    },
62
];
63

            
64
pub struct TracksInfo;
65
impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
66
    type Id = u16;
67
    type RuntimeOrigin = <RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin;
68
1
    fn tracks(
69
1
    ) -> impl Iterator<Item = Cow<'static, pallet_referenda::Track<Self::Id, Balance, BlockNumber>>>
70
    {
71
1
        TRACKS_DATA.iter().map(Cow::Borrowed)
72
1
    }
73
    fn track_for(id: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
74
        if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) {
75
            match system_origin {
76
                frame_system::RawOrigin::Root => Ok(0),
77
                _ => Err(()),
78
            }
79
        } else if let Ok(custom_origin) = pallet_custom_origins::Origin::try_from(id.clone()) {
80
            match custom_origin {
81
                origins::Origin::WhitelistedCaller => Ok(1),
82
                _ => Err(()),
83
            }
84
        } else {
85
            Err(())
86
        }
87
    }
88
}
89

            
90
#[test]
91
/// To ensure voters are always locked into their vote
92
1
fn vote_locking_always_longer_than_enactment_period() {
93
    use core::str::from_utf8;
94
3
    for track in TRACKS_DATA {
95
2
        assert!(
96
2
            <Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get()
97
2
                >= track.info.min_enactment_period,
98
            "Track {} has enactment period {} < vote locking period {}",
99
            from_utf8(&track.info.name).expect("Track name is valid UTF-8"),
100
            track.info.min_enactment_period,
101
            <Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get(),
102
        );
103
    }
104
1
}