Skip to content

Commit e9de9d8

Browse files
authored
account-view: Improve type documentation (#442)
Improve docs
1 parent 5390fa9 commit e9de9d8

File tree

1 file changed

+75
-68
lines changed

1 file changed

+75
-68
lines changed

account-view/src/lib.rs

Lines changed: 75 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,19 @@ pub struct RuntimeAccount {
7777
pub data_len: u64,
7878
}
7979

80-
/// Wrapper struct for an `Account`.
80+
/// Wrapper struct for a `RuntimeAccount`.
8181
///
82-
/// This struct provides safe access to the data in an `Account`. It is
83-
/// also used to track borrows of the account data and lamports, given
84-
/// that an account can be "shared" across multiple `AccountView`
85-
/// instances.
82+
/// This struct provides safe access to the data in a `RuntimeAccount`.
83+
/// It is also used to track borrows of the account data, given that
84+
/// an account can be "shared" across multiple `AccountView` instances.
8685
///
8786
/// # Invariants
8887
///
89-
/// - The `raw` pointer must be valid and point to memory containing an
90-
/// `Account` struct, immediately followed by the account's data region.
88+
/// - The `raw` pointer must be valid and point to memory containing a
89+
/// `RuntimeAccount` struct, immediately followed by the account's data
90+
/// region.
9191
/// - The length of the account data must exactly match the value stored in
92-
/// `Account::data_len`.
92+
/// `RuntimeAccount::data_len`.
9393
///
9494
/// These conditions must always hold for any `AccountView` created from
9595
/// a raw pointer.
@@ -109,7 +109,7 @@ impl AccountView {
109109
/// # Safety
110110
///
111111
/// The caller must ensure that the `raw` pointer is valid and points
112-
/// to memory containing an `Account` struct, immediately followed by
112+
/// to memory containing a `RuntimeAccount` struct, immediately followed by
113113
/// the account's data region.
114114
#[inline(always)]
115115
pub unsafe fn new_unchecked(raw: *mut RuntimeAccount) -> Self {
@@ -131,7 +131,7 @@ impl AccountView {
131131
///
132132
/// This method is unsafe because it returns a reference to the owner field,
133133
/// which can be modified by `assign` and `close` methods. It is undefined
134-
/// behavior to use this reference after the account has been modified.
134+
/// behavior to use this reference after the account owner has been modified.
135135
#[inline(always)]
136136
pub unsafe fn owner(&self) -> &Address {
137137
// SAFETY: The `raw` pointer is guaranteed to be valid.
@@ -145,23 +145,22 @@ impl AccountView {
145145
unsafe { (*self.raw).is_signer != 0 }
146146
}
147147

148-
/// Indicate whether the account is writable.
148+
/// Indicate whether the account is writable or not.
149149
#[inline(always)]
150150
pub fn is_writable(&self) -> bool {
151151
// SAFETY: The `raw` pointer is guaranteed to be valid.
152152
unsafe { (*self.raw).is_writable != 0 }
153153
}
154154

155-
/// Indicate whether this account represents an executable program.
156-
///
157-
/// Program accounts are always read-only.
155+
/// Indicate whether this account represents an executable program
156+
/// or not.
158157
#[inline(always)]
159158
pub fn executable(&self) -> bool {
160159
// SAFETY: The `raw` pointer is guaranteed to be valid.
161160
unsafe { (*self.raw).executable != 0 }
162161
}
163162

164-
/// Return the size of the data in the account.
163+
/// Return the size of the account data.
165164
#[inline(always)]
166165
pub fn data_len(&self) -> usize {
167166
// SAFETY: The `raw` pointer is guaranteed to be valid.
@@ -195,7 +194,7 @@ impl AccountView {
195194
}
196195
}
197196

198-
/// Indicates whether the account data is empty.
197+
/// Indicates whether the account data is empty or not.
199198
///
200199
/// An account is considered empty if the data length is zero.
201200
#[inline(always)]
@@ -235,34 +234,34 @@ impl AccountView {
235234
unsafe { (*self.raw).borrow_state == 0 }
236235
}
237236

238-
/// Returns a read-only reference to the data in the account.
237+
/// Returns an immutable reference to the data in the account.
239238
///
240239
/// # Safety
241240
///
242241
/// This method is unsafe because it does not return a `Ref`, thus leaving the borrow
243242
/// flag untouched. Useful when an instruction has verified non-duplicate accounts.
244243
#[inline(always)]
245-
pub unsafe fn borrow_data_unchecked(&self) -> &[u8] {
244+
pub unsafe fn borrow_unchecked(&self) -> &[u8] {
246245
from_raw_parts(self.data_ptr(), self.data_len())
247246
}
248247

249248
/// Returns a mutable reference to the data in the account.
250249
///
251250
/// # Safety
252251
///
253-
/// This method is unsafe because it does not return a `Ref`, thus leaving the borrow
252+
/// This method is unsafe because it does not return a `RefMut`, thus leaving the borrow
254253
/// flag untouched. Useful when an instruction has verified non-duplicate accounts.
255254
#[allow(clippy::mut_from_ref)]
256255
#[inline(always)]
257-
pub unsafe fn borrow_data_unchecked_mut(&self) -> &mut [u8] {
256+
pub unsafe fn borrow_unchecked_mut(&self) -> &mut [u8] {
258257
from_raw_parts_mut(self.data_ptr(), self.data_len())
259258
}
260259

261-
/// Tries to get a read-only reference to the data field, failing if the field
262-
/// is already mutable borrowed or if `7` borrows already exist.
263-
pub fn try_borrow_data(&self) -> Result<Ref<'_, [u8]>, ProgramError> {
264-
// check if the account data is already borrowed
265-
self.can_borrow_data()?;
260+
/// Tries to get an immutable reference to the account data, failing if the account
261+
/// is already mutably borrowed.
262+
pub fn try_borrow(&self) -> Result<Ref<'_, [u8]>, ProgramError> {
263+
// check if the account data can be borrowed
264+
self.check_borrow()?;
266265

267266
let borrow_state = self.raw as *mut u8;
268267
// Use one immutable borrow for data by subtracting `1` from the data
@@ -281,11 +280,11 @@ impl AccountView {
281280
})
282281
}
283282

284-
/// Tries to get a mutable reference to the data field, failing if the field
283+
/// Tries to get a mutable reference to the account data, failing if the account
285284
/// is already borrowed in any form.
286-
pub fn try_borrow_data_mut(&self) -> Result<RefMut<'_, [u8]>, ProgramError> {
287-
// check if the account data is already borrowed
288-
self.can_borrow_data_mut()?;
285+
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, [u8]>, ProgramError> {
286+
// check if the account data can be mutably borrowed
287+
self.check_borrow_mut()?;
289288

290289
let borrow_state = self.raw as *mut u8;
291290
// Set the mutable data borrow bit to `0`; we are guaranteed that account
@@ -303,11 +302,11 @@ impl AccountView {
303302
})
304303
}
305304

306-
/// Check if it is possible to get a immutable reference to the data field,
307-
/// failing if the field is already mutably borrowed or there are not enough
305+
/// Check if it is possible to get an immutable reference to the account data,
306+
/// failing if the account is already mutably borrowed or there are not enough
308307
/// immutable borrows available.
309308
#[inline(always)]
310-
pub fn can_borrow_data(&self) -> Result<(), ProgramError> {
309+
pub fn check_borrow(&self) -> Result<(), ProgramError> {
311310
// There must be at least one immutable borrow available.
312311
//
313312
// SAFETY: The `raw` pointer is guaranteed to be valid.
@@ -318,10 +317,10 @@ impl AccountView {
318317
Ok(())
319318
}
320319

321-
/// Checks if it is possible to get a mutable reference to the data field,
322-
/// failing if the field is already borrowed in any form.
320+
/// Checks if it is possible to get a mutable reference to the account data,
321+
/// failing if the account is already borrowed in any form.
323322
#[inline(always)]
324-
pub fn can_borrow_data_mut(&self) -> Result<(), ProgramError> {
323+
pub fn check_borrow_mut(&self) -> Result<(), ProgramError> {
325324
// SAFETY: The `raw` pointer is guaranteed to be valid.
326325
if unsafe { (*self.raw).borrow_state } != NOT_BORROWED {
327326
return Err(ProgramError::AccountBorrowFailed);
@@ -338,13 +337,13 @@ impl AccountView {
338337
/// # Important
339338
///
340339
/// This method makes assumptions about the layout and location of memory
341-
/// referenced by `Account` fields. It should only be called for instances
342-
/// of `AccountView` that were created by the runtime and received in the
343-
/// `process_instruction` entrypoint of a program.
340+
/// referenced by `RuntimeAccount` fields. It should only be called for
341+
/// instances of `AccountView` that were created by the runtime and received
342+
/// in the `process_instruction` entrypoint of a program.
344343
#[inline]
345344
pub fn resize(&self, new_len: usize) -> Result<(), ProgramError> {
346345
// Check whether the account data is already borrowed.
347-
self.can_borrow_data_mut()?;
346+
self.check_borrow_mut()?;
348347

349348
// SAFETY: We are checking if the account data is already borrowed, so
350349
// we are safe to call.
@@ -409,7 +408,8 @@ impl AccountView {
409408
/// # Important
410409
///
411410
/// The lamports must be moved from the account prior to closing it to prevent
412-
/// an unbalanced instruction error.
411+
/// an unbalanced instruction error. Any existing reference to the account owner
412+
/// will be invalidated after calling this method.
413413
#[inline]
414414
pub fn close(&self) -> ProgramResult {
415415
// Make sure the account is not borrowed since we are about to
@@ -452,8 +452,8 @@ impl AccountView {
452452
/// borrowed. It should only be called when the account is not being used.
453453
///
454454
/// It also makes assumptions about the layout and location of memory
455-
/// referenced by `AccountInfo` fields. It should only be called for
456-
/// instances of `AccountInfo` that were created by the runtime and received
455+
/// referenced by `RuntimeAccount` fields. It should only be called for
456+
/// instances of `AccountView` that were created by the runtime and received
457457
/// in the `process_instruction` entrypoint of a program.
458458
#[inline(always)]
459459
pub unsafe fn close_unchecked(&self) {
@@ -478,16 +478,16 @@ impl AccountView {
478478
/// Obtaining the raw pointer itself is safe, but de-referencing it requires
479479
/// the caller to uphold Rust's aliasing rules. It is undefined behavior to
480480
/// de-reference the pointer or write through it while any safe reference
481-
/// (e.g., from any of `borrow_data` or `borrow_mut_data` methods) to the same
482-
/// data is still alive.
481+
/// (e.g., from any of `borrow` or `borrow_mut` methods) to the same data
482+
/// is still alive.
483483
#[inline(always)]
484484
pub fn data_ptr(&self) -> *mut u8 {
485485
// SAFETY: The `raw` pointer is guaranteed to be valid.
486486
unsafe { (self.raw as *mut u8).add(size_of::<RuntimeAccount>()) }
487487
}
488488
}
489489

490-
/// Reference to account data or lamports with checked borrow rules.
490+
/// Reference to account data with checked borrow rules.
491491
#[derive(Debug)]
492492
pub struct Ref<'a, T: ?Sized> {
493493
value: NonNull<T>,
@@ -504,7 +504,7 @@ impl<'a, T: ?Sized> Ref<'a, T> {
504504
where
505505
F: FnOnce(&T) -> &U,
506506
{
507-
// Avoid decrementing the borrow flag on Drop.
507+
// Avoid decrementing the borrow flag on drop.
508508
let orig = ManuallyDrop::new(orig);
509509
Ref {
510510
value: NonNull::from(f(&*orig)),
@@ -514,6 +514,7 @@ impl<'a, T: ?Sized> Ref<'a, T> {
514514
}
515515

516516
/// Tries to makes a new `Ref` for a component of the borrowed data.
517+
///
517518
/// On failure, the original guard is returned alongside with the error
518519
/// returned by the closure.
519520
#[inline]
@@ -534,12 +535,14 @@ impl<'a, T: ?Sized> Ref<'a, T> {
534535
}
535536

536537
/// Filters and maps a reference to a new type.
538+
///
539+
/// On failure, the original guard is returned.
537540
#[inline]
538541
pub fn filter_map<U: ?Sized, F>(orig: Ref<'a, T>, f: F) -> Result<Ref<'a, U>, Self>
539542
where
540543
F: FnOnce(&T) -> Option<&U>,
541544
{
542-
// Avoid decrementing the borrow flag on Drop.
545+
// Avoid decrementing the borrow flag on drop.
543546
let orig = ManuallyDrop::new(orig);
544547

545548
match f(&*orig) {
@@ -567,7 +570,7 @@ impl<T: ?Sized> Drop for Ref<'_, T> {
567570
}
568571
}
569572

570-
/// Mutable reference to account data or lamports with checked borrow rules.
573+
/// Mutable reference to account data with checked borrow rules.
571574
#[derive(Debug)]
572575
pub struct RefMut<'a, T: ?Sized> {
573576
value: NonNull<T>,
@@ -594,6 +597,7 @@ impl<'a, T: ?Sized> RefMut<'a, T> {
594597
}
595598

596599
/// Tries to makes a new `RefMut` for a component of the borrowed data.
600+
///
597601
/// On failure, the original guard is returned alongside with the error
598602
/// returned by the closure.
599603
#[inline]
@@ -614,6 +618,9 @@ impl<'a, T: ?Sized> RefMut<'a, T> {
614618
}
615619

616620
/// Filters and maps a mutable reference to a new type.
621+
///
622+
/// On failure, the original guard is returned alongside with the error
623+
/// returned by the closure.
617624
#[inline]
618625
pub fn filter_map<U: ?Sized, F>(orig: RefMut<'a, T>, f: F) -> Result<RefMut<'a, U>, Self>
619626
where
@@ -659,7 +666,7 @@ mod tests {
659666
};
660667

661668
#[test]
662-
fn test_data_ref() {
669+
fn test_ref() {
663670
let data: [u8; 4] = [0, 1, 2, 3];
664671
let mut state = NOT_BORROWED - 1;
665672

@@ -706,7 +713,7 @@ mod tests {
706713
}
707714

708715
#[test]
709-
fn test_data_ref_mut() {
716+
fn test_ref_mut() {
710717
let mut data: [u8; 4] = [0, 1, 2, 3];
711718
let mut state = 0;
712719

@@ -733,7 +740,7 @@ mod tests {
733740
}
734741

735742
#[test]
736-
fn test_borrow_data() {
743+
fn test_borrow() {
737744
// 8-bytes aligned account data + 8 bytes of trailing data.
738745
let mut data = [0u64; size_of::<RuntimeAccount>() / size_of::<u64>() + 1];
739746
let account = data.as_mut_ptr() as *mut RuntimeAccount;
@@ -743,8 +750,8 @@ mod tests {
743750
let account_view = AccountView { raw: account };
744751

745752
// Check that we can borrow data and lamports.
746-
assert!(account_view.can_borrow_data().is_ok());
747-
assert!(account_view.can_borrow_data_mut().is_ok());
753+
assert!(account_view.check_borrow().is_ok());
754+
assert!(account_view.check_borrow_mut().is_ok());
748755

749756
// It should be sound to mutate the data through the data pointer
750757
// while no other borrows exist.
@@ -761,7 +768,7 @@ mod tests {
761768
let mut refs = [ACCOUNT_REF; (NOT_BORROWED as usize) - 1];
762769

763770
refs.iter_mut().for_each(|r| {
764-
let Ok(data_ref) = account_view.try_borrow_data() else {
771+
let Ok(data_ref) = account_view.try_borrow() else {
765772
panic!("Failed to borrow data");
766773
};
767774
// Sanity check: the data pointer should see the change.
@@ -770,10 +777,10 @@ mod tests {
770777
});
771778

772779
// Check that we cannot borrow the data anymore.
773-
assert!(account_view.can_borrow_data().is_err());
774-
assert!(account_view.try_borrow_data().is_err());
775-
assert!(account_view.can_borrow_data_mut().is_err());
776-
assert!(account_view.try_borrow_data_mut().is_err());
780+
assert!(account_view.check_borrow().is_err());
781+
assert!(account_view.try_borrow().is_err());
782+
assert!(account_view.check_borrow_mut().is_err());
783+
assert!(account_view.try_borrow_mut().is_err());
777784

778785
// Drop the immutable borrows.
779786
refs.iter_mut().for_each(|r| {
@@ -782,26 +789,26 @@ mod tests {
782789
});
783790

784791
// We should be able to borrow the data again.
785-
assert!(account_view.can_borrow_data().is_ok());
786-
assert!(account_view.can_borrow_data_mut().is_ok());
792+
assert!(account_view.check_borrow().is_ok());
793+
assert!(account_view.check_borrow_mut().is_ok());
787794

788795
// Borrow mutable data.
789-
let ref_mut = account_view.try_borrow_data_mut().unwrap();
796+
let ref_mut = account_view.try_borrow_mut().unwrap();
790797
// It should be sound to get the data pointer while the data is borrowed
791798
// as long as we don't use it.
792799
let _data_ptr = account_view.data_ptr();
793800

794801
// Check that we cannot borrow the data anymore.
795-
assert!(account_view.can_borrow_data().is_err());
796-
assert!(account_view.try_borrow_data().is_err());
797-
assert!(account_view.can_borrow_data_mut().is_err());
798-
assert!(account_view.try_borrow_data_mut().is_err());
802+
assert!(account_view.check_borrow().is_err());
803+
assert!(account_view.try_borrow().is_err());
804+
assert!(account_view.check_borrow_mut().is_err());
805+
assert!(account_view.try_borrow_mut().is_err());
799806

800807
drop(ref_mut);
801808

802809
// We should be able to borrow the data again.
803-
assert!(account_view.can_borrow_data().is_ok());
804-
assert!(account_view.can_borrow_data_mut().is_ok());
810+
assert!(account_view.check_borrow().is_ok());
811+
assert!(account_view.check_borrow_mut().is_ok());
805812

806813
let borrow_state = unsafe { (*account_view.raw).borrow_state };
807814
assert!(borrow_state == NOT_BORROWED);
@@ -867,7 +874,7 @@ mod tests {
867874
assert_eq!(account.data_len(), 500);
868875
assert_eq!(account.resize_delta(), 400);
869876

870-
let data = account.try_borrow_data().unwrap();
877+
let data = account.try_borrow().unwrap();
871878
assert_eq!(data.len(), 500);
872879
}
873880
}

0 commit comments

Comments
 (0)