cronos_network/instructions/
initialize.rs

1use {
2    crate::state::*,
3    anchor_lang::{
4        prelude::*, 
5        solana_program::{instruction::Instruction, system_program, sysvar}
6    },
7    anchor_spl::token::Mint,
8    std::mem::size_of,
9};
10
11#[derive(Accounts)]
12pub struct Initialize<'info> {
13    #[account(mut)]
14    pub admin: Signer<'info>,
15
16    #[account(
17        init,
18        seeds = [SEED_AUTHORITY],
19        bump,
20        payer = admin,
21        space = 8 + size_of::<Authority>(),
22    )]
23    pub authority: Account<'info, Authority>,
24
25    #[account(address = sysvar::clock::ID)]
26    pub clock: Sysvar<'info, Clock>,
27
28    #[account(
29        init,
30        seeds = [SEED_CONFIG],
31        bump,
32        payer = admin,
33        space = 8 + size_of::<Config>(),
34    )]
35    pub config: Account<'info, Config>,
36    
37    #[account(
38        init,
39        seeds = [SEED_ROTATOR],
40        bump,
41        payer = admin,
42        space = 8 + size_of::<Rotator>(),
43    )]
44    pub rotator: Account<'info, Rotator>,
45
46    #[account()]
47    pub mint: Account<'info, Mint>,
48
49    #[account(
50        init,
51        seeds = [SEED_REGISTRY],
52        bump,
53        payer = admin,
54        space = 8 + size_of::<Registry>(),
55    )]
56    pub registry: Account<'info, Registry>,
57 
58    #[account(address = cronos_scheduler::ID)]
59    pub scheduler_program: Program<'info, cronos_scheduler::program::CronosScheduler>,
60
61    #[account(
62        init,
63        seeds = [
64            SEED_SNAPSHOT, 
65            (0 as u64).to_be_bytes().as_ref()
66        ],
67        bump,
68        payer = admin,
69        space = 8 + size_of::<Snapshot>(),
70    )]
71    pub snapshot: Account<'info, Snapshot>,
72
73    #[account(address = system_program::ID)]
74    pub system_program: Program<'info, System>
75}
76
77pub fn handler<'info>(ctx: Context<'_, '_, '_, 'info, Initialize<'info>>) -> Result<()> {
78    // Get accounts
79    let admin = &ctx.accounts.admin;
80    let authority = &mut ctx.accounts.authority;
81    let clock = &ctx.accounts.clock;
82    let rotator = &mut ctx.accounts.rotator;
83    let config = &mut ctx.accounts.config;
84    let mint = &ctx.accounts.mint;
85    let registry = &mut ctx.accounts.registry;
86    let scheduler_program = &ctx.accounts.scheduler_program;
87    let snapshot = &mut ctx.accounts.snapshot;
88    let system_program = &ctx.accounts.system_program;
89
90    // Get remaining accounts
91    // let rotator_fee = ctx.remaining_accounts.get(0).unwrap();
92    // let rotator_queue = ctx.remaining_accounts.get(1).unwrap();
93    let manager = ctx.remaining_accounts.get(0).unwrap();
94    let snapshot_fee = ctx.remaining_accounts.get(1).unwrap();
95    let snapshot_queue = ctx.remaining_accounts.get(2).unwrap();
96    let snapshot_task = ctx.remaining_accounts.get(3).unwrap();
97
98    // Initialize accounts
99    authority.new(manager.key())?;
100    config.new(admin.key(), mint.key())?;
101    rotator.new()?;
102    registry.new()?;
103    registry.new_snapshot(snapshot)?;
104    registry.rotate_snapshot(clock, None, snapshot)?;
105
106    // Create a manager
107    let bump = *ctx.bumps.get("authority").unwrap();
108    cronos_scheduler::cpi::manager_new(
109        CpiContext::new_with_signer(
110            scheduler_program.to_account_info(), 
111            cronos_scheduler::cpi::accounts::ManagerNew {
112                authority: authority.to_account_info(),
113                manager: manager.to_account_info(),
114                payer: admin.to_account_info(),
115                system_program: system_program.to_account_info(),
116            },
117            &[&[SEED_AUTHORITY, &[bump]]]
118        )
119    )?;
120
121    // Create a queue to take snapshots of the registry
122    cronos_scheduler::cpi::queue_new(
123        CpiContext::new_with_signer(
124            scheduler_program.to_account_info(),
125            cronos_scheduler::cpi::accounts::QueueNew {
126                authority: authority.to_account_info(),
127                clock: clock.to_account_info(),
128                fee: snapshot_fee.to_account_info(),
129                manager: manager.to_account_info(),
130                payer: admin.to_account_info(),
131                queue: snapshot_queue.to_account_info(),
132                system_program: system_program.to_account_info(),
133            },
134            &[&[SEED_AUTHORITY, &[bump]]]
135        ), 
136        "0 * * * * * *".into()
137    )?;
138
139    // TOOD Create a queue to cleanup snapshots and snapshot entries
140    // TODO Return the lamports to the manager account
141
142    // Add an task to the snapshot queue to kick things off
143    let next_snapshot_pubkey = Snapshot::pda(1).0;
144    let snapshot_start_ix = Instruction {
145        program_id: crate::ID,
146        accounts: vec![
147            AccountMeta::new_readonly(authority.key(), false),
148            AccountMeta::new_readonly(config.key(), false),
149            AccountMeta::new_readonly(manager.key(), true),
150            AccountMeta::new(cronos_scheduler::payer::ID, true),
151            AccountMeta::new(registry.key(), false),
152            AccountMeta::new(next_snapshot_pubkey, false),
153            AccountMeta::new_readonly(system_program.key(), false),
154        ],
155        data: cronos_scheduler::anchor::sighash("snapshot_start").into(),
156    };
157    let snapshot_rotate_ix = Instruction {
158        program_id: crate::ID,
159        accounts: vec![
160            AccountMeta::new_readonly(authority.key(), false),
161            AccountMeta::new_readonly(sysvar::clock::ID, false),
162            AccountMeta::new_readonly(config.key(), false),
163            AccountMeta::new(snapshot.key(), false),
164            AccountMeta::new(next_snapshot_pubkey, false),
165            AccountMeta::new_readonly(manager.key(), true),
166            AccountMeta::new(registry.key(), false),
167        ],
168        data: cronos_scheduler::anchor::sighash("snapshot_rotate").into(),
169    };
170    cronos_scheduler::cpi::task_new(
171        CpiContext::new_with_signer(
172            scheduler_program.to_account_info(),
173            cronos_scheduler::cpi::accounts::TaskNew {
174                authority: authority.to_account_info(),
175                manager: manager.to_account_info(),
176                payer: admin.to_account_info(),
177                queue: snapshot_queue.to_account_info(),
178                system_program: system_program.to_account_info(),
179                task: snapshot_task.to_account_info(),
180            },
181            &[&[SEED_AUTHORITY, &[bump]]],
182        ),
183        vec![snapshot_start_ix.into(), snapshot_rotate_ix.into()],
184    )?;
185
186    Ok(())
187}
188