1#[cfg(feature = "dev-context-only-utils")]
4use qualifier_attr::qualifiers;
5use {
6 crate::{Account, AccountSharedData},
7 solana_account_info::{debug_account_data::*, AccountInfo},
8 solana_clock::{Epoch, INITIAL_RENT_EPOCH},
9 solana_instruction_error::LamportsError,
10 solana_pubkey::Pubkey,
11 solana_sdk_ids::{bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, loader_v4},
12 std::{cell::RefCell, fmt, mem::MaybeUninit, ops::Deref, ptr, rc::Rc, sync::Arc},
13};
14
15#[cfg(feature = "bincode")]
16mod bincode;
17#[cfg(feature = "bincode")]
18pub use bincode::*;
19
20pub fn accounts_equal<T: ReadableAccount, U: ReadableAccount>(me: &T, other: &U) -> bool {
35 me.lamports() == other.lamports()
36 && me.executable() == other.executable()
37 && me.rent_epoch() == other.rent_epoch()
38 && me.owner() == other.owner()
39 && me.data() == other.data()
40}
41
42impl From<AccountSharedData> for Account {
43 fn from(mut other: AccountSharedData) -> Self {
44 let account_data = Arc::make_mut(&mut other.data);
45 Self {
46 lamports: other.lamports,
47 data: std::mem::take(account_data),
48 owner: other.owner,
49 executable: other.executable,
50 rent_epoch: other.rent_epoch,
51 }
52 }
53}
54
55impl From<Account> for AccountSharedData {
56 fn from(other: Account) -> Self {
57 Self {
58 lamports: other.lamports,
59 data: Arc::new(other.data),
60 owner: other.owner,
61 executable: other.executable,
62 rent_epoch: other.rent_epoch,
63 }
64 }
65}
66
67pub trait WritableAccount: ReadableAccount {
68 fn set_lamports(&mut self, lamports: u64);
69 fn checked_add_lamports(&mut self, lamports: u64) -> Result<(), LamportsError> {
70 self.set_lamports(
71 self.lamports()
72 .checked_add(lamports)
73 .ok_or(LamportsError::ArithmeticOverflow)?,
74 );
75 Ok(())
76 }
77 fn checked_sub_lamports(&mut self, lamports: u64) -> Result<(), LamportsError> {
78 self.set_lamports(
79 self.lamports()
80 .checked_sub(lamports)
81 .ok_or(LamportsError::ArithmeticUnderflow)?,
82 );
83 Ok(())
84 }
85 fn saturating_add_lamports(&mut self, lamports: u64) {
86 self.set_lamports(self.lamports().saturating_add(lamports))
87 }
88 fn saturating_sub_lamports(&mut self, lamports: u64) {
89 self.set_lamports(self.lamports().saturating_sub(lamports))
90 }
91 fn data_as_mut_slice(&mut self) -> &mut [u8];
92 fn set_owner(&mut self, owner: Pubkey);
93 fn copy_into_owner_from_slice(&mut self, source: &[u8]);
94 fn set_executable(&mut self, executable: bool);
95 fn set_rent_epoch(&mut self, epoch: Epoch);
96}
97
98pub trait ReadableAccount: Sized {
99 fn lamports(&self) -> u64;
100 fn data(&self) -> &[u8];
101 fn owner(&self) -> &Pubkey;
102 fn executable(&self) -> bool;
103 fn rent_epoch(&self) -> Epoch;
104}
105
106impl<T> ReadableAccount for T
107where
108 T: Deref,
109 T::Target: ReadableAccount,
110{
111 fn lamports(&self) -> u64 {
112 self.deref().lamports()
113 }
114 fn data(&self) -> &[u8] {
115 self.deref().data()
116 }
117 fn owner(&self) -> &Pubkey {
118 self.deref().owner()
119 }
120 fn executable(&self) -> bool {
121 self.deref().executable()
122 }
123 fn rent_epoch(&self) -> Epoch {
124 self.deref().rent_epoch()
125 }
126}
127
128impl ReadableAccount for Account {
129 fn lamports(&self) -> u64 {
130 self.lamports
131 }
132 fn data(&self) -> &[u8] {
133 &self.data
134 }
135 fn owner(&self) -> &Pubkey {
136 &self.owner
137 }
138 fn executable(&self) -> bool {
139 self.executable
140 }
141 fn rent_epoch(&self) -> Epoch {
142 self.rent_epoch
143 }
144}
145
146impl WritableAccount for Account {
147 fn set_lamports(&mut self, lamports: u64) {
148 self.lamports = lamports;
149 }
150 fn data_as_mut_slice(&mut self) -> &mut [u8] {
151 &mut self.data
152 }
153 fn set_owner(&mut self, owner: Pubkey) {
154 self.owner = owner;
155 }
156 fn copy_into_owner_from_slice(&mut self, source: &[u8]) {
157 self.owner.as_mut().copy_from_slice(source);
158 }
159 fn set_executable(&mut self, executable: bool) {
160 self.executable = executable;
161 }
162 fn set_rent_epoch(&mut self, epoch: Epoch) {
163 self.rent_epoch = epoch;
164 }
165}
166
167impl WritableAccount for AccountSharedData {
168 fn set_lamports(&mut self, lamports: u64) {
169 self.lamports = lamports;
170 }
171 fn data_as_mut_slice(&mut self) -> &mut [u8] {
172 &mut self.data_mut()[..]
173 }
174 fn set_owner(&mut self, owner: Pubkey) {
175 self.owner = owner;
176 }
177 fn copy_into_owner_from_slice(&mut self, source: &[u8]) {
178 self.owner.as_mut().copy_from_slice(source);
179 }
180 fn set_executable(&mut self, executable: bool) {
181 self.executable = executable;
182 }
183 fn set_rent_epoch(&mut self, epoch: Epoch) {
184 self.rent_epoch = epoch;
185 }
186}
187
188impl ReadableAccount for AccountSharedData {
189 fn lamports(&self) -> u64 {
190 self.lamports
191 }
192 fn data(&self) -> &[u8] {
193 &self.data
194 }
195 fn owner(&self) -> &Pubkey {
196 &self.owner
197 }
198 fn executable(&self) -> bool {
199 self.executable
200 }
201 fn rent_epoch(&self) -> Epoch {
202 self.rent_epoch
203 }
204}
205
206fn debug_fmt<T: ReadableAccount>(item: &T, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 let mut f = f.debug_struct("Account");
208
209 f.field("lamports", &item.lamports())
210 .field("data.len", &item.data().len())
211 .field("owner", &item.owner())
212 .field("executable", &item.executable())
213 .field("rent_epoch", &item.rent_epoch());
214 debug_account_data(item.data(), &mut f);
215
216 f.finish()
217}
218
219impl fmt::Debug for Account {
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 debug_fmt(self, f)
222 }
223}
224
225impl fmt::Debug for AccountSharedData {
226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227 debug_fmt(self, f)
228 }
229}
230
231impl Account {
232 pub fn new(lamports: u64, space: usize, owner: &Pubkey) -> Self {
233 Account {
234 lamports,
235 data: vec![0; space],
236 owner: *owner,
237 executable: false,
238 rent_epoch: Epoch::default(),
239 }
240 }
241 pub fn new_with_data(lamports: u64, data: Vec<u8>, owner: &Pubkey) -> Self {
245 Account {
246 lamports,
247 data,
248 owner: *owner,
249 executable: false,
250 rent_epoch: Epoch::default(),
251 }
252 }
253 pub fn new_ref(lamports: u64, space: usize, owner: &Pubkey) -> Rc<RefCell<Self>> {
254 Rc::new(RefCell::new(Account::new(lamports, space, owner)))
255 }
256 pub fn new_rent_epoch(lamports: u64, space: usize, owner: &Pubkey, rent_epoch: Epoch) -> Self {
257 Account {
258 lamports,
259 data: vec![0; space],
260 owner: *owner,
261 executable: false,
262 rent_epoch,
263 }
264 }
265}
266
267impl AccountSharedData {
268 pub fn is_shared(&self) -> bool {
269 Arc::strong_count(&self.data) > 1
270 }
271
272 pub fn reserve(&mut self, additional: usize) {
273 if let Some(data) = Arc::get_mut(&mut self.data) {
274 data.reserve(additional)
275 } else {
276 let mut data = Vec::with_capacity(self.data.len().saturating_add(additional));
277 data.extend_from_slice(&self.data);
278 self.data = Arc::new(data);
279 }
280 }
281
282 pub fn capacity(&self) -> usize {
283 self.data.capacity()
284 }
285
286 pub fn data_clone(&self) -> Arc<Vec<u8>> {
287 Arc::clone(&self.data)
288 }
289
290 fn data_mut(&mut self) -> &mut Vec<u8> {
291 Arc::make_mut(&mut self.data)
292 }
293
294 pub fn resize(&mut self, new_len: usize, value: u8) {
295 self.data_mut().resize(new_len, value)
296 }
297
298 pub fn extend_from_slice(&mut self, data: &[u8]) {
299 self.data_mut().extend_from_slice(data)
300 }
301
302 pub fn set_data_from_slice(&mut self, new_data: &[u8]) {
303 let Some(data) = Arc::get_mut(&mut self.data) else {
305 return self.set_data(new_data.to_vec());
308 };
309
310 let new_len = new_data.len();
311
312 data.reserve(new_len.saturating_sub(data.len()));
327
328 #[allow(clippy::uninit_vec)]
333 unsafe {
335 data.set_len(0);
336 ptr::copy_nonoverlapping(new_data.as_ptr(), data.as_mut_ptr(), new_len);
337 data.set_len(new_len);
338 };
339 }
340
341 #[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
342 fn set_data(&mut self, data: Vec<u8>) {
343 self.data = Arc::new(data);
344 }
345
346 pub fn spare_data_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
347 self.data_mut().spare_capacity_mut()
348 }
349
350 pub fn new(lamports: u64, space: usize, owner: &Pubkey) -> Self {
351 AccountSharedData {
352 lamports,
353 data: Arc::new(vec![0u8; space]),
354 owner: *owner,
355 executable: false,
356 rent_epoch: Epoch::default(),
357 }
358 }
359 pub fn new_with_data(lamports: u64, data: Vec<u8>, owner: &Pubkey) -> Self {
366 AccountSharedData {
367 lamports,
368 data: Arc::new(data),
369 owner: *owner,
370 executable: false,
371 rent_epoch: Epoch::default(),
372 }
373 }
374 pub fn new_ref(lamports: u64, space: usize, owner: &Pubkey) -> Rc<RefCell<Self>> {
375 Rc::new(RefCell::new(AccountSharedData::new(lamports, space, owner)))
376 }
377 pub fn new_rent_epoch(lamports: u64, space: usize, owner: &Pubkey, rent_epoch: Epoch) -> Self {
378 AccountSharedData {
379 lamports,
380 data: Arc::new(vec![0; space]),
381 owner: *owner,
382 executable: false,
383 rent_epoch,
384 }
385 }
386 pub fn create_from_existing_shared_data(
387 lamports: u64,
388 data: Arc<Vec<u8>>,
389 owner: Pubkey,
390 executable: bool,
391 rent_epoch: Epoch,
392 ) -> AccountSharedData {
393 AccountSharedData {
394 lamports,
395 data,
396 owner,
397 executable,
398 rent_epoch,
399 }
400 }
401}
402
403pub type InheritableAccountFields = (u64, Epoch);
404pub const DUMMY_INHERITABLE_ACCOUNT_FIELDS: InheritableAccountFields = (1, INITIAL_RENT_EPOCH);
405
406impl solana_account_info::Account for Account {
409 fn get(&mut self) -> (&mut u64, &mut [u8], &Pubkey, bool) {
410 (
411 &mut self.lamports,
412 &mut self.data,
413 &self.owner,
414 self.executable,
415 )
416 }
417}
418
419pub fn create_is_signer_account_infos<'a>(
421 accounts: &'a mut [(&'a Pubkey, bool, &'a mut Account)],
422) -> Vec<AccountInfo<'a>> {
423 accounts
424 .iter_mut()
425 .map(|(key, is_signer, account)| {
426 AccountInfo::new(
427 key,
428 *is_signer,
429 false,
430 &mut account.lamports,
431 &mut account.data,
432 &account.owner,
433 account.executable,
434 )
435 })
436 .collect()
437}
438
439#[deprecated(since = "4.3.0", note = "no longer available as a constant")]
441pub const PROGRAM_OWNERS: &[Pubkey] = &[
442 bpf_loader_upgradeable::id(),
443 bpf_loader::id(),
444 bpf_loader_deprecated::id(),
445 loader_v4::id(),
446];
447
448#[cfg(test)]
449pub mod tests {
450 use super::*;
451
452 fn make_two_accounts(key: &Pubkey) -> (Account, AccountSharedData) {
453 let mut account1 = Account::new(1, 2, key);
454 account1.executable = true;
455 account1.rent_epoch = 4;
456 let mut account2 = AccountSharedData::new(1, 2, key);
457 account2.executable = true;
458 account2.rent_epoch = 4;
459 assert!(accounts_equal(&account1, &account2));
460 (account1, account2)
461 }
462
463 #[test]
464 fn test_account_shared_data_new_with_data() {
465 let key = Pubkey::new_unique();
466
467 let account = AccountSharedData::new_with_data(1, vec![1, 2, 3], &key);
468 assert!(accounts_equal(
469 &account,
470 &Account::new_with_data(1, vec![1, 2, 3], &key)
471 ));
472 assert_eq!(account.lamports(), 1);
473 assert_eq!(account.owner(), &key);
474 assert_eq!(account.data(), &[1, 2, 3]);
475 assert!(!account.executable());
476 assert_eq!(account.rent_epoch(), Epoch::default());
477 assert!(!account.is_shared());
478 }
479
480 #[test]
481 fn test_account_data_copy_as_slice() {
482 let key = Pubkey::new_unique();
483 let key2 = Pubkey::new_unique();
484 let (mut account1, mut account2) = make_two_accounts(&key);
485 account1.copy_into_owner_from_slice(key2.as_ref());
486 account2.copy_into_owner_from_slice(key2.as_ref());
487 assert!(accounts_equal(&account1, &account2));
488 assert_eq!(account1.owner(), &key2);
489 }
490
491 #[test]
492 fn test_account_set_data_from_slice() {
493 let key = Pubkey::new_unique();
494 let (_, mut account) = make_two_accounts(&key);
495 assert_eq!(account.data(), &vec![0, 0]);
496 account.set_data_from_slice(&[1, 2]);
497 assert_eq!(account.data(), &vec![1, 2]);
498 account.set_data_from_slice(&[1, 2, 3]);
499 assert_eq!(account.data(), &vec![1, 2, 3]);
500 account.set_data_from_slice(&[4, 5, 6]);
501 assert_eq!(account.data(), &vec![4, 5, 6]);
502 account.set_data_from_slice(&[4, 5, 6, 0]);
503 assert_eq!(account.data(), &vec![4, 5, 6, 0]);
504 account.set_data_from_slice(&[]);
505 assert_eq!(account.data().len(), 0);
506 account.set_data_from_slice(&[44]);
507 assert_eq!(account.data(), &vec![44]);
508 account.set_data_from_slice(&[44]);
509 assert_eq!(account.data(), &vec![44]);
510 }
511
512 #[test]
513 fn test_account_data_set_data() {
514 let key = Pubkey::new_unique();
515 let (_, mut account) = make_two_accounts(&key);
516 assert_eq!(account.data(), &vec![0, 0]);
517 account.set_data(vec![1, 2]);
518 assert_eq!(account.data(), &vec![1, 2]);
519 account.set_data(vec![]);
520 assert_eq!(account.data().len(), 0);
521 }
522
523 #[test]
524 #[should_panic(
525 expected = "called `Result::unwrap()` on an `Err` value: Io(Kind(UnexpectedEof))"
526 )]
527 fn test_account_deserialize() {
528 let key = Pubkey::new_unique();
529 let (account1, _account2) = make_two_accounts(&key);
530 account1.deserialize_data::<String>().unwrap();
531 }
532
533 #[test]
534 #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: SizeLimit")]
535 fn test_account_serialize() {
536 let key = Pubkey::new_unique();
537 let (mut account1, _account2) = make_two_accounts(&key);
538 account1.serialize_data(&"hello world").unwrap();
539 }
540
541 #[test]
542 #[should_panic(
543 expected = "called `Result::unwrap()` on an `Err` value: Io(Kind(UnexpectedEof))"
544 )]
545 fn test_account_shared_data_deserialize() {
546 let key = Pubkey::new_unique();
547 let (_account1, account2) = make_two_accounts(&key);
548 account2.deserialize_data::<String>().unwrap();
549 }
550
551 #[test]
552 #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: SizeLimit")]
553 fn test_account_shared_data_serialize() {
554 let key = Pubkey::new_unique();
555 let (_account1, mut account2) = make_two_accounts(&key);
556 account2.serialize_data(&"hello world").unwrap();
557 }
558
559 #[test]
560 fn test_account_shared_data() {
561 let key = Pubkey::new_unique();
562 let (account1, account2) = make_two_accounts(&key);
563 assert!(accounts_equal(&account1, &account2));
564 let account = account1;
565 assert_eq!(account.lamports, 1);
566 assert_eq!(account.lamports(), 1);
567 assert_eq!(account.data.len(), 2);
568 assert_eq!(account.data().len(), 2);
569 assert_eq!(account.owner, key);
570 assert_eq!(account.owner(), &key);
571 assert!(account.executable);
572 assert!(account.executable());
573 assert_eq!(account.rent_epoch, 4);
574 assert_eq!(account.rent_epoch(), 4);
575 let account = account2;
576 assert_eq!(account.lamports, 1);
577 assert_eq!(account.lamports(), 1);
578 assert_eq!(account.data.len(), 2);
579 assert_eq!(account.data().len(), 2);
580 assert_eq!(account.owner, key);
581 assert_eq!(account.owner(), &key);
582 assert!(account.executable);
583 assert!(account.executable());
584 assert_eq!(account.rent_epoch, 4);
585 assert_eq!(account.rent_epoch(), 4);
586 }
587
588 fn test_equal(
590 should_be_equal: bool,
591 account1: &Account,
592 account2: &AccountSharedData,
593 account_expected: &Account,
594 ) {
595 assert_eq!(should_be_equal, accounts_equal(account1, account2));
596 if should_be_equal {
597 assert!(accounts_equal(account_expected, account2));
598 }
599 assert_eq!(
600 accounts_equal(account_expected, account1),
601 accounts_equal(account_expected, &account1.clone())
602 );
603 assert_eq!(
604 accounts_equal(account_expected, account2),
605 accounts_equal(account_expected, &account2.clone())
606 );
607 assert_eq!(
608 accounts_equal(account_expected, account1),
609 accounts_equal(account_expected, &AccountSharedData::from(account1.clone()))
610 );
611 assert_eq!(
612 accounts_equal(account_expected, account2),
613 accounts_equal(account_expected, &Account::from(account2.clone()))
614 );
615 }
616
617 #[test]
618 fn test_account_add_sub_lamports() {
619 let key = Pubkey::new_unique();
620 let (mut account1, mut account2) = make_two_accounts(&key);
621 assert!(accounts_equal(&account1, &account2));
622 account1.checked_add_lamports(1).unwrap();
623 account2.checked_add_lamports(1).unwrap();
624 assert!(accounts_equal(&account1, &account2));
625 assert_eq!(account1.lamports(), 2);
626 account1.checked_sub_lamports(2).unwrap();
627 account2.checked_sub_lamports(2).unwrap();
628 assert!(accounts_equal(&account1, &account2));
629 assert_eq!(account1.lamports(), 0);
630 }
631
632 #[test]
633 #[should_panic(expected = "Overflow")]
634 fn test_account_checked_add_lamports_overflow() {
635 let key = Pubkey::new_unique();
636 let (mut account1, _account2) = make_two_accounts(&key);
637 account1.checked_add_lamports(u64::MAX).unwrap();
638 }
639
640 #[test]
641 #[should_panic(expected = "Underflow")]
642 fn test_account_checked_sub_lamports_underflow() {
643 let key = Pubkey::new_unique();
644 let (mut account1, _account2) = make_two_accounts(&key);
645 account1.checked_sub_lamports(u64::MAX).unwrap();
646 }
647
648 #[test]
649 #[should_panic(expected = "Overflow")]
650 fn test_account_checked_add_lamports_overflow2() {
651 let key = Pubkey::new_unique();
652 let (_account1, mut account2) = make_two_accounts(&key);
653 account2.checked_add_lamports(u64::MAX).unwrap();
654 }
655
656 #[test]
657 #[should_panic(expected = "Underflow")]
658 fn test_account_checked_sub_lamports_underflow2() {
659 let key = Pubkey::new_unique();
660 let (_account1, mut account2) = make_two_accounts(&key);
661 account2.checked_sub_lamports(u64::MAX).unwrap();
662 }
663
664 #[test]
665 fn test_account_saturating_add_lamports() {
666 let key = Pubkey::new_unique();
667 let (mut account, _) = make_two_accounts(&key);
668
669 let remaining = 22;
670 account.set_lamports(u64::MAX - remaining);
671 account.saturating_add_lamports(remaining * 2);
672 assert_eq!(account.lamports(), u64::MAX);
673 }
674
675 #[test]
676 fn test_account_saturating_sub_lamports() {
677 let key = Pubkey::new_unique();
678 let (mut account, _) = make_two_accounts(&key);
679
680 let remaining = 33;
681 account.set_lamports(remaining);
682 account.saturating_sub_lamports(remaining * 2);
683 assert_eq!(account.lamports(), 0);
684 }
685
686 #[test]
687 fn test_account_shared_data_all_fields() {
688 let key = Pubkey::new_unique();
689 let key2 = Pubkey::new_unique();
690 let key3 = Pubkey::new_unique();
691 let (mut account1, mut account2) = make_two_accounts(&key);
692 assert!(accounts_equal(&account1, &account2));
693
694 let mut account_expected = account1.clone();
695 assert!(accounts_equal(&account1, &account_expected));
696 assert!(accounts_equal(&account1, &account2.clone())); for field_index in 0..5 {
699 for pass in 0..4 {
700 if field_index == 0 {
701 if pass == 0 {
702 account1.checked_add_lamports(1).unwrap();
703 } else if pass == 1 {
704 account_expected.checked_add_lamports(1).unwrap();
705 account2.set_lamports(account2.lamports + 1);
706 } else if pass == 2 {
707 account1.set_lamports(account1.lamports + 1);
708 } else if pass == 3 {
709 account_expected.checked_add_lamports(1).unwrap();
710 account2.checked_add_lamports(1).unwrap();
711 }
712 } else if field_index == 1 {
713 if pass == 0 {
714 account1.data[0] += 1;
715 } else if pass == 1 {
716 account_expected.data[0] += 1;
717 account2.data_as_mut_slice()[0] = account2.data[0] + 1;
718 } else if pass == 2 {
719 account1.data_as_mut_slice()[0] = account1.data[0] + 1;
720 } else if pass == 3 {
721 account_expected.data[0] += 1;
722 account2.data_as_mut_slice()[0] += 1;
723 }
724 } else if field_index == 2 {
725 if pass == 0 {
726 account1.owner = key2;
727 } else if pass == 1 {
728 account_expected.owner = key2;
729 account2.set_owner(key2);
730 } else if pass == 2 {
731 account1.set_owner(key3);
732 } else if pass == 3 {
733 account_expected.owner = key3;
734 account2.owner = key3;
735 }
736 } else if field_index == 3 {
737 if pass == 0 {
738 account1.executable = !account1.executable;
739 } else if pass == 1 {
740 account_expected.executable = !account_expected.executable;
741 account2.set_executable(!account2.executable);
742 } else if pass == 2 {
743 account1.set_executable(!account1.executable);
744 } else if pass == 3 {
745 account_expected.executable = !account_expected.executable;
746 account2.executable = !account2.executable;
747 }
748 } else if field_index == 4 {
749 if pass == 0 {
750 account1.rent_epoch += 1;
751 } else if pass == 1 {
752 account_expected.rent_epoch += 1;
753 account2.set_rent_epoch(account2.rent_epoch + 1);
754 } else if pass == 2 {
755 account1.set_rent_epoch(account1.rent_epoch + 1);
756 } else if pass == 3 {
757 account_expected.rent_epoch += 1;
758 account2.rent_epoch += 1;
759 }
760 }
761
762 let should_be_equal = pass == 1 || pass == 3;
763 test_equal(should_be_equal, &account1, &account2, &account_expected);
764
765 if should_be_equal {
767 assert!(accounts_equal(
768 &Account::new_ref(
769 account_expected.lamports(),
770 account_expected.data().len(),
771 account_expected.owner()
772 )
773 .borrow(),
774 &AccountSharedData::new_ref(
775 account_expected.lamports(),
776 account_expected.data().len(),
777 account_expected.owner()
778 )
779 .borrow()
780 ));
781
782 {
783 let account1_with_data = Account::new_data(
785 account_expected.lamports(),
786 &account_expected.data()[0],
787 account_expected.owner(),
788 )
789 .unwrap();
790 let account2_with_data = AccountSharedData::new_data(
791 account_expected.lamports(),
792 &account_expected.data()[0],
793 account_expected.owner(),
794 )
795 .unwrap();
796
797 assert!(accounts_equal(&account1_with_data, &account2_with_data));
798 assert_eq!(
799 account1_with_data.deserialize_data::<u8>().unwrap(),
800 account2_with_data.deserialize_data::<u8>().unwrap()
801 );
802 }
803
804 assert!(accounts_equal(
806 &Account::new_data_with_space(
807 account_expected.lamports(),
808 &account_expected.data()[0],
809 1,
810 account_expected.owner()
811 )
812 .unwrap(),
813 &AccountSharedData::new_data_with_space(
814 account_expected.lamports(),
815 &account_expected.data()[0],
816 1,
817 account_expected.owner()
818 )
819 .unwrap()
820 ));
821
822 assert!(accounts_equal(
824 &Account::new_ref_data(
825 account_expected.lamports(),
826 &account_expected.data()[0],
827 account_expected.owner()
828 )
829 .unwrap()
830 .borrow(),
831 &AccountSharedData::new_ref_data(
832 account_expected.lamports(),
833 &account_expected.data()[0],
834 account_expected.owner()
835 )
836 .unwrap()
837 .borrow()
838 ));
839
840 assert!(accounts_equal(
842 &Account::new_ref_data_with_space(
843 account_expected.lamports(),
844 &account_expected.data()[0],
845 1,
846 account_expected.owner()
847 )
848 .unwrap()
849 .borrow(),
850 &AccountSharedData::new_ref_data_with_space(
851 account_expected.lamports(),
852 &account_expected.data()[0],
853 1,
854 account_expected.owner()
855 )
856 .unwrap()
857 .borrow()
858 ));
859 }
860 }
861 }
862 }
863}