pallet_moonbeam_orbiters/
types.rs1use scale_info::TypeInfo;
18use sp_runtime::{
19 codec::{Decode, Encode},
20 RuntimeDebug,
21};
22use sp_std::vec::Vec;
23
24#[derive(Decode, Encode, RuntimeDebug, TypeInfo)]
25pub struct CurrentOrbiter<AccountId> {
26 pub account_id: AccountId,
27 pub removed: bool,
28}
29impl<AccountId: Clone> Clone for CurrentOrbiter<AccountId> {
30 fn clone(&self) -> Self {
31 Self {
32 account_id: self.account_id.clone(),
33 removed: self.removed,
34 }
35 }
36}
37
38pub(super) enum RemoveOrbiterResult {
39 OrbiterNotFound,
40 OrbiterRemoved,
41 OrbiterRemoveScheduled,
42}
43
44#[derive(Decode, Encode, RuntimeDebug, TypeInfo)]
45pub(super) struct RotateOrbiterResult<AccountId> {
46 pub maybe_old_orbiter: Option<CurrentOrbiter<AccountId>>,
47 pub maybe_next_orbiter: Option<AccountId>,
48}
49
50#[derive(Decode, Encode, RuntimeDebug, TypeInfo)]
51pub struct CollatorPoolInfo<AccountId> {
52 orbiters: Vec<AccountId>,
53 maybe_current_orbiter: Option<CurrentOrbiter<AccountId>>,
54 next_orbiter: u32,
55}
56
57impl<AccountId> Default for CollatorPoolInfo<AccountId> {
58 fn default() -> Self {
59 Self {
60 orbiters: Vec::new(),
61 maybe_current_orbiter: None,
62 next_orbiter: 0,
63 }
64 }
65}
66
67impl<AccountId: Clone + PartialEq> CollatorPoolInfo<AccountId> {
68 pub(super) fn add_orbiter(&mut self, orbiter: AccountId) {
69 if self.next_orbiter > self.orbiters.len() as u32 {
70 self.next_orbiter = 0;
71 }
72 self.orbiters.insert(self.next_orbiter as usize, orbiter);
73 self.next_orbiter += 1;
74 }
75 pub(super) fn contains_orbiter(&self, orbiter: &AccountId) -> bool {
76 if let Some(CurrentOrbiter { ref account_id, .. }) = self.maybe_current_orbiter {
77 if account_id == orbiter {
78 return true;
79 }
80 }
81 for orbiter_ in self.orbiters.iter() {
82 if orbiter_ == orbiter {
83 return true;
84 }
85 }
86 false
87 }
88 pub(super) fn get_orbiters(&self) -> &[AccountId] {
89 &self.orbiters
90 }
91 pub(super) fn remove_orbiter(&mut self, orbiter: &AccountId) -> RemoveOrbiterResult {
92 let mut found = false;
93 for (index, orbiter_) in self.orbiters.iter().enumerate() {
94 if orbiter_ == orbiter {
95 self.orbiters.remove(index);
96 found = true;
97 break;
98 }
99 }
100
101 if found {
102 if let Some(CurrentOrbiter {
103 account_id: ref current_orbiter,
104 ref mut removed,
105 }) = self.maybe_current_orbiter
106 {
107 if current_orbiter == orbiter {
108 *removed = true;
109 return RemoveOrbiterResult::OrbiterRemoveScheduled;
110 }
111 }
112 RemoveOrbiterResult::OrbiterRemoved
113 } else {
114 RemoveOrbiterResult::OrbiterNotFound
115 }
116 }
117 pub(super) fn rotate_orbiter(&mut self) -> RotateOrbiterResult<AccountId> {
118 let maybe_old_orbiter = self.maybe_current_orbiter.clone();
119 if self.next_orbiter >= self.orbiters.len() as u32 {
120 self.next_orbiter = 0;
121 }
122 let maybe_next_orbiter =
123 if let Some(next_orbiter) = self.orbiters.get(self.next_orbiter as usize) {
124 self.maybe_current_orbiter = Some(CurrentOrbiter {
125 account_id: next_orbiter.clone(),
126 removed: false,
127 });
128 self.next_orbiter += 1;
129 Some(next_orbiter.clone())
130 } else {
131 None
132 };
133
134 RotateOrbiterResult {
135 maybe_old_orbiter,
136 maybe_next_orbiter,
137 }
138 }
139}
140
141#[derive(Decode, Encode, RuntimeDebug, TypeInfo)]
142pub struct RoundAuthors<AccountId> {
143 data: Vec<(AccountId, u32)>,
144 blocks_count: u32,
145}
146
147impl<AccountId> Default for RoundAuthors<AccountId> {
148 fn default() -> Self {
149 Self {
150 data: Vec::new(),
151 blocks_count: 0,
152 }
153 }
154}
155
156impl<AccountId: Ord> RoundAuthors<AccountId> {
157 pub fn add_author(&mut self, author: AccountId) {
158 match self
159 .data
160 .binary_search_by(|(account, _counter)| account.cmp(&author))
161 {
162 Ok(index) => self.data[index].1 = self.data[index].1.saturating_add(1),
163 Err(index) => self.data.insert(index, (author, 1)),
164 };
165 self.blocks_count += 1;
166 }
167 pub fn into_data(self) -> (Vec<(AccountId, u32)>, u32) {
168 let Self { data, blocks_count } = self;
169 (data, blocks_count)
170 }
171}