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