clockwork_scheduler/instructions/
task_exec.rs

1use {
2    crate::{errors::ClockworkError, instructions::utils::is_spam, state::*},
3    anchor_lang::{prelude::*, system_program},
4    clockwork_pool::state::Pool,
5    std::mem::size_of,
6};
7
8#[derive(Accounts)]
9pub struct TaskExec<'info> {
10    #[account(seeds = [SEED_CONFIG], bump)]
11    pub config: Box<Account<'info, Config>>,
12
13    #[account(
14        init_if_needed,
15        seeds = [
16            SEED_FEE,
17            worker.key().as_ref()
18        ],
19        bump,
20        payer = worker,
21        space = 8 + size_of::<Fee>(),
22    )]
23    pub fee: Account<'info, Fee>,
24
25    #[account()]
26    pub pool: Account<'info, Pool>,
27
28    #[account(
29        mut,
30        seeds = [
31            SEED_QUEUE, 
32            queue.authority.as_ref(),
33            queue.name.as_bytes(),
34        ],
35        bump,
36        constraint = match queue.status {
37            QueueStatus::Processing { task_id } => task_id == task.id,
38            _ => false,
39        } @ ClockworkError::InvalidQueueStatus
40    )]
41    pub queue: Account<'info, Queue>,
42
43    #[account(address = system_program::ID)]
44    pub system_program: Program<'info, System>,
45
46    #[account(
47        mut,
48        seeds = [
49            SEED_TASK,
50            task.queue.as_ref(),
51            task.id.to_be_bytes().as_ref()
52        ],
53        bump,
54    )]
55    pub task: Account<'info, Task>,
56
57    #[account(mut)]
58    pub worker: Signer<'info>,
59}
60
61pub fn handler(ctx: Context<TaskExec>) -> Result<()> {
62    // Load accounts
63    let task = &mut ctx.accounts.task;
64    let config = &ctx.accounts.config;
65    let fee = &mut ctx.accounts.fee;
66    let pool = &ctx.accounts.pool;
67    let queue = &mut ctx.accounts.queue;
68    let worker = &mut ctx.accounts.worker;
69
70    // Validate the worker is authorized to execute this task
71    if is_spam(&config, pool, queue, worker)? {
72        fee.pay_to_admin(config.spam_penalty, queue)?;
73        return Ok(());
74    }
75
76    // Execute the task
77    let account_infos = &mut ctx.remaining_accounts.clone().to_vec();
78    let queue_bump = *ctx.bumps.get("queue").unwrap();
79    task.exec(account_infos, config, fee, queue, queue_bump, worker)
80}