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