pallet_conviction_voting/traits.rs
1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.use crate::AccountVote;
17
18//! Traits for conviction voting.
19
20use crate::AccountVote;
21use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
22use frame_support::dispatch::DispatchResult;
23use scale_info::TypeInfo;
24use sp_runtime::RuntimeDebug;
25
26/// Represents the differents states of a referendum.
27#[derive(
28 Encode,
29 Decode,
30 DecodeWithMemTracking,
31 Copy,
32 Clone,
33 Eq,
34 PartialEq,
35 RuntimeDebug,
36 TypeInfo,
37 MaxEncodedLen,
38)]
39pub enum Status {
40 /// The referendum is not started.
41 None,
42 /// The referendum is ongoing.
43 Ongoing,
44 /// The referendum is finished.
45 Completed,
46}
47
48/// Trait for voting hooks that are called during various stages of the voting process.
49///
50/// # Important Note
51/// These hooks are called BEFORE the actual vote is recorded in storage. This means:
52/// - If `on_vote` returns an error, the entire voting operation will be reverted
53/// - If `on_vote` succeeds but the voting operation fails later, any storage modifications made by
54/// `on_vote` will still persist
55///
56/// # Hook Methods
57/// - `on_vote`: Called before a vote is recorded. Returns `Err` to prevent the vote from being
58/// recorded. Storage modifications made by this hook will persist even if the vote fails later.
59///
60/// - `on_remove_vote`: Called before a vote is removed. Cannot fail.
61/// - `lock_balance_on_unsuccessful_vote`: Called when a vote fails to be recorded (e.g. due to
62/// insufficient balance). Returns optionally locked balance amount.
63///
64/// # Benchmarking Hooks
65/// The following methods are only used during runtime benchmarking:
66/// - `on_vote_worst_case`: Sets up worst-case state for `on_vote` benchmarking
67/// - `on_remove_vote_worst_case`: Sets up worst-case state for `on_remove_vote` benchmarking
68///
69/// # Generic Parameters
70/// - `AccountId`: The type used to identify accounts in the system
71/// - `Index`: The type used for referendum indices
72/// - `Balance`: The type used for balance values
73pub trait VotingHooks<AccountId, Index, Balance> {
74 // Called before a vote is recorded.
75 // Returns `Err` to prevent the vote from being recorded.
76 fn on_before_vote(
77 who: &AccountId,
78 ref_index: Index,
79 vote: AccountVote<Balance>,
80 ) -> DispatchResult;
81
82 // Called when removed vote is executed.
83 fn on_remove_vote(who: &AccountId, ref_index: Index, status: Status);
84
85 // Called when a vote is unsuccessful.
86 // Returns the amount of locked balance, which is `None` in the default implementation.
87 fn lock_balance_on_unsuccessful_vote(who: &AccountId, ref_index: Index) -> Option<Balance>;
88
89 /// Will be called by benchmarking before calling `on_vote` in a benchmark.
90 ///
91 /// Should setup the state in such a way that when `on_vote` is called it will
92 /// take the worst case path performance wise.
93 #[cfg(feature = "runtime-benchmarks")]
94 fn on_vote_worst_case(who: &AccountId);
95
96 /// Will be called by benchmarking before calling `on_remove_vote` in a benchmark.
97 ///
98 /// Should setup the state in such a way that when `on_remove_vote` is called it will
99 /// take the worst case path performance wise.
100 #[cfg(feature = "runtime-benchmarks")]
101 fn on_remove_vote_worst_case(who: &AccountId);
102}
103
104// Default implementation for VotingHooks
105impl<A, I, B> VotingHooks<A, I, B> for () {
106 fn on_before_vote(_who: &A, _ref_index: I, _vote: AccountVote<B>) -> DispatchResult {
107 Ok(())
108 }
109
110 fn on_remove_vote(_who: &A, _ref_index: I, _status: Status) {}
111
112 fn lock_balance_on_unsuccessful_vote(_who: &A, _ref_index: I) -> Option<B> {
113 None
114 }
115
116 #[cfg(feature = "runtime-benchmarks")]
117 fn on_vote_worst_case(_who: &A) {}
118
119 #[cfg(feature = "runtime-benchmarks")]
120 fn on_remove_vote_worst_case(_who: &A) {}
121}