1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
pub mod escrow_constraints;
pub mod transfer_effects;
pub mod trifle;
use std::io::ErrorKind;
use borsh::{maybestd::io::Error as BorshError, BorshDeserialize, BorshSerialize};
use mpl_token_metadata::assertions::assert_owned_by;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use solana_program::{account_info::AccountInfo, program_error::ProgramError};
use crate::error::TrifleError;
pub const TRIFLE_SEED: &str = "trifle";
pub const ESCROW_SEED: &str = "escrow";
pub const FREEZE_AUTHORITY: &str = "freeze_authority";
#[repr(C)]
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone, Copy, FromPrimitive)]
pub enum Key {
Uninitialized,
EscrowConstraintModel,
Trifle,
}
pub trait SolanaAccount: BorshDeserialize {
fn key() -> Key;
fn size() -> usize;
fn is_correct_account_type(data: &[u8], data_type: Key) -> bool {
let key: Option<Key> = Key::from_u8(data[0]);
match key {
Some(key) => key == data_type || key == Key::Uninitialized,
None => false,
}
}
fn pad_length(buf: &mut Vec<u8>) -> Result<(), TrifleError> {
let padding_length = Self::size()
.checked_sub(buf.len())
.ok_or(TrifleError::NumericalOverflow)?;
buf.extend(vec![0; padding_length]);
Ok(())
}
fn safe_deserialize(mut data: &[u8]) -> Result<Self, BorshError> {
if !Self::is_correct_account_type(data, Self::key()) {
return Err(BorshError::new(ErrorKind::Other, "DataTypeMismatch"));
}
let result = Self::deserialize(&mut data)?;
Ok(result)
}
fn from_account_info(a: &AccountInfo) -> Result<Self, ProgramError>
where {
let ua = Self::safe_deserialize(&a.data.borrow_mut())
.map_err(|_| TrifleError::DataTypeMismatch)?;
assert_owned_by(a, &crate::id())?;
Ok(ua)
}
}