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#[repr(C)]
22#[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")]
23#[derive(Deserialize, PartialEq, Eq, Clone, Default, AbiExample)]
24#[serde(rename_all = "camelCase")]
25pub struct Account {
26 pub lamports: u64,
28 #[serde(with = "serde_bytes")]
30 pub data: Vec<u8>,
31 pub owner: Pubkey,
33 pub executable: bool,
35 pub rent_epoch: Epoch,
37}
38
39mod 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 data: &'a [u8],
54 owner: Pubkey,
56 executable: bool,
57 rent_epoch: Epoch,
58 }
59
60 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#[derive(PartialEq, Eq, Clone, Default, AbiExample, Deserialize)]
101#[serde(from = "Account")]
102pub struct AccountSharedData {
103 lamports: u64,
105 data: Arc<Vec<u8>>,
107 owner: Pubkey,
109 executable: bool,
111 rent_epoch: Epoch,
113}
114
115pub 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 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 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#[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#[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
652pub fn from_account<S: Sysvar, T: ReadableAccount>(account: &T) -> Option<S> {
654 bincode::deserialize(account.data()).ok()
655}
656
657pub 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
662impl 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
676pub 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 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())); 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 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 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 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 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 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}