cronos_network/state/
registry.rs1use anchor_spl::token::TokenAccount;
2
3use {
4 super::{Node, Snapshot},
5 crate::{
6 errors::CronosError,
7 pda::PDA,
8 state::{NodeAccount, SnapshotAccount, SnapshotStatus},
9 },
10 anchor_lang::{prelude::*, AnchorDeserialize},
11 std::convert::TryFrom,
12};
13
14pub const SEED_REGISTRY: &[u8] = b"registry";
15
16#[account]
21#[derive(Debug)]
22pub struct Registry {
23 pub is_locked: bool,
24 pub node_count: u64,
25 pub snapshot_count: u64,
26}
27
28impl Registry {
29 pub fn pda() -> PDA {
30 Pubkey::find_program_address(&[SEED_REGISTRY], &crate::ID)
31 }
32}
33
34impl TryFrom<Vec<u8>> for Registry {
35 type Error = Error;
36 fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
37 Registry::try_deserialize(&mut data.as_slice())
38 }
39}
40
41pub trait RegistryAccount {
46 fn new(&mut self) -> Result<()>;
47
48 fn new_node(
49 &mut self,
50 delegate: &Signer,
51 owner: &mut Signer,
52 node: &mut Account<Node>,
53 stake: &mut Account<TokenAccount>,
54 ) -> Result<()>;
55
56 fn new_snapshot(&mut self, snapshot: &mut Account<Snapshot>) -> Result<()>;
57
58 fn rotate_snapshot(
59 &mut self,
60 clock: &Sysvar<Clock>,
61 current_snapshot: Option<&mut Account<Snapshot>>,
62 next_snapshot: &mut Account<Snapshot>,
63 ) -> Result<()>;
64
65 fn lock(&mut self) -> Result<()>;
66
67 fn unlock(&mut self) -> Result<()>;
68}
69
70impl RegistryAccount for Account<'_, Registry> {
71 fn new(&mut self) -> Result<()> {
72 self.is_locked = false;
73 self.node_count = 0;
74 self.snapshot_count = 0;
75 Ok(())
76 }
77
78 fn new_node(
79 &mut self,
80 delegate: &Signer,
81 owner: &mut Signer,
82 node: &mut Account<Node>,
83 stake: &mut Account<TokenAccount>,
84 ) -> Result<()> {
85 require!(!self.is_locked, CronosError::RegistryLocked);
86 node.new(delegate, self.node_count, owner, stake)?;
87 self.node_count = self.node_count.checked_add(1).unwrap();
88 Ok(())
89 }
90
91 fn new_snapshot(&mut self, snapshot: &mut Account<Snapshot>) -> Result<()> {
92 require!(!self.is_locked, CronosError::RegistryLocked);
93 self.lock()?;
94 snapshot.new(self.snapshot_count)?;
95 Ok(())
96 }
97
98 fn rotate_snapshot(
99 &mut self,
100 clock: &Sysvar<Clock>,
101 current_snapshot: Option<&mut Account<Snapshot>>,
102 next_snapshot: &mut Account<Snapshot>,
103 ) -> Result<()> {
104 require!(self.is_locked, CronosError::RegistryMustBeLocked);
106
107 require!(
109 next_snapshot.status == SnapshotStatus::InProgress,
110 CronosError::SnapshotNotInProgress
111 );
112
113 require!(
115 next_snapshot.node_count == self.node_count,
116 CronosError::SnapshotIncomplete
117 );
118
119 match current_snapshot {
121 Some(current_snapshot) => {
122 require!(
124 current_snapshot.status == SnapshotStatus::Current,
125 CronosError::SnapshotNotCurrent
126 );
127
128 current_snapshot.status = SnapshotStatus::Archived {
130 ts: clock.unix_timestamp,
131 };
132 }
133 None => require!(self.snapshot_count == 0, CronosError::SnapshotNotCurrent),
134 }
135
136 next_snapshot.status = SnapshotStatus::Current;
138
139 self.snapshot_count = self.snapshot_count.checked_add(1).unwrap();
141
142 self.unlock()?;
144
145 Ok(())
146 }
147
148 fn lock(&mut self) -> Result<()> {
149 self.is_locked = true;
150 Ok(())
151 }
152
153 fn unlock(&mut self) -> Result<()> {
154 self.is_locked = false;
155 Ok(())
156 }
157}