| 33 | } |
| 34 | |
| 35 | pub fn handler(ctx: Context<ThreadUpdate>, settings: ThreadSettings) -> Result<()> { |
| 36 | // Get accounts |
| 37 | let authority = &ctx.accounts.authority; |
| 38 | let thread = &mut ctx.accounts.thread; |
| 39 | let system_program = &ctx.accounts.system_program; |
| 40 | |
| 41 | // Update the thread. |
| 42 | if let Some(fee) = settings.fee { |
| 43 | thread.fee = fee; |
| 44 | } |
| 45 | |
| 46 | // If provided, update the thread's instruction set. |
| 47 | if let Some(instructions) = settings.instructions { |
| 48 | thread.instructions = instructions; |
| 49 | } |
| 50 | |
| 51 | // If provided, update the rate limit. |
| 52 | if let Some(rate_limit) = settings.rate_limit { |
| 53 | thread.rate_limit = rate_limit; |
| 54 | } |
| 55 | |
| 56 | // If provided, update the thread's trigger and reset the exec context. |
| 57 | if let Some(trigger) = settings.trigger { |
| 58 | // Require the thread is not in the middle of processing. |
| 59 | require!( |
| 60 | std::mem::discriminant(&thread.trigger) == std::mem::discriminant(&trigger), |
| 61 | ClockworkError::InvalidTriggerVariant |
| 62 | ); |
| 63 | thread.trigger = trigger.clone(); |
| 64 | |
| 65 | // If the user updates an account trigger, the trigger context is no longer valid. |
| 66 | // Here we reset the trigger context to zero to re-prime the trigger. |
| 67 | if thread.exec_context.is_some() { |
| 68 | thread.exec_context = Some(ExecContext { |
| 69 | trigger_context: match trigger { |
| 70 | Trigger::Account { |
| 71 | address: _, |
| 72 | offset: _, |
| 73 | size: _, |
| 74 | } => TriggerContext::Account { data_hash: 0 }, |
| 75 | _ => thread.exec_context.unwrap().trigger_context, |
| 76 | }, |
| 77 | ..thread.exec_context.unwrap() |
| 78 | }); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | // Reallocate mem for the thread account |
| 83 | thread.realloc()?; |
| 84 | |
| 85 | // If lamports are required to maintain rent-exemption, pay them |
| 86 | let data_len = thread.to_account_info().data_len(); |
| 87 | let minimum_rent = Rent::get().unwrap().minimum_balance(data_len); |
| 88 | if minimum_rent > thread.to_account_info().lamports() { |
| 89 | transfer( |
| 90 | CpiContext::new( |
| 91 | system_program.to_account_info(), |
| 92 | Transfer { |