clockwork_network/instructions/
snapshot_close.rs

1use {
2    crate::state::*,
3    anchor_lang::{prelude::*, solana_program::instruction::Instruction},
4    clockwork_crank::state::{CrankResponse, Queue, SEED_QUEUE},
5};
6
7#[derive(Accounts)]
8pub struct SnapshotClose<'info> {
9    #[account(seeds = [SEED_AUTHORITY], bump)]
10    pub authority: Account<'info, Authority>,
11
12    #[account(
13        mut,
14        seeds = [
15            SEED_SNAPSHOT,
16            snapshot.id.to_be_bytes().as_ref(),
17        ],
18        bump,
19        constraint = snapshot.status == SnapshotStatus::Archived
20    )]
21    pub snapshot: Account<'info, Snapshot>,
22
23    #[account(
24        signer, 
25        seeds = [
26            SEED_QUEUE, 
27            authority.key().as_ref(), 
28            "snapshot".as_bytes()
29        ], 
30        seeds::program = clockwork_crank::ID,
31        bump,
32        has_one = authority
33    )]
34    pub snapshot_queue: Account<'info, Queue>,
35}
36
37pub fn handler(ctx: Context<SnapshotClose>) -> Result<CrankResponse> {
38    // Get accounts
39    let authority = &ctx.accounts.authority;
40    let snapshot = &mut ctx.accounts.snapshot;
41    let snapshot_queue = &mut ctx.accounts.snapshot_queue;
42
43    // If this snapshot has no entries, then close immediately
44    if snapshot.node_count == 0 {
45        let snapshot_lamports = snapshot.to_account_info().lamports();
46        **snapshot.to_account_info().lamports.borrow_mut() = 0;
47        **snapshot_queue.to_account_info().lamports.borrow_mut() = snapshot_queue
48            .to_account_info()
49            .lamports()
50            .checked_add(snapshot_lamports)
51            .unwrap();
52    } else {
53        // Otherwise, set the status to closing
54        snapshot.status = SnapshotStatus::Closing;
55    }
56
57    // If there are entries to capture, build the next instruction
58    let next_instruction = if snapshot.node_count > 0 {
59        let entry_pubkey = SnapshotEntry::pubkey(snapshot.key(), 0);
60        Some(
61            Instruction {
62                program_id: crate::ID,
63                accounts: vec![
64                    AccountMeta::new_readonly(authority.key(), false),
65                    AccountMeta::new(entry_pubkey, false),
66                    AccountMeta::new(snapshot.key(), false),
67                    AccountMeta::new(snapshot_queue.key(), true),
68                ],
69                data: clockwork_crank::anchor::sighash("entry_close").into(),
70            }.into()
71        )
72    } else {
73        None
74    };
75
76    Ok(CrankResponse { next_instruction })
77}