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