cronos_network/instructions/
node_register.rs

1use {
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(has_one = manager)]
30    // pub rotator_queue: Box<Account<'info, Queue>>,
31
32    #[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    // Get accounts
114    let authority = &ctx.accounts.authority;
115    let config = &ctx.accounts.config;
116    // let rotator_queue = &ctx.accounts.rotator_queue;
117    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    // Get remaining accountsgs
130    // let rotator_task = ctx.remaining_accounts.get(0).unwrap();
131    let snapshot_task = ctx.remaining_accounts.get(0).unwrap();
132    
133    // Get bumps
134    let authority_bump = *ctx.bumps.get("authority").unwrap();
135
136    // Add node to the registry
137    registry.new_node(delegate, owner, node, stake)?;
138
139    // Add an empty entry to the current snapshot
140    snapshot.capture(entry, node, stake)?;
141
142    // Add an task to the rotator queue to check the snapshot entry for this node
143    // let rotator_run_ix = Instruction {
144    //     program_id: crate::ID,
145    //     accounts: vec![
146    //         AccountMeta::new_readonly(authority.key(), false),
147    //         AccountMeta::new(Rotator::pda().0, false),
148    //         AccountMeta::new_readonly(entry.key(), false),
149    //         AccountMeta::new(cronos_pool::state::Pool::pda().0, false),
150    //         AccountMeta::new_readonly(cronos_pool::state::Config::pda().0, false),
151    //         AccountMeta::new_readonly(cronos_pool::ID, false),
152    //         AccountMeta::new_readonly(manager.key(), true),
153    //         AccountMeta::new_readonly(registry.key(), false),
154    //         AccountMeta::new_readonly(snapshot.key(), false),
155    //     ],
156    //     data: cronos_scheduler::anchor::sighash("rotator_run").into(),
157    // };
158    // cronos_scheduler::cpi::task_new(
159    //     CpiContext::new_with_signer(
160    //         scheduler_program.to_account_info(),
161    //         cronos_scheduler::cpi::accounts::TaskNew {
162    //             authority: authority.to_account_info(),
163    //             manager: manager.to_account_info(),
164    //             payer: owner.to_account_info(),
165    //             queue: rotator_queue.to_account_info(),
166    //             system_program: system_program.to_account_info(),
167    //             task: rotator_task.to_account_info(),
168    //         },
169    //         &[&[SEED_AUTHORITY, &[authority_bump]]],
170    //     ),
171    //     vec![rotator_run_ix.into()],
172    // )?;
173
174    // Add an task to the snapshot queue to capture an entry for this node
175    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}