cronos_network/instructions/
node_register.rs1use {
2 crate::state::*,
3 anchor_lang::{
4 prelude::*,
5 solana_program::{instruction::Instruction, system_program, sysvar},
6 },
7 anchor_spl::{
8 associated_token::AssociatedToken,
9 token::{Mint, Token, TokenAccount},
10 },
11 cronos_scheduler::{
12 program::CronosScheduler,
13 state::{Queue, Manager}
14 },
15 std::mem::size_of,
16};
17
18#[derive(Accounts)]
19pub struct NodeRegister<'info> {
20 #[account(address = anchor_spl::associated_token::ID)]
21 pub associated_token_program: Program<'info, AssociatedToken>,
22
23 #[account(seeds = [SEED_AUTHORITY], bump, has_one = manager)]
24 pub authority: Box<Account<'info, Authority>>,
25
26 #[account(seeds = [SEED_CONFIG], bump)]
27 pub config: Box<Account<'info, Config>>,
28
29 #[account()]
33 pub delegate: Signer<'info>,
34
35 #[account(
36 init,
37 seeds = [
38 SEED_SNAPSHOT_ENTRY,
39 snapshot.key().as_ref(),
40 snapshot.node_count.to_be_bytes().as_ref(),
41 ],
42 bump,
43 payer = owner,
44 space = 8 + size_of::<SnapshotEntry>(),
45 )]
46 pub entry: Account<'info, SnapshotEntry>,
47
48 #[account(constraint = manager.authority == authority.key())]
49 pub manager: Box<Account<'info, Manager>>,
50
51 #[account(address = config.mint)]
52 pub mint: Box<Account<'info, Mint>>,
53
54 #[account(
55 init,
56 seeds = [
57 SEED_NODE,
58 delegate.key().as_ref()
59 ],
60 bump,
61 payer = owner,
62 space = 8 + size_of::<Node>(),
63 )]
64 pub node: Account<'info, Node>,
65
66 #[account(mut, constraint = owner.key() != delegate.key())]
67 pub owner: Signer<'info>,
68
69 #[account(
70 mut,
71 seeds = [SEED_REGISTRY],
72 bump,
73 constraint = !registry.is_locked
74 )]
75 pub registry: Account<'info, Registry>,
76
77 #[account(address = sysvar::rent::ID)]
78 pub rent: Sysvar<'info, Rent>,
79
80 #[account(address = cronos_scheduler::ID)]
81 pub scheduler_program: Program<'info, CronosScheduler>,
82
83 #[account(
84 mut,
85 seeds = [
86 SEED_SNAPSHOT,
87 snapshot.id.to_be_bytes().as_ref(),
88 ],
89 bump,
90 constraint = snapshot.status == SnapshotStatus::Current
91 )]
92 pub snapshot: Account<'info, Snapshot>,
93
94 #[account(has_one = manager)]
95 pub snapshot_queue: Box<Account<'info, Queue>>,
96
97 #[account(
98 init,
99 payer = owner,
100 associated_token::authority = node,
101 associated_token::mint = mint,
102 )]
103 pub stake: Account<'info, TokenAccount>,
104
105 #[account(address = system_program::ID)]
106 pub system_program: Program<'info, System>,
107
108 #[account(address = anchor_spl::token::ID)]
109 pub token_program: Program<'info, Token>,
110}
111
112pub fn handler<'info>(ctx: Context<'_, '_, '_, 'info, NodeRegister<'info>>) -> Result<()> {
113 let authority = &ctx.accounts.authority;
115 let config = &ctx.accounts.config;
116 let delegate = &ctx.accounts.delegate;
118 let entry = &mut ctx.accounts.entry;
119 let manager = &ctx.accounts.manager;
120 let node = &mut ctx.accounts.node;
121 let owner = &mut ctx.accounts.owner;
122 let registry = &mut ctx.accounts.registry;
123 let scheduler_program = &ctx.accounts.scheduler_program;
124 let snapshot = &mut ctx.accounts.snapshot;
125 let snapshot_queue = &ctx.accounts.snapshot_queue;
126 let system_program = &ctx.accounts.system_program;
127 let stake = &mut ctx.accounts.stake;
128
129 let snapshot_task = ctx.remaining_accounts.get(0).unwrap();
132
133 let authority_bump = *ctx.bumps.get("authority").unwrap();
135
136 registry.new_node(delegate, owner, node, stake)?;
138
139 snapshot.capture(entry, node, stake)?;
141
142 let current_snapshot_pubkey = Snapshot::pda(registry.snapshot_count.checked_sub(1).unwrap()).0;
176 let next_snapshot_pubkey = Snapshot::pda(registry.snapshot_count).0;
177 let next_entry_pubkey = SnapshotEntry::pda(next_snapshot_pubkey, node.id).0;
178 let stake_pubkey = stake.key();
179 let snapshot_capture_ix = Instruction {
180 program_id: crate::ID,
181 accounts: vec![
182 AccountMeta::new_readonly(authority.key(), false),
183 AccountMeta::new_readonly(config.key(), false),
184 AccountMeta::new(next_entry_pubkey, false),
185 AccountMeta::new_readonly(node.key(), false,),
186 AccountMeta::new(cronos_scheduler::payer::ID, true),
187 AccountMeta::new_readonly(manager.key(), true),
188 AccountMeta::new_readonly(registry.key(), false),
189 AccountMeta::new(next_snapshot_pubkey, false),
190 AccountMeta::new_readonly(stake_pubkey, false),
191 AccountMeta::new_readonly(system_program.key(), false)
192 ],
193 data: cronos_scheduler::anchor::sighash("snapshot_capture").into(),
194 };
195 let snapshot_rotate_ix = Instruction {
196 program_id: crate::ID,
197 accounts: vec![
198 AccountMeta::new_readonly(authority.key(), false),
199 AccountMeta::new_readonly(sysvar::clock::ID, false),
200 AccountMeta::new_readonly(config.key(), false),
201 AccountMeta::new(current_snapshot_pubkey, false),
202 AccountMeta::new(next_snapshot_pubkey, false),
203 AccountMeta::new_readonly(manager.key(), true),
204 AccountMeta::new(registry.key(), false),
205 ],
206 data: cronos_scheduler::anchor::sighash("snapshot_rotate").into(),
207 };
208 cronos_scheduler::cpi::task_new(
209 CpiContext::new_with_signer(
210 scheduler_program.to_account_info(),
211 cronos_scheduler::cpi::accounts::TaskNew {
212 authority: authority.to_account_info(),
213 manager: manager.to_account_info(),
214 payer: owner.to_account_info(),
215 queue: snapshot_queue.to_account_info(),
216 system_program: system_program.to_account_info(),
217 task: snapshot_task.to_account_info(),
218 },
219 &[&[SEED_AUTHORITY, &[authority_bump]]],
220 ),
221 vec![snapshot_capture_ix.into(), snapshot_rotate_ix.into()],
222 )?;
223
224 Ok(())
225}