tachyon_math_library/instructions/
func_load.rs

1use crate::{FunctionDataAccessors, LOAD_ERROR_TOLERANCE};
2use anchor_lang::prelude::*;
3use anchor_lang::ZeroCopy;
4
5use rust_decimal::{Decimal};
6
7
8use crate::error::ErrorCode;
9use crate::state::*;
10
11#[derive(Accounts)]
12pub struct FuncLoad<'info, T: ZeroCopy + Owner + FunctionDataAccessors> {
13    #[account(mut)]
14    pub admin: Signer<'info>,
15    #[account(
16        mut,
17        seeds = [FUNCTIONS_SEED],
18        bump,
19        has_one = admin
20    )]
21    pub functions: Account<'info, Functions>,
22    #[account(mut)]
23    pub f: AccountLoader<'info, T>,
24    pub system_program: Program<'info, System>,
25}
26
27impl<T: ZeroCopy + Owner + FunctionDataAccessors> FuncLoad<'_, T> {
28    pub fn handler(ctx: Context<FuncLoad<T>>, index_in: u32, x_in_raw: [u8; 16], y_in_raw: [u8; 16]) -> Result<()> {
29        let mut f = ctx.accounts.f.load_mut()?;
30
31        let x_in = Decimal::deserialize(x_in_raw);
32        let y_in = Decimal::deserialize(y_in_raw);
33
34        // verify that the index corresponds to the value of x
35        let x = f.get_x_from_index(index_in)?;
36        let x_diff = (x - x_in).abs();
37        if x_diff > LOAD_ERROR_TOLERANCE {
38            return err!(ErrorCode::InvalidIndex);
39        }
40
41        // verify (approximately) that f(x) = y, and use the return value as the load input (to load any edge cases re: truncation)
42        let (y, code) = f.eval_load(x_in, y_in)?;
43        f.set_value(index_in, y.serialize(), code as u8)?;
44
45        f.increment_num_values_loaded()?;
46
47        Ok(())
48    }
49}