referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_parachains/
reward_points.rs

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//! An implementation of the `RewardValidators` trait used by `inclusion` that employs
18//! `pallet-staking` to compute the rewards.
19//!
20//! Based on <https://research.web3.foundation/en/latest/polkadot/overview/2-token-economics.html>
21//! which doesn't currently mention availability bitfields. As such, we don't reward them
22//! for the time being, although we will build schemes to do so in the future.
23
24use crate::{session_info, shared};
25use alloc::collections::btree_set::BTreeSet;
26use frame_support::traits::{Defensive, RewardsReporter, ValidatorSet};
27use polkadot_primitives::{SessionIndex, ValidatorIndex};
28
29/// The amount of era points given by backing a candidate that is included.
30pub const BACKING_POINTS: u32 = 20;
31/// The amount of era points given by dispute voting on a candidate.
32pub const DISPUTE_STATEMENT_POINTS: u32 = 20;
33
34/// Rewards validators for participating in parachains with era points in pallet-staking.
35pub struct RewardValidatorsWithEraPoints<C, R>(core::marker::PhantomData<(C, R)>);
36
37impl<C, R> RewardValidatorsWithEraPoints<C, R>
38where
39	C: session_info::Config,
40	C::ValidatorSet: ValidatorSet<C::AccountId, ValidatorId = C::AccountId>,
41	R: RewardsReporter<C::AccountId>,
42{
43	/// Reward validators in session with points, but only if they are in the active set.
44	fn reward_only_active(
45		session_index: SessionIndex,
46		indices: impl IntoIterator<Item = ValidatorIndex>,
47		points: u32,
48	) {
49		let validators = session_info::AccountKeys::<C>::get(&session_index);
50		let validators = match validators
51			.defensive_proof("account_keys are present for dispute_period sessions")
52		{
53			Some(validators) => validators,
54			None => return,
55		};
56		// limit rewards to the active validator set
57		let active_set: BTreeSet<_> = C::ValidatorSet::validators().into_iter().collect();
58
59		let rewards = indices
60			.into_iter()
61			.filter_map(|i| validators.get(i.0 as usize).cloned())
62			.filter(|v| active_set.contains(v))
63			.map(|v| (v, points));
64
65		R::reward_by_ids(rewards);
66	}
67}
68
69impl<C, R> crate::inclusion::RewardValidators for RewardValidatorsWithEraPoints<C, R>
70where
71	C: shared::Config + session_info::Config,
72	C::ValidatorSet: ValidatorSet<C::AccountId, ValidatorId = C::AccountId>,
73	R: RewardsReporter<C::AccountId>,
74{
75	fn reward_backing(indices: impl IntoIterator<Item = ValidatorIndex>) {
76		let session_index = shared::CurrentSessionIndex::<C>::get();
77		Self::reward_only_active(session_index, indices, BACKING_POINTS);
78	}
79
80	fn reward_bitfields(_validators: impl IntoIterator<Item = ValidatorIndex>) {}
81}
82
83impl<C, R> crate::disputes::RewardValidators for RewardValidatorsWithEraPoints<C, R>
84where
85	C: session_info::Config,
86	C::ValidatorSet: ValidatorSet<C::AccountId, ValidatorId = C::AccountId>,
87	R: RewardsReporter<C::AccountId>,
88{
89	fn reward_dispute_statement(
90		session: SessionIndex,
91		validators: impl IntoIterator<Item = ValidatorIndex>,
92	) {
93		Self::reward_only_active(session, validators, DISPUTE_STATEMENT_POINTS);
94	}
95}