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