solana_sdk/
account.rs

1use {
2    crate::{
3        clock::{Epoch, INITIAL_RENT_EPOCH},
4        lamports::LamportsError,
5        pubkey::Pubkey,
6    },
7    serde::{
8        ser::{Serialize, Serializer},
9        Deserialize,
10    },
11    solana_program::{account_info::AccountInfo, debug_account_data::*, sysvar::Sysvar},
12    std::{
13        cell::{Ref, RefCell},
14        fmt,
15        rc::Rc,
16        sync::Arc,
17    },
18};
19
20/// An Account with data that is stored on chain
21#[repr(C)]
22#[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")]
23#[derive(Deserialize, PartialEq, Eq, Clone, Default, AbiExample)]
24#[serde(rename_all = "camelCase")]
25pub struct Account {
26    /// lamports in the account
27    pub lamports: u64,
28    /// data held in this account
29    #[serde(with = "serde_bytes")]
30    pub data: Vec<u8>,
31    /// the program that owns this account. If executable, the program that loads this account.
32    pub owner: Pubkey,
33    /// this account's data contains a loaded program (and is now read-only)
34    pub executable: bool,
35    /// the epoch at which this account will next owe rent
36    pub rent_epoch: Epoch,
37}
38
39// mod because we need 'Account' below to have the name 'Account' to match expected serialization
40mod account_serialize {
41    use {
42        crate::{account::ReadableAccount, clock::Epoch, pubkey::Pubkey},
43        serde::{ser::Serializer, Serialize},
44    };
45    #[repr(C)]
46    #[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")]
47    #[derive(Serialize, AbiExample)]
48    #[serde(rename_all = "camelCase")]
49    struct Account<'a> {
50        lamports: u64,
51        #[serde(with = "serde_bytes")]
52        // a slice so we don't have to make a copy just to serialize this
53        data: &'a [u8],
54        // can't be &pubkey because abi example doesn't support it
55        owner: Pubkey,
56        executable: bool,
57        rent_epoch: Epoch,
58    }
59
60    /// allows us to implement serialize on AccountSharedData that is equivalent to Account::serialize without making a copy of the Vec<u8>
61    pub fn serialize_account<S>(
62        account: &(impl ReadableAccount + Serialize),
63        serializer: S,
64    ) -> Result<S::Ok, S::Error>
65    where
66        S: Serializer,
67    {
68        let temp = Account {
69            lamports: account.lamports(),
70            data: account.data(),
71            owner: *account.owner(),
72            executable: account.executable(),
73            rent_epoch: account.rent_epoch(),
74        };
75        temp.serialize(serializer)
76    }
77}
78
79impl Serialize for Account {
80    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81    where
82        S: Serializer,
83    {
84        crate::account::account_serialize::serialize_account(self, serializer)
85    }
86}
87
88impl Serialize for AccountSharedData {
89    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
90    where
91        S: Serializer,
92    {
93        crate::account::account_serialize::serialize_account(self, serializer)
94    }
95}
96
97/// An Account with data that is stored on chain
98/// This will be the in-memory representation of the 'Account' struct data.
99/// The existing 'Account' structure cannot easily change due to downstream projects.
100#[derive(PartialEq, Eq, Clone, Default, AbiExample, Deserialize)]
101#[serde(from = "Account")]
102pub struct AccountSharedData {
103    /// lamports in the account
104    lamports: u64,
105    /// data held in this account
106    data: Arc<Vec<u8>>,
107    /// the program that owns this account. If executable, the program that loads this account.
108    owner: Pubkey,
109    /// this account's data contains a loaded program (and is now read-only)
110    executable: bool,
111    /// the epoch at which this account will next owe rent
112    rent_epoch: Epoch,
113}
114
115/// Compares two ReadableAccounts
116///
117/// Returns true if accounts are essentially equivalent as in all fields are equivalent.
118pub fn accounts_equal<T: ReadableAccount, U: ReadableAccount>(me: &T, other: &U) -> bool {
119    me.lamports() == other.lamports()
120        && me.executable() == other.executable()
121        && me.rent_epoch() == other.rent_epoch()
122        && me.owner() == other.owner()
123        && me.data() == other.data()
124}
125
126impl From<AccountSharedData> for Account {
127    fn from(mut other: AccountSharedData) -> Self {
128        let account_data = Arc::make_mut(&mut other.data);
129        Self {
130            lamports: other.lamports,
131            data: std::mem::take(account_data),
132            owner: other.owner,
133            executable: other.executable,
134            rent_epoch: other.rent_epoch,
135        }
136    }
137}
138
139impl From<Account> for AccountSharedData {
140    fn from(other: Account) -> Self {
141        Self {
142            lamports: other.lamports,
143            data: Arc::new(other.data),
144            owner: other.owner,
145            executable: other.executable,
146            rent_epoch: other.rent_epoch,
147        }
148    }
149}
150
151pub trait WritableAccount: ReadableAccount {
152    fn set_lamports(&mut self, lamports: u64);
153    fn checked_add_lamports(&mut self, lamports: u64) -> Result<(), LamportsError> {
154        self.set_lamports(
155            self.lamports()
156                .checked_add(lamports)
157                .ok_or(LamportsError::ArithmeticOverflow)?,
158        );
159        Ok(())
160    }
161    fn checked_sub_lamports(&mut self, lamports: u64) -> Result<(), LamportsError> {
162        self.set_lamports(
163            self.lamports()
164                .checked_sub(lamports)
165                .ok_or(LamportsError::ArithmeticUnderflow)?,
166        );
167        Ok(())
168    }
169    fn saturating_add_lamports(&mut self, lamports: u64) {
170        self.set_lamports(self.lamports().saturating_add(lamports))
171    }
172    fn saturating_sub_lamports(&mut self, lamports: u64) {
173        self.set_lamports(self.lamports().saturating_sub(lamports))
174    }
175    fn data_mut(&mut self) -> &mut Vec<u8>;
176    fn data_as_mut_slice(&mut self) -> &mut [u8];
177    fn set_owner(&mut self, owner: Pubkey);
178    fn copy_into_owner_from_slice(&mut self, source: &[u8]);
179    fn set_executable(&mut self, executable: bool);
180    fn set_rent_epoch(&mut self, epoch: Epoch);
181    fn create(
182        lamports: u64,
183        data: Vec<u8>,
184        owner: Pubkey,
185        executable: bool,
186        rent_epoch: Epoch,
187    ) -> Self;
188}
189
190pub trait ReadableAccount: Sized {
191    fn lamports(&self) -> u64;
192    fn data(&self) -> &[u8];
193    fn owner(&self) -> &Pubkey;
194    fn executable(&self) -> bool;
195    fn rent_epoch(&self) -> Epoch;
196    fn to_account_shared_data(&self) -> AccountSharedData {
197        AccountSharedData::create(
198            self.lamports(),
199            self.data().to_vec(),
200            *self.owner(),
201            self.executable(),
202            self.rent_epoch(),
203        )
204    }
205}
206
207impl ReadableAccount for Account {
208    fn lamports(&self) -> u64 {
209        self.lamports
210    }
211    fn data(&self) -> &[u8] {
212        &self.data
213    }
214    fn owner(&self) -> &Pubkey {
215        &self.owner
216    }
217    fn executable(&self) -> bool {
218        self.executable
219    }
220    fn rent_epoch(&self) -> Epoch {
221        self.rent_epoch
222    }
223}
224
225impl WritableAccount for Account {
226    fn set_lamports(&mut self, lamports: u64) {
227        self.lamports = lamports;
228    }
229    fn data_mut(&mut self) -> &mut Vec<u8> {
230        &mut self.data
231    }
232    fn data_as_mut_slice(&mut self) -> &mut [u8] {
233        &mut self.data
234    }
235    fn set_owner(&mut self, owner: Pubkey) {
236        self.owner = owner;
237    }
238    fn copy_into_owner_from_slice(&mut self, source: &[u8]) {
239        self.owner.as_mut().copy_from_slice(source);
240    }
241    fn set_executable(&mut self, executable: bool) {
242        self.executable = executable;
243    }
244    fn set_rent_epoch(&mut self, epoch: Epoch) {
245        self.rent_epoch = epoch;
246    }
247    fn create(
248        lamports: u64,
249        data: Vec<u8>,
250        owner: Pubkey,
251        executable: bool,
252        rent_epoch: Epoch,
253    ) -> Self {
254        Account {
255            lamports,
256            data,
257            owner,
258            executable,
259            rent_epoch,
260        }
261    }
262}
263
264impl WritableAccount for AccountSharedData {
265    fn set_lamports(&mut self, lamports: u64) {
266        self.lamports = lamports;
267    }
268    fn data_mut(&mut self) -> &mut Vec<u8> {
269        Arc::make_mut(&mut self.data)
270    }
271    fn data_as_mut_slice(&mut self) -> &mut [u8] {
272        &mut self.data_mut()[..]
273    }
274    fn set_owner(&mut self, owner: Pubkey) {
275        self.owner = owner;
276    }
277    fn copy_into_owner_from_slice(&mut self, source: &[u8]) {
278        self.owner.as_mut().copy_from_slice(source);
279    }
280    fn set_executable(&mut self, executable: bool) {
281        self.executable = executable;
282    }
283    fn set_rent_epoch(&mut self, epoch: Epoch) {
284        self.rent_epoch = epoch;
285    }
286    fn create(
287        lamports: u64,
288        data: Vec<u8>,
289        owner: Pubkey,
290        executable: bool,
291        rent_epoch: Epoch,
292    ) -> Self {
293        AccountSharedData {
294            lamports,
295            data: Arc::new(data),
296            owner,
297            executable,
298            rent_epoch,
299        }
300    }
301}
302
303impl ReadableAccount for AccountSharedData {
304    fn lamports(&self) -> u64 {
305        self.lamports
306    }
307    fn data(&self) -> &[u8] {
308        &self.data
309    }
310    fn owner(&self) -> &Pubkey {
311        &self.owner
312    }
313    fn executable(&self) -> bool {
314        self.executable
315    }
316    fn rent_epoch(&self) -> Epoch {
317        self.rent_epoch
318    }
319    fn to_account_shared_data(&self) -> AccountSharedData {
320        // avoid data copy here
321        self.clone()
322    }
323}
324
325impl ReadableAccount for Ref<'_, AccountSharedData> {
326    fn lamports(&self) -> u64 {
327        self.lamports
328    }
329    fn data(&self) -> &[u8] {
330        &self.data
331    }
332    fn owner(&self) -> &Pubkey {
333        &self.owner
334    }
335    fn executable(&self) -> bool {
336        self.executable
337    }
338    fn rent_epoch(&self) -> Epoch {
339        self.rent_epoch
340    }
341    fn to_account_shared_data(&self) -> AccountSharedData {
342        AccountSharedData {
343            lamports: self.lamports(),
344            // avoid data copy here
345            data: Arc::clone(&self.data),
346            owner: *self.owner(),
347            executable: self.executable(),
348            rent_epoch: self.rent_epoch(),
349        }
350    }
351}
352
353impl ReadableAccount for Ref<'_, Account> {
354    fn lamports(&self) -> u64 {
355        self.lamports
356    }
357    fn data(&self) -> &[u8] {
358        &self.data
359    }
360    fn owner(&self) -> &Pubkey {
361        &self.owner
362    }
363    fn executable(&self) -> bool {
364        self.executable
365    }
366    fn rent_epoch(&self) -> Epoch {
367        self.rent_epoch
368    }
369}
370
371fn debug_fmt<T: ReadableAccount>(item: &T, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372    let mut f = f.debug_struct("Account");
373
374    f.field("lamports", &item.lamports())
375        .field("data.len", &item.data().len())
376        .field("owner", &item.owner())
377        .field("executable", &item.executable())
378        .field("rent_epoch", &item.rent_epoch());
379    debug_account_data(item.data(), &mut f);
380
381    f.finish()
382}
383
384impl fmt::Debug for Account {
385    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386        debug_fmt(self, f)
387    }
388}
389
390impl fmt::Debug for AccountSharedData {
391    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392        debug_fmt(self, f)
393    }
394}
395
396fn shared_new<T: WritableAccount>(lamports: u64, space: usize, owner: &Pubkey) -> T {
397    T::create(
398        lamports,
399        vec![0u8; space],
400        *owner,
401        bool::default(),
402        Epoch::default(),
403    )
404}
405
406fn shared_new_rent_epoch<T: WritableAccount>(
407    lamports: u64,
408    space: usize,
409    owner: &Pubkey,
410    rent_epoch: Epoch,
411) -> T {
412    T::create(
413        lamports,
414        vec![0u8; space],
415        *owner,
416        bool::default(),
417        rent_epoch,
418    )
419}
420
421fn shared_new_ref<T: WritableAccount>(
422    lamports: u64,
423    space: usize,
424    owner: &Pubkey,
425) -> Rc<RefCell<T>> {
426    Rc::new(RefCell::new(shared_new::<T>(lamports, space, owner)))
427}
428
429fn shared_new_data<T: serde::Serialize, U: WritableAccount>(
430    lamports: u64,
431    state: &T,
432    owner: &Pubkey,
433) -> Result<U, bincode::Error> {
434    let data = bincode::serialize(state)?;
435    Ok(U::create(
436        lamports,
437        data,
438        *owner,
439        bool::default(),
440        Epoch::default(),
441    ))
442}
443fn shared_new_ref_data<T: serde::Serialize, U: WritableAccount>(
444    lamports: u64,
445    state: &T,
446    owner: &Pubkey,
447) -> Result<RefCell<U>, bincode::Error> {
448    Ok(RefCell::new(shared_new_data::<T, U>(
449        lamports, state, owner,
450    )?))
451}
452
453fn shared_new_data_with_space<T: serde::Serialize, U: WritableAccount>(
454    lamports: u64,
455    state: &T,
456    space: usize,
457    owner: &Pubkey,
458) -> Result<U, bincode::Error> {
459    let mut account = shared_new::<U>(lamports, space, owner);
460
461    shared_serialize_data(&mut account, state)?;
462
463    Ok(account)
464}
465fn shared_new_ref_data_with_space<T: serde::Serialize, U: WritableAccount>(
466    lamports: u64,
467    state: &T,
468    space: usize,
469    owner: &Pubkey,
470) -> Result<RefCell<U>, bincode::Error> {
471    Ok(RefCell::new(shared_new_data_with_space::<T, U>(
472        lamports, state, space, owner,
473    )?))
474}
475
476fn shared_deserialize_data<T: serde::de::DeserializeOwned, U: ReadableAccount>(
477    account: &U,
478) -> Result<T, bincode::Error> {
479    bincode::deserialize(account.data())
480}
481
482fn shared_serialize_data<T: serde::Serialize, U: WritableAccount>(
483    account: &mut U,
484    state: &T,
485) -> Result<(), bincode::Error> {
486    if bincode::serialized_size(state)? > account.data().len() as u64 {
487        return Err(Box::new(bincode::ErrorKind::SizeLimit));
488    }
489    bincode::serialize_into(&mut account.data_as_mut_slice(), state)
490}
491
492impl Account {
493    pub fn new(lamports: u64, space: usize, owner: &Pubkey) -> Self {
494        shared_new(lamports, space, owner)
495    }
496    pub fn new_ref(lamports: u64, space: usize, owner: &Pubkey) -> Rc<RefCell<Self>> {
497        shared_new_ref(lamports, space, owner)
498    }
499    pub fn new_data<T: serde::Serialize>(
500        lamports: u64,
501        state: &T,
502        owner: &Pubkey,
503    ) -> Result<Self, bincode::Error> {
504        shared_new_data(lamports, state, owner)
505    }
506    pub fn new_ref_data<T: serde::Serialize>(
507        lamports: u64,
508        state: &T,
509        owner: &Pubkey,
510    ) -> Result<RefCell<Self>, bincode::Error> {
511        shared_new_ref_data(lamports, state, owner)
512    }
513    pub fn new_data_with_space<T: serde::Serialize>(
514        lamports: u64,
515        state: &T,
516        space: usize,
517        owner: &Pubkey,
518    ) -> Result<Self, bincode::Error> {
519        shared_new_data_with_space(lamports, state, space, owner)
520    }
521    pub fn new_ref_data_with_space<T: serde::Serialize>(
522        lamports: u64,
523        state: &T,
524        space: usize,
525        owner: &Pubkey,
526    ) -> Result<RefCell<Self>, bincode::Error> {
527        shared_new_ref_data_with_space(lamports, state, space, owner)
528    }
529    pub fn new_rent_epoch(lamports: u64, space: usize, owner: &Pubkey, rent_epoch: Epoch) -> Self {
530        shared_new_rent_epoch(lamports, space, owner, rent_epoch)
531    }
532    pub fn deserialize_data<T: serde::de::DeserializeOwned>(&self) -> Result<T, bincode::Error> {
533        shared_deserialize_data(self)
534    }
535    pub fn serialize_data<T: serde::Serialize>(&mut self, state: &T) -> Result<(), bincode::Error> {
536        shared_serialize_data(self, state)
537    }
538}
539
540impl AccountSharedData {
541    pub fn set_data_from_slice(&mut self, data: &[u8]) {
542        let len = self.data.len();
543        let len_different = len != data.len();
544        let different = len_different || data != &self.data[..];
545        if different {
546            self.data = Arc::new(data.to_vec());
547        }
548    }
549    pub fn set_data(&mut self, data: Vec<u8>) {
550        self.data = Arc::new(data);
551    }
552    pub fn new(lamports: u64, space: usize, owner: &Pubkey) -> Self {
553        shared_new(lamports, space, owner)
554    }
555    pub fn new_ref(lamports: u64, space: usize, owner: &Pubkey) -> Rc<RefCell<Self>> {
556        shared_new_ref(lamports, space, owner)
557    }
558    pub fn new_data<T: serde::Serialize>(
559        lamports: u64,
560        state: &T,
561        owner: &Pubkey,
562    ) -> Result<Self, bincode::Error> {
563        shared_new_data(lamports, state, owner)
564    }
565    pub fn new_ref_data<T: serde::Serialize>(
566        lamports: u64,
567        state: &T,
568        owner: &Pubkey,
569    ) -> Result<RefCell<Self>, bincode::Error> {
570        shared_new_ref_data(lamports, state, owner)
571    }
572    pub fn new_data_with_space<T: serde::Serialize>(
573        lamports: u64,
574        state: &T,
575        space: usize,
576        owner: &Pubkey,
577    ) -> Result<Self, bincode::Error> {
578        shared_new_data_with_space(lamports, state, space, owner)
579    }
580    pub fn new_ref_data_with_space<T: serde::Serialize>(
581        lamports: u64,
582        state: &T,
583        space: usize,
584        owner: &Pubkey,
585    ) -> Result<RefCell<Self>, bincode::Error> {
586        shared_new_ref_data_with_space(lamports, state, space, owner)
587    }
588    pub fn new_rent_epoch(lamports: u64, space: usize, owner: &Pubkey, rent_epoch: Epoch) -> Self {
589        shared_new_rent_epoch(lamports, space, owner, rent_epoch)
590    }
591    pub fn deserialize_data<T: serde::de::DeserializeOwned>(&self) -> Result<T, bincode::Error> {
592        shared_deserialize_data(self)
593    }
594    pub fn serialize_data<T: serde::Serialize>(&mut self, state: &T) -> Result<(), bincode::Error> {
595        shared_serialize_data(self, state)
596    }
597}
598
599pub type InheritableAccountFields = (u64, Epoch);
600pub const DUMMY_INHERITABLE_ACCOUNT_FIELDS: InheritableAccountFields = (1, INITIAL_RENT_EPOCH);
601
602/// Create an `Account` from a `Sysvar`.
603#[deprecated(
604    since = "1.5.17",
605    note = "Please use `create_account_for_test` instead"
606)]
607pub fn create_account<S: Sysvar>(sysvar: &S, lamports: u64) -> Account {
608    create_account_with_fields(sysvar, (lamports, INITIAL_RENT_EPOCH))
609}
610
611pub fn create_account_with_fields<S: Sysvar>(
612    sysvar: &S,
613    (lamports, rent_epoch): InheritableAccountFields,
614) -> Account {
615    let data_len = S::size_of().max(bincode::serialized_size(sysvar).unwrap() as usize);
616    let mut account = Account::new(lamports, data_len, &solana_program::sysvar::id());
617    to_account::<S, Account>(sysvar, &mut account).unwrap();
618    account.rent_epoch = rent_epoch;
619    account
620}
621
622pub fn create_account_for_test<S: Sysvar>(sysvar: &S) -> Account {
623    create_account_with_fields(sysvar, DUMMY_INHERITABLE_ACCOUNT_FIELDS)
624}
625
626/// Create an `Account` from a `Sysvar`.
627#[deprecated(
628    since = "1.5.17",
629    note = "Please use `create_account_shared_data_for_test` instead"
630)]
631pub fn create_account_shared_data<S: Sysvar>(sysvar: &S, lamports: u64) -> AccountSharedData {
632    AccountSharedData::from(create_account_with_fields(
633        sysvar,
634        (lamports, INITIAL_RENT_EPOCH),
635    ))
636}
637
638pub fn create_account_shared_data_with_fields<S: Sysvar>(
639    sysvar: &S,
640    fields: InheritableAccountFields,
641) -> AccountSharedData {
642    AccountSharedData::from(create_account_with_fields(sysvar, fields))
643}
644
645pub fn create_account_shared_data_for_test<S: Sysvar>(sysvar: &S) -> AccountSharedData {
646    AccountSharedData::from(create_account_with_fields(
647        sysvar,
648        DUMMY_INHERITABLE_ACCOUNT_FIELDS,
649    ))
650}
651
652/// Create a `Sysvar` from an `Account`'s data.
653pub fn from_account<S: Sysvar, T: ReadableAccount>(account: &T) -> Option<S> {
654    bincode::deserialize(account.data()).ok()
655}
656
657/// Serialize a `Sysvar` into an `Account`'s data.
658pub fn to_account<S: Sysvar, T: WritableAccount>(sysvar: &S, account: &mut T) -> Option<()> {
659    bincode::serialize_into(account.data_as_mut_slice(), sysvar).ok()
660}
661
662/// Return the information required to construct an `AccountInfo`.  Used by the
663/// `AccountInfo` conversion implementations.
664impl solana_program::account_info::Account for Account {
665    fn get(&mut self) -> (&mut u64, &mut [u8], &Pubkey, bool, Epoch) {
666        (
667            &mut self.lamports,
668            &mut self.data,
669            &self.owner,
670            self.executable,
671            self.rent_epoch,
672        )
673    }
674}
675
676/// Create `AccountInfo`s
677pub fn create_is_signer_account_infos<'a>(
678    accounts: &'a mut [(&'a Pubkey, bool, &'a mut Account)],
679) -> Vec<AccountInfo<'a>> {
680    accounts
681        .iter_mut()
682        .map(|(key, is_signer, account)| {
683            AccountInfo::new(
684                key,
685                *is_signer,
686                false,
687                &mut account.lamports,
688                &mut account.data,
689                &account.owner,
690                account.executable,
691                account.rent_epoch,
692            )
693        })
694        .collect()
695}
696
697#[cfg(test)]
698pub mod tests {
699    use super::*;
700
701    fn make_two_accounts(key: &Pubkey) -> (Account, AccountSharedData) {
702        let mut account1 = Account::new(1, 2, key);
703        account1.executable = true;
704        account1.rent_epoch = 4;
705        let mut account2 = AccountSharedData::new(1, 2, key);
706        account2.executable = true;
707        account2.rent_epoch = 4;
708        assert!(accounts_equal(&account1, &account2));
709        (account1, account2)
710    }
711
712    #[test]
713    fn test_account_data_copy_as_slice() {
714        let key = Pubkey::new_unique();
715        let key2 = Pubkey::new_unique();
716        let (mut account1, mut account2) = make_two_accounts(&key);
717        account1.copy_into_owner_from_slice(key2.as_ref());
718        account2.copy_into_owner_from_slice(key2.as_ref());
719        assert!(accounts_equal(&account1, &account2));
720        assert_eq!(account1.owner(), &key2);
721    }
722
723    #[test]
724    fn test_account_set_data_from_slice() {
725        let key = Pubkey::new_unique();
726        let (_, mut account) = make_two_accounts(&key);
727        assert_eq!(account.data(), &vec![0, 0]);
728        account.set_data_from_slice(&[1, 2]);
729        assert_eq!(account.data(), &vec![1, 2]);
730        account.set_data_from_slice(&[1, 2, 3]);
731        assert_eq!(account.data(), &vec![1, 2, 3]);
732        account.set_data_from_slice(&[4, 5, 6]);
733        assert_eq!(account.data(), &vec![4, 5, 6]);
734        account.set_data_from_slice(&[4, 5, 6, 0]);
735        assert_eq!(account.data(), &vec![4, 5, 6, 0]);
736        account.set_data_from_slice(&[]);
737        assert_eq!(account.data().len(), 0);
738        account.set_data_from_slice(&[44]);
739        assert_eq!(account.data(), &vec![44]);
740        account.set_data_from_slice(&[44]);
741        assert_eq!(account.data(), &vec![44]);
742    }
743
744    #[test]
745    fn test_account_data_set_data() {
746        let key = Pubkey::new_unique();
747        let (_, mut account) = make_two_accounts(&key);
748        assert_eq!(account.data(), &vec![0, 0]);
749        account.set_data(vec![1, 2]);
750        assert_eq!(account.data(), &vec![1, 2]);
751        account.set_data(vec![]);
752        assert_eq!(account.data().len(), 0);
753    }
754
755    #[test]
756    #[should_panic(
757        expected = "called `Result::unwrap()` on an `Err` value: Io(Kind(UnexpectedEof))"
758    )]
759    fn test_account_deserialize() {
760        let key = Pubkey::new_unique();
761        let (account1, _account2) = make_two_accounts(&key);
762        account1.deserialize_data::<String>().unwrap();
763    }
764
765    #[test]
766    #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: SizeLimit")]
767    fn test_account_serialize() {
768        let key = Pubkey::new_unique();
769        let (mut account1, _account2) = make_two_accounts(&key);
770        account1.serialize_data(&"hello world").unwrap();
771    }
772
773    #[test]
774    #[should_panic(
775        expected = "called `Result::unwrap()` on an `Err` value: Io(Kind(UnexpectedEof))"
776    )]
777    fn test_account_shared_data_deserialize() {
778        let key = Pubkey::new_unique();
779        let (_account1, account2) = make_two_accounts(&key);
780        account2.deserialize_data::<String>().unwrap();
781    }
782
783    #[test]
784    #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: SizeLimit")]
785    fn test_account_shared_data_serialize() {
786        let key = Pubkey::new_unique();
787        let (_account1, mut account2) = make_two_accounts(&key);
788        account2.serialize_data(&"hello world").unwrap();
789    }
790
791    #[test]
792    fn test_to_account_shared_data() {
793        let key = Pubkey::new_unique();
794        let (account1, account2) = make_two_accounts(&key);
795        assert!(accounts_equal(&account1, &account2));
796        let account3 = account1.to_account_shared_data();
797        let account4 = account2.to_account_shared_data();
798        assert!(accounts_equal(&account1, &account3));
799        assert!(accounts_equal(&account1, &account4));
800    }
801
802    #[test]
803    fn test_account_shared_data() {
804        let key = Pubkey::new_unique();
805        let (account1, account2) = make_two_accounts(&key);
806        assert!(accounts_equal(&account1, &account2));
807        let account = account1;
808        assert_eq!(account.lamports, 1);
809        assert_eq!(account.lamports(), 1);
810        assert_eq!(account.data.len(), 2);
811        assert_eq!(account.data().len(), 2);
812        assert_eq!(account.owner, key);
813        assert_eq!(account.owner(), &key);
814        assert!(account.executable);
815        assert!(account.executable());
816        assert_eq!(account.rent_epoch, 4);
817        assert_eq!(account.rent_epoch(), 4);
818        let account = account2;
819        assert_eq!(account.lamports, 1);
820        assert_eq!(account.lamports(), 1);
821        assert_eq!(account.data.len(), 2);
822        assert_eq!(account.data().len(), 2);
823        assert_eq!(account.owner, key);
824        assert_eq!(account.owner(), &key);
825        assert!(account.executable);
826        assert!(account.executable());
827        assert_eq!(account.rent_epoch, 4);
828        assert_eq!(account.rent_epoch(), 4);
829    }
830
831    // test clone and from for both types against expected
832    fn test_equal(
833        should_be_equal: bool,
834        account1: &Account,
835        account2: &AccountSharedData,
836        account_expected: &Account,
837    ) {
838        assert_eq!(should_be_equal, accounts_equal(account1, account2));
839        if should_be_equal {
840            assert!(accounts_equal(account_expected, account2));
841        }
842        assert_eq!(
843            accounts_equal(account_expected, account1),
844            accounts_equal(account_expected, &account1.clone())
845        );
846        assert_eq!(
847            accounts_equal(account_expected, account2),
848            accounts_equal(account_expected, &account2.clone())
849        );
850        assert_eq!(
851            accounts_equal(account_expected, account1),
852            accounts_equal(account_expected, &AccountSharedData::from(account1.clone()))
853        );
854        assert_eq!(
855            accounts_equal(account_expected, account2),
856            accounts_equal(account_expected, &Account::from(account2.clone()))
857        );
858    }
859
860    #[test]
861    fn test_account_add_sub_lamports() {
862        let key = Pubkey::new_unique();
863        let (mut account1, mut account2) = make_two_accounts(&key);
864        assert!(accounts_equal(&account1, &account2));
865        account1.checked_add_lamports(1).unwrap();
866        account2.checked_add_lamports(1).unwrap();
867        assert!(accounts_equal(&account1, &account2));
868        assert_eq!(account1.lamports(), 2);
869        account1.checked_sub_lamports(2).unwrap();
870        account2.checked_sub_lamports(2).unwrap();
871        assert!(accounts_equal(&account1, &account2));
872        assert_eq!(account1.lamports(), 0);
873    }
874
875    #[test]
876    #[should_panic(expected = "Overflow")]
877    fn test_account_checked_add_lamports_overflow() {
878        let key = Pubkey::new_unique();
879        let (mut account1, _account2) = make_two_accounts(&key);
880        account1.checked_add_lamports(u64::MAX).unwrap();
881    }
882
883    #[test]
884    #[should_panic(expected = "Underflow")]
885    fn test_account_checked_sub_lamports_underflow() {
886        let key = Pubkey::new_unique();
887        let (mut account1, _account2) = make_two_accounts(&key);
888        account1.checked_sub_lamports(u64::MAX).unwrap();
889    }
890
891    #[test]
892    #[should_panic(expected = "Overflow")]
893    fn test_account_checked_add_lamports_overflow2() {
894        let key = Pubkey::new_unique();
895        let (_account1, mut account2) = make_two_accounts(&key);
896        account2.checked_add_lamports(u64::MAX).unwrap();
897    }
898
899    #[test]
900    #[should_panic(expected = "Underflow")]
901    fn test_account_checked_sub_lamports_underflow2() {
902        let key = Pubkey::new_unique();
903        let (_account1, mut account2) = make_two_accounts(&key);
904        account2.checked_sub_lamports(u64::MAX).unwrap();
905    }
906
907    #[test]
908    fn test_account_saturating_add_lamports() {
909        let key = Pubkey::new_unique();
910        let (mut account, _) = make_two_accounts(&key);
911
912        let remaining = 22;
913        account.set_lamports(u64::MAX - remaining);
914        account.saturating_add_lamports(remaining * 2);
915        assert_eq!(account.lamports(), u64::MAX);
916    }
917
918    #[test]
919    fn test_account_saturating_sub_lamports() {
920        let key = Pubkey::new_unique();
921        let (mut account, _) = make_two_accounts(&key);
922
923        let remaining = 33;
924        account.set_lamports(remaining);
925        account.saturating_sub_lamports(remaining * 2);
926        assert_eq!(account.lamports(), 0);
927    }
928
929    #[test]
930    #[allow(clippy::redundant_clone)]
931    fn test_account_shared_data_all_fields() {
932        let key = Pubkey::new_unique();
933        let key2 = Pubkey::new_unique();
934        let key3 = Pubkey::new_unique();
935        let (mut account1, mut account2) = make_two_accounts(&key);
936        assert!(accounts_equal(&account1, &account2));
937
938        let mut account_expected = account1.clone();
939        assert!(accounts_equal(&account1, &account_expected));
940        assert!(accounts_equal(&account1, &account2.clone())); // test the clone here
941
942        for field_index in 0..5 {
943            for pass in 0..4 {
944                if field_index == 0 {
945                    if pass == 0 {
946                        account1.checked_add_lamports(1).unwrap();
947                    } else if pass == 1 {
948                        account_expected.checked_add_lamports(1).unwrap();
949                        account2.set_lamports(account2.lamports + 1);
950                    } else if pass == 2 {
951                        account1.set_lamports(account1.lamports + 1);
952                    } else if pass == 3 {
953                        account_expected.checked_add_lamports(1).unwrap();
954                        account2.checked_add_lamports(1).unwrap();
955                    }
956                } else if field_index == 1 {
957                    if pass == 0 {
958                        account1.data[0] += 1;
959                    } else if pass == 1 {
960                        account_expected.data[0] += 1;
961                        account2.data_as_mut_slice()[0] = account2.data[0] + 1;
962                    } else if pass == 2 {
963                        account1.data_as_mut_slice()[0] = account1.data[0] + 1;
964                    } else if pass == 3 {
965                        account_expected.data[0] += 1;
966                        account2.data_as_mut_slice()[0] += 1;
967                    }
968                } else if field_index == 2 {
969                    if pass == 0 {
970                        account1.owner = key2;
971                    } else if pass == 1 {
972                        account_expected.owner = key2;
973                        account2.set_owner(key2);
974                    } else if pass == 2 {
975                        account1.set_owner(key3);
976                    } else if pass == 3 {
977                        account_expected.owner = key3;
978                        account2.owner = key3;
979                    }
980                } else if field_index == 3 {
981                    if pass == 0 {
982                        account1.executable = !account1.executable;
983                    } else if pass == 1 {
984                        account_expected.executable = !account_expected.executable;
985                        account2.set_executable(!account2.executable);
986                    } else if pass == 2 {
987                        account1.set_executable(!account1.executable);
988                    } else if pass == 3 {
989                        account_expected.executable = !account_expected.executable;
990                        account2.executable = !account2.executable;
991                    }
992                } else if field_index == 4 {
993                    if pass == 0 {
994                        account1.rent_epoch += 1;
995                    } else if pass == 1 {
996                        account_expected.rent_epoch += 1;
997                        account2.set_rent_epoch(account2.rent_epoch + 1);
998                    } else if pass == 2 {
999                        account1.set_rent_epoch(account1.rent_epoch + 1);
1000                    } else if pass == 3 {
1001                        account_expected.rent_epoch += 1;
1002                        account2.rent_epoch += 1;
1003                    }
1004                }
1005
1006                let should_be_equal = pass == 1 || pass == 3;
1007                test_equal(should_be_equal, &account1, &account2, &account_expected);
1008
1009                // test new_ref
1010                if should_be_equal {
1011                    assert!(accounts_equal(
1012                        &Account::new_ref(
1013                            account_expected.lamports(),
1014                            account_expected.data().len(),
1015                            account_expected.owner()
1016                        )
1017                        .borrow(),
1018                        &AccountSharedData::new_ref(
1019                            account_expected.lamports(),
1020                            account_expected.data().len(),
1021                            account_expected.owner()
1022                        )
1023                        .borrow()
1024                    ));
1025
1026                    {
1027                        // test new_data
1028                        let account1_with_data = Account::new_data(
1029                            account_expected.lamports(),
1030                            &account_expected.data()[0],
1031                            account_expected.owner(),
1032                        )
1033                        .unwrap();
1034                        let account2_with_data = AccountSharedData::new_data(
1035                            account_expected.lamports(),
1036                            &account_expected.data()[0],
1037                            account_expected.owner(),
1038                        )
1039                        .unwrap();
1040
1041                        assert!(accounts_equal(&account1_with_data, &account2_with_data));
1042                        assert_eq!(
1043                            account1_with_data.deserialize_data::<u8>().unwrap(),
1044                            account2_with_data.deserialize_data::<u8>().unwrap()
1045                        );
1046                    }
1047
1048                    // test new_data_with_space
1049                    assert!(accounts_equal(
1050                        &Account::new_data_with_space(
1051                            account_expected.lamports(),
1052                            &account_expected.data()[0],
1053                            1,
1054                            account_expected.owner()
1055                        )
1056                        .unwrap(),
1057                        &AccountSharedData::new_data_with_space(
1058                            account_expected.lamports(),
1059                            &account_expected.data()[0],
1060                            1,
1061                            account_expected.owner()
1062                        )
1063                        .unwrap()
1064                    ));
1065
1066                    // test new_ref_data
1067                    assert!(accounts_equal(
1068                        &Account::new_ref_data(
1069                            account_expected.lamports(),
1070                            &account_expected.data()[0],
1071                            account_expected.owner()
1072                        )
1073                        .unwrap()
1074                        .borrow(),
1075                        &AccountSharedData::new_ref_data(
1076                            account_expected.lamports(),
1077                            &account_expected.data()[0],
1078                            account_expected.owner()
1079                        )
1080                        .unwrap()
1081                        .borrow()
1082                    ));
1083
1084                    //new_ref_data_with_space
1085                    assert!(accounts_equal(
1086                        &Account::new_ref_data_with_space(
1087                            account_expected.lamports(),
1088                            &account_expected.data()[0],
1089                            1,
1090                            account_expected.owner()
1091                        )
1092                        .unwrap()
1093                        .borrow(),
1094                        &AccountSharedData::new_ref_data_with_space(
1095                            account_expected.lamports(),
1096                            &account_expected.data()[0],
1097                            1,
1098                            account_expected.owner()
1099                        )
1100                        .unwrap()
1101                        .borrow()
1102                    ));
1103                }
1104            }
1105        }
1106    }
1107}