miclockwork_network_program/jobs/delete_snapshot/
process_entry.rs

1use anchor_lang::{prelude::*, InstructionData, solana_program::instruction::Instruction};
2use miclockwork_utils::thread::ThreadResponse;
3
4use crate::state::*;
5
6#[derive(Accounts)]
7pub struct DeleteSnapshotProcessEntry<'info> {
8    #[account(address = Config::pubkey())]
9    pub config: Account<'info, Config>,
10
11    #[account(
12        address = Registry::pubkey(),
13        constraint = !registry.locked
14    )]
15    pub registry: Account<'info, Registry>,
16
17    #[account(
18        mut,
19        seeds = [
20            SEED_SNAPSHOT,
21            snapshot.id.to_be_bytes().as_ref(),
22        ],
23        bump,
24        constraint = snapshot.id.lt(&registry.current_epoch)
25    )]
26    pub snapshot: Account<'info, Snapshot>,
27
28    #[account(
29        mut,
30        seeds = [
31            SEED_SNAPSHOT_ENTRY,
32            snapshot_entry.snapshot_frame.as_ref(),
33            snapshot_entry.id.to_be_bytes().as_ref(),
34        ],
35        bump,
36        has_one = snapshot_frame
37    )]
38    pub snapshot_entry: Account<'info, SnapshotEntry>,
39
40    #[account(
41        mut,
42        seeds = [
43            SEED_SNAPSHOT_FRAME,
44            snapshot_frame.snapshot.as_ref(),
45            snapshot_frame.id.to_be_bytes().as_ref(),
46        ],
47        bump,
48        has_one = snapshot,
49    )]
50    pub snapshot_frame: Account<'info, SnapshotFrame>,
51
52    #[account(
53        mut, 
54        address = config.epoch_thread
55    )]
56    pub thread: Signer<'info>,
57}
58
59pub fn handler(ctx: Context<DeleteSnapshotProcessEntry>) -> Result<ThreadResponse> {
60    // Get accounts
61    let config = &ctx.accounts.config;
62    let registry = &ctx.accounts.registry;
63    let snapshot = &mut ctx.accounts.snapshot;
64    let snapshot_entry = &mut ctx.accounts.snapshot_entry;
65    let snapshot_frame = &mut ctx.accounts.snapshot_frame;
66    let thread = &mut ctx.accounts.thread;
67
68    // Close the snapshot entry account.
69    let snapshot_entry_lamports = snapshot_entry.to_account_info().lamports();
70    **snapshot_entry.to_account_info().lamports.borrow_mut() = 0;
71    **thread.to_account_info().lamports.borrow_mut() = thread
72        .to_account_info()
73        .lamports()
74        .checked_add(snapshot_entry_lamports)
75        .unwrap();
76
77    // If this frame has no more entries, then close the frame account.
78    if snapshot_entry.id.checked_add(1).unwrap().eq(&snapshot_frame.total_entries) {
79        let snapshot_frame_lamports = snapshot_frame.to_account_info().lamports();
80        **snapshot_frame.to_account_info().lamports.borrow_mut() = 0;
81        **thread.to_account_info().lamports.borrow_mut() = thread
82            .to_account_info()
83            .lamports()
84            .checked_add(snapshot_frame_lamports)
85            .unwrap();
86
87
88        // If this is also the last frame in the snapshot, then close the snapshot account.
89        if snapshot_frame.id.checked_add(1).unwrap().eq(&snapshot.total_frames) {
90            let snapshot_lamports = snapshot.to_account_info().lamports();
91            **snapshot.to_account_info().lamports.borrow_mut() = 0;
92            **thread.to_account_info().lamports.borrow_mut() = thread
93                .to_account_info()
94                .lamports()
95                .checked_add(snapshot_lamports)
96                .unwrap();
97        }
98    }
99
100    // Build the next instruction
101    let dynamic_instruction = if snapshot_entry.id.checked_add(1).unwrap().lt(&snapshot_frame.total_entries) {
102        // Move on to the next entry.
103        Some (
104            Instruction {
105                program_id: crate::ID,
106                accounts: crate::accounts::DeleteSnapshotProcessEntry {
107                    config:config.key(),
108                    registry:registry.key(),
109                    snapshot:snapshot.key(),
110                    snapshot_entry:SnapshotEntry::pubkey(snapshot_frame.key(), snapshot_entry.id.checked_add(1).unwrap()),
111                    snapshot_frame:snapshot_frame.key(),
112                    thread: thread.key(),
113                }.to_account_metas(Some(true)),
114                data: crate::instruction::DeleteSnapshotProcessEntry{}.data()
115            }.into()
116        )
117    } else if snapshot_frame.id.checked_add(1).unwrap().lt(&snapshot.total_frames) {
118        // This frame has no more entries. Move onto the next frame.
119        Some(Instruction {
120            program_id: crate::ID,
121            accounts: crate::accounts::DeleteSnapshotProcessFrame {
122                config: config.key(), 
123                registry: registry.key(), 
124                snapshot: snapshot.key(), 
125                snapshot_frame: SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id.checked_add(1).unwrap()), 
126                thread: thread.key(),
127            }.to_account_metas(Some(true)),
128            data: crate::instruction::DeleteSnapshotProcessFrame{}.data()
129        }.into())
130    } else {
131        // This frame as no more entires and it was the last frame in the snapshot. We are done!
132        None
133    };
134
135    Ok( ThreadResponse { dynamic_instruction, close_to: None, trigger: None } )
136}