use crate::cfg_client; use crate::prelude::*; use anchor_lang::{AccountDeserialize, AccountSerialize}; use bytemuck::{Pod, Zeroable}; use std::cell::Ref; #[repr(u8)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize)] pub enum RequestStatus { #[default] None = 0, RequestPending = 1, RequestCancelled = 2, RequestFailure = 3, RequestExpired = 4, RequestSuccess = 5, } impl From for u8 { fn from(value: RequestStatus) -> Self { match value { RequestStatus::RequestPending => 1, RequestStatus::RequestCancelled => 2, RequestStatus::RequestFailure => 3, RequestStatus::RequestExpired => 4, RequestStatus::RequestSuccess => 5, _ => 0, } } } impl From for RequestStatus { fn from(value: u8) -> Self { match value { 1 => RequestStatus::RequestPending, 2 => RequestStatus::RequestCancelled, 3 => RequestStatus::RequestFailure, 4 => RequestStatus::RequestExpired, 5 => RequestStatus::RequestSuccess, _ => RequestStatus::default(), } } } #[derive(Copy, Clone, AnchorSerialize, AnchorDeserialize)] pub struct FunctionRequestTriggerRound { /// The status of the request. pub status: RequestStatus, /// The SOL bounty in lamports used to incentivize a verifier to expedite the request. pub bounty: u64, /// The slot the request was published pub request_slot: u64, /// The slot when the request was fulfilled pub fulfilled_slot: u64, /// The slot when the request will expire and be able to be closed by the non-authority account pub expiration_slot: u64, /// The EnclaveAccount who verified the enclave for this request pub verifier: Pubkey, /// The keypair generated in the enclave and required to sign any /// valid transactions processed by the function. pub enclave_signer: Pubkey, /// Reserved. pub _ebuf: [u8; 64], } impl Default for FunctionRequestTriggerRound { fn default() -> Self { unsafe { std::mem::zeroed() } } } // #[account] #[derive(AnchorDeserialize, AnchorSerialize, Clone)] pub struct FunctionRequestAccountData { // Up-Front Params for RPC filtering /// Whether the request is ready to be processed. pub is_triggered: u8, /// The status of the current request. pub status: RequestStatus, // Accounts /// Signer allowed to cancel the request. pub authority: Pubkey, /// The default destination for rent exemption when the account is closed. pub payer: Pubkey, /// The function that can process this request pub function: Pubkey, /// The tokenAccount escrow pub escrow: Pubkey, // Rounds /// The current active request. pub active_request: FunctionRequestTriggerRound, /// The previous request. pub previous_request: FunctionRequestTriggerRound, // Container Params /// The maximum number of bytes to pass to the container params. pub max_container_params_len: u32, /// Hash of the serialized container_params to prevent RPC tampering. pub hash: [u8; 32], /// The stringified container params to pass\ pub container_params: Vec, // Metadata /// The unix timestamp when the function was created. pub created_at: i64, /// The slot when the account can be garbage collected and closed by anyone for a portion of the rent. pub garbage_collection_slot: Option, /// Reserved. pub _ebuf: [u8; 256], } impl anchor_lang::AccountSerialize for FunctionRequestAccountData { fn try_serialize(&self, writer: &mut W) -> anchor_lang::Result<()> { if writer .write_all(&FunctionRequestAccountData::discriminator()) .is_err() { return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); } if AnchorSerialize::serialize(self, writer).is_err() { return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); } Ok(()) } } impl anchor_lang::AccountDeserialize for FunctionRequestAccountData { fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result { if buf.len() < FunctionRequestAccountData::discriminator().len() { return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorNotFound.into()); } let given_disc = &buf[..8]; if &FunctionRequestAccountData::discriminator() != given_disc { return Err( anchor_lang::error::Error::from(anchor_lang::error::AnchorError { error_name: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.name(), error_code_number: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch .into(), error_msg: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch .to_string(), error_origin: Some(anchor_lang::error::ErrorOrigin::Source( anchor_lang::error::Source { filename: "programs/attestation_program/src/lib.rs", line: 357u32, }, )), compared_values: None, }) .with_account_name("FunctionRequestAccountData"), ); } Self::try_deserialize_unchecked(buf) } fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { let mut data: &[u8] = &buf[8..]; AnchorDeserialize::deserialize(&mut data) .map_err(|_| anchor_lang::error::ErrorCode::AccountDidNotDeserialize.into()) } } impl Discriminator for FunctionRequestAccountData { const DISCRIMINATOR: [u8; 8] = [8, 14, 177, 85, 144, 65, 148, 246]; } impl Owner for FunctionRequestAccountData { fn owner() -> Pubkey { SWITCHBOARD_ATTESTATION_PROGRAM_ID } } impl FunctionRequestAccountData {}