light_registry/protocol_config/
state.rs1use aligned_sized::aligned_sized;
2use anchor_lang::prelude::*;
3
4use crate::errors::RegistryError;
5
6#[aligned_sized(anchor)]
7#[derive(Debug)]
8#[account]
9pub struct ProtocolConfigPda {
10 pub authority: Pubkey,
11 pub bump: u8,
12 pub config: ProtocolConfig,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, AnchorSerialize, AnchorDeserialize)]
23pub struct ProtocolConfig {
24 pub genesis_slot: u64,
26 pub min_weight: u64,
28 pub slot_length: u64,
30 pub registration_phase_length: u64,
32 pub active_phase_length: u64,
34 pub report_work_phase_length: u64,
37 pub network_fee: u64,
38 pub cpi_context_size: u64,
39 pub finalize_counter_limit: u64,
40 pub place_holder: Pubkey,
42 pub place_holder_a: u64,
43 pub place_holder_b: u64,
44 pub place_holder_c: u64,
45 pub place_holder_d: u64,
46 pub place_holder_e: u64,
47 pub place_holder_f: u64,
48}
49
50impl Default for ProtocolConfig {
51 fn default() -> Self {
52 Self {
53 genesis_slot: 0,
54 min_weight: 1,
55 slot_length: 10,
56 registration_phase_length: 100,
57 active_phase_length: 1000,
58 report_work_phase_length: 100,
59 network_fee: 5000,
60 cpi_context_size: 20 * 1024 + 8,
61 finalize_counter_limit: 100,
62 place_holder: Pubkey::default(),
63 place_holder_a: 0,
64 place_holder_b: 0,
65 place_holder_c: 0,
66 place_holder_d: 0,
67 place_holder_e: 0,
68 place_holder_f: 0,
69 }
70 }
71}
72
73impl ProtocolConfig {
74 pub fn testnet_default() -> Self {
75 Self {
76 genesis_slot: 0,
77 min_weight: 1,
78 slot_length: 60,
79 registration_phase_length: 100,
80 active_phase_length: 1000,
81 report_work_phase_length: 100,
82 network_fee: 5000,
83 cpi_context_size: 20 * 1024 + 8,
84 finalize_counter_limit: 100,
85 place_holder: Pubkey::default(),
86 place_holder_a: 0,
87 place_holder_b: 0,
88 place_holder_c: 0,
89 place_holder_d: 0,
90 place_holder_e: 0,
91 place_holder_f: 0,
92 }
93 }
94}
95
96#[derive(Debug, Default, Clone, PartialEq, Eq)]
97pub enum EpochState {
98 Registration,
99 Active,
100 ReportWork,
101 Post,
102 #[default]
103 Pre,
104}
105
106impl ProtocolConfig {
152 pub fn get_latest_register_epoch(&self, slot: u64) -> Result<u64> {
154 let slot = slot
155 .checked_sub(self.genesis_slot)
156 .ok_or(RegistryError::GetLatestRegisterEpochFailed)?;
157 Ok(slot / self.active_phase_length)
158 }
159
160 pub fn get_current_epoch(&self, slot: u64) -> u64 {
161 (slot.saturating_sub(self.genesis_slot)) / self.active_phase_length
162 }
163
164 pub fn get_current_active_epoch(&self, slot: u64) -> Result<u64> {
165 let slot = slot
166 .checked_sub(self.genesis_slot + self.registration_phase_length)
167 .ok_or(RegistryError::GetCurrentActiveEpochFailed)?;
168 Ok(slot / self.active_phase_length)
169 }
170
171 pub fn get_latest_register_epoch_progress(&self, slot: u64) -> Result<u64> {
172 Ok(slot
173 .checked_sub(self.genesis_slot)
174 .ok_or(RegistryError::ArithmeticUnderflow)?
175 % self.active_phase_length)
176 }
177
178 pub fn get_current_active_epoch_progress(&self, slot: u64) -> u64 {
179 (slot
180 .checked_sub(self.genesis_slot + self.registration_phase_length)
181 .unwrap())
182 % self.active_phase_length
183 }
184
185 pub fn is_registration_phase(&self, slot: u64) -> Result<u64> {
188 let latest_register_epoch = self.get_latest_register_epoch(slot)?;
189 let latest_register_epoch_progress = self.get_latest_register_epoch_progress(slot)?;
190 if latest_register_epoch_progress >= self.registration_phase_length {
191 return err!(RegistryError::NotInRegistrationPeriod);
192 }
193 Ok((latest_register_epoch) * self.active_phase_length
194 + self.genesis_slot
195 + self.registration_phase_length)
196 }
197
198 pub fn is_active_phase(&self, slot: u64, epoch: u64) -> Result<()> {
199 if self.get_current_active_epoch(slot)? != epoch {
200 return err!(RegistryError::NotInActivePhase);
201 }
202 Ok(())
203 }
204
205 pub fn is_report_work_phase(&self, slot: u64, epoch: u64) -> Result<()> {
206 self.is_active_phase(slot, epoch + 1)?;
207 let current_epoch_progress = self.get_current_active_epoch_progress(slot);
208 if current_epoch_progress >= self.report_work_phase_length {
209 return err!(RegistryError::NotInReportWorkPhase);
210 }
211 Ok(())
212 }
213
214 pub fn is_post_epoch(&self, slot: u64, epoch: u64) -> Result<()> {
215 if self.get_current_active_epoch(slot)? <= epoch {
216 return err!(RegistryError::InvalidEpoch);
217 }
218 Ok(())
219 }
220}