dlp_api/state/
delegation_metadata.rs1use std::ptr;
2
3use borsh::{BorshDeserialize, BorshSerialize};
4use pinocchio::{account::RefMut, error::ProgramError, AccountView};
5use solana_program::pubkey::Pubkey;
6
7use super::discriminator::{AccountDiscriminator, AccountWithDiscriminator};
8use crate::{
9 impl_to_bytes_with_discriminator_borsh,
10 impl_try_from_bytes_with_discriminator_borsh, require_ge,
11};
12
13#[derive(BorshSerialize, BorshDeserialize, Debug, PartialEq)]
17pub struct DelegationMetadata {
18 pub last_update_nonce: u64,
21 pub is_undelegatable: bool,
23 pub seeds: Vec<Vec<u8>>,
25 pub rent_payer: Pubkey,
27}
28
29pub struct DelegationMetadataFast<'a> {
30 data: RefMut<'a, [u8]>,
31}
32
33impl<'a> DelegationMetadataFast<'a> {
34 pub fn from_account(
35 account: &'a AccountView,
36 ) -> Result<Self, ProgramError> {
37 require_ge!(
38 account.data_len(),
39 AccountDiscriminator::SPACE
40 + 8 + 1 + 32 + 4, ProgramError::InvalidAccountData
45 );
46
47 Ok(Self {
48 data: account.try_borrow_mut()?,
49 })
50 }
51
52 pub fn last_update_nonce(&self) -> u64 {
53 unsafe {
54 ptr::read(self.data.as_ptr().add(AccountDiscriminator::SPACE)
55 as *const u64)
56 }
57 }
58
59 pub fn set_last_update_nonce(&mut self, val: u64) {
60 unsafe {
61 ptr::write(
62 self.data.as_mut_ptr().add(AccountDiscriminator::SPACE)
63 as *mut u64,
64 val,
65 )
66 }
67 }
68
69 pub fn replace_last_update_nonce(&mut self, val: u64) -> u64 {
70 unsafe {
71 ptr::replace(
72 self.data.as_mut_ptr().add(AccountDiscriminator::SPACE)
73 as *mut u64,
74 val,
75 )
76 }
77 }
78
79 pub fn set_is_undelegatable(&mut self, val: bool) {
80 unsafe {
81 ptr::write(
82 self.data.as_mut_ptr().add(AccountDiscriminator::SPACE + 8)
83 as *mut bool,
84 val,
85 )
86 }
87 }
88
89 pub fn replace_is_undelegatable(&mut self, val: bool) -> bool {
90 unsafe {
91 ptr::replace(
92 self.data.as_mut_ptr().add(AccountDiscriminator::SPACE + 8)
93 as *mut bool,
94 val,
95 )
96 }
97 }
98}
99
100impl AccountWithDiscriminator for DelegationMetadata {
101 fn discriminator() -> AccountDiscriminator {
102 AccountDiscriminator::DelegationMetadata
103 }
104}
105
106impl DelegationMetadata {
107 pub fn serialized_size(&self) -> usize {
108 AccountDiscriminator::SPACE
109 + 8 + 1 + 32 + (4 + self.seeds.iter().map(|s| 4 + s.len()).sum::<usize>()) }
114}
115
116impl_to_bytes_with_discriminator_borsh!(DelegationMetadata);
117impl_try_from_bytes_with_discriminator_borsh!(DelegationMetadata);
118
119#[cfg(test)]
120mod tests {
121 use borsh::to_vec;
122
123 use super::*;
124
125 #[test]
126 fn test_serialization_without_discriminator() {
127 let original = DelegationMetadata {
128 seeds: vec![
129 vec![],
130 vec![
131 215, 233, 74, 188, 162, 203, 12, 212, 106, 87, 189, 226,
132 48, 38, 129, 7, 34, 82, 254, 106, 161, 35, 74, 146, 30,
133 211, 164, 97, 139, 136, 136, 77,
134 ],
135 ],
136 is_undelegatable: false,
137 last_update_nonce: 0,
138 rent_payer: Pubkey::default(),
139 };
140
141 let serialized = to_vec(&original).expect("Serialization failed");
143
144 let deserialized: DelegationMetadata =
146 DelegationMetadata::try_from_slice(&serialized)
147 .expect("Deserialization failed");
148
149 assert_eq!(deserialized, original);
150 }
151}