pub struct OwnedView<'info> { /* private fields */ }Expand description
An AccountView that has been proven to be owned by a specific program.
Prevents confused-deputy attacks: once validated, downstream code can trust the account data without re-checking ownership.
Implementations§
Source§impl<'info> OwnedView<'info>
impl<'info> OwnedView<'info>
Sourcepub fn validate(
view: AccountView<'info>,
expected_owner: &Address,
) -> Result<Self, ProgramError>
pub fn validate( view: AccountView<'info>, expected_owner: &Address, ) -> Result<Self, ProgramError>
Validate that the account is owned by expected_owner.
Sourcepub fn as_view(&self) -> &AccountView<'info>
pub fn as_view(&self) -> &AccountView<'info>
Access the underlying AccountView.
Sourcepub fn into_view(self) -> AccountView<'info>
pub fn into_view(self) -> AccountView<'info>
Consume and return the inner AccountView.
Methods from Deref<Target = AccountView<'info>>§
pub const SYSTEM_PROGRAM_ID: Address
Sourcepub unsafe fn owner(&self) -> &Address
pub unsafe fn owner(&self) -> &Address
The owning program’s address.
§Safety
The returned reference is invalidated if the account is assigned to a new owner or closed. The caller must ensure no concurrent mutation occurs.
Sourcepub fn is_writable(&self) -> bool
pub fn is_writable(&self) -> bool
Whether this account is writable in the transaction.
Sourcepub fn executable(&self) -> bool
pub fn executable(&self) -> bool
Whether this account contains an executable program.
Sourcepub fn original_data_len(&self) -> usize
pub fn original_data_len(&self) -> usize
Original data length captured by the entrypoint for this invocation.
Solana reserves the four bytes at header offset 4 for this value. It must remain unchanged across local resizes and CPI so every resize is checked against one invocation-wide baseline.
Sourcepub fn resize_delta(&self) -> i32
pub fn resize_delta(&self) -> i32
Difference between the current and original data length.
Sourcepub fn is_data_empty(&self) -> bool
pub fn is_data_empty(&self) -> bool
Whether the account data is empty (data_len == 0).
Sourcepub fn set_lamports(&self, lamports: u64)
pub fn set_lamports(&self, lamports: u64)
Set the lamport balance.
Sourcepub fn owned_by(&self, program: &Address) -> bool
pub fn owned_by(&self, program: &Address) -> bool
Check whether this account is owned by the given program.
Sourcepub unsafe fn assign(&self, new_owner: &Address)
pub unsafe fn assign(&self, new_owner: &Address)
Assign a new owner.
§Safety
The caller must ensure the account is writable and that ownership transfer is authorized by the current owner program.
Sourcepub fn is_borrowed(&self) -> bool
pub fn is_borrowed(&self) -> bool
Whether the account data is currently borrowed (shared or exclusive).
Sourcepub fn is_borrowed_mut(&self) -> bool
pub fn is_borrowed_mut(&self) -> bool
Whether the account data is exclusively (mutably) borrowed.
Sourcepub fn check_borrow(&self) -> Result<(), ProgramError>
pub fn check_borrow(&self) -> Result<(), ProgramError>
Check that the account can be shared-borrowed.
Sourcepub fn check_borrow_mut(&self) -> Result<(), ProgramError>
pub fn check_borrow_mut(&self) -> Result<(), ProgramError>
Check that the account can be exclusively borrowed.
Sourcepub unsafe fn borrow_unchecked(&self) -> &[u8]
pub unsafe fn borrow_unchecked(&self) -> &[u8]
Borrow account data without borrow tracking.
§Safety
The caller must ensure no mutable borrow is active.
Sourcepub unsafe fn borrow_unchecked_mut(&self) -> &mut [u8] ⓘ
pub unsafe fn borrow_unchecked_mut(&self) -> &mut [u8] ⓘ
Mutably borrow account data without borrow tracking.
§Safety
The caller must ensure no other borrows (shared or exclusive) are active.
Sourcepub fn try_borrow(&self) -> Result<Ref<'_, [u8]>, ProgramError>
pub fn try_borrow(&self) -> Result<Ref<'_, [u8]>, ProgramError>
Try to obtain a shared borrow of the account data.
Returns Err(AccountBorrowFailed) if the data is exclusively borrowed.
Sourcepub fn try_borrow_mut(&self) -> Result<RefMut<'_, [u8]>, ProgramError>
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, [u8]>, ProgramError>
Try to obtain an exclusive (mutable) borrow of the account data.
Returns Err(AccountBorrowFailed) if the data is already borrowed.
Sourcepub fn segment_ref<T: Pod>(
&self,
offset: u32,
size: u32,
) -> Result<Ref<'_, T>, ProgramError>
pub fn segment_ref<T: Pod>( &self, offset: u32, size: u32, ) -> Result<Ref<'_, T>, ProgramError>
Project a typed segment from account data with native borrow tracking.
Sourcepub unsafe fn segment_ref_unchecked<T: Pod>(
&self,
offset: u32,
) -> Result<Ref<'_, T>, ProgramError>
pub unsafe fn segment_ref_unchecked<T: Pod>( &self, offset: u32, ) -> Result<Ref<'_, T>, ProgramError>
Acquire a shared segment borrow without size/bounds validation.
§Safety
The caller must have already verified:
offset + size_of::<T>()does not overflowoffset + size_of::<T>() <= data_len()- no exclusive borrow overlapping
[offset, offset + size_of::<T>())is live for the returned reference’s lifetime (this method performs no borrow tracking)
Sourcepub fn segment_mut<T: Pod>(
&self,
offset: u32,
size: u32,
) -> Result<RefMut<'_, T>, ProgramError>
pub fn segment_mut<T: Pod>( &self, offset: u32, size: u32, ) -> Result<RefMut<'_, T>, ProgramError>
Project a mutable typed segment from account data with native borrow tracking.
Sourcepub unsafe fn segment_mut_unchecked<T: Pod>(
&self,
offset: u32,
) -> Result<RefMut<'_, T>, ProgramError>
pub unsafe fn segment_mut_unchecked<T: Pod>( &self, offset: u32, ) -> Result<RefMut<'_, T>, ProgramError>
Acquire an exclusive segment borrow without size/bounds/writable validation.
§Safety
The caller must have already verified:
- The account is writable
offset + size_of::<T>()does not overflowoffset + size_of::<T>() <= data_len()- no other borrow (shared or exclusive) overlapping
[offset, offset + size_of::<T>())is live for the returned reference’s lifetime (this method performs no borrow tracking)
Sourcepub unsafe fn raw_ref<T: Pod>(&self) -> Result<Ref<'_, T>, ProgramError>
pub unsafe fn raw_ref<T: Pod>(&self) -> Result<Ref<'_, T>, ProgramError>
Explicit raw typed read of the account buffer.
§Safety
Caller must uphold the invariants documented for this unsafe API before invoking it.
Sourcepub unsafe fn raw_mut<T: Pod>(&self) -> Result<RefMut<'_, T>, ProgramError>
pub unsafe fn raw_mut<T: Pod>(&self) -> Result<RefMut<'_, T>, ProgramError>
Explicit raw typed write of the account buffer.
§Safety
Caller must uphold the invariants documented for this unsafe API before invoking it.
Sourcepub fn check_resize(&self, new_len: usize) -> Result<(), ProgramError>
pub fn check_resize(&self, new_len: usize) -> Result<(), ProgramError>
Check every precondition of resize without changing
the account: the account must be writable, no data borrow may be live,
and new_len may exceed the entry-time length by at most
MAX_PERMITTED_DATA_INCREASE. A no-op resize to the current length
always passes.
Callers that move lamports before resizing (rent top-ups) run this first so a refused resize cannot leave the transfer behind.
Sourcepub fn resize(&self, new_len: usize) -> Result<(), ProgramError>
pub fn resize(&self, new_len: usize) -> Result<(), ProgramError>
Resize the account data to new_len bytes, zeroing any newly
exposed region.
Returns Err(InvalidRealloc) if the new length exceeds the
permitted increase from the original allocation.
When the account grows, the bytes in [old_len, new_len) are
zero-filled. The Solana loader zeroes the realloc reserve once at
the start of an instruction, but a shrink-then-grow within a
single instruction can re-expose previously written bytes; zeroing
on growth makes that impossible. Use resize_raw
for the hot path when the caller will overwrite the grown region
in full and has measured the saved memset.
Sourcepub fn resize_raw(&self, new_len: usize) -> Result<(), ProgramError>
pub fn resize_raw(&self, new_len: usize) -> Result<(), ProgramError>
Resize without zero-filling the newly exposed region.
Same bounds check as resize but skips the
zero-fill on growth. Prefer resize unless the caller immediately
overwrites the entire grown region; otherwise stale bytes from an
earlier shrink within the same instruction can leak into the new
region.
Sourcepub unsafe fn resize_unchecked(&self, new_len: usize)
pub unsafe fn resize_unchecked(&self, new_len: usize)
Resize without bounds checking or zero-filling.
§Safety
The caller must guarantee that the account is writable, no data borrow
is live, and
new_len.saturating_sub(original_data_len) <= MAX_PERMITTED_DATA_INCREASE.
The caller is also responsible for any zero-fill of the grown region
(see resize for why that matters).
Sourcepub fn close(&self) -> ProgramResult
pub fn close(&self) -> ProgramResult
Close the account: zero lamports and data, reassign owner to the System Program.
Fails with AccountBorrowFailed if any data borrow (shared or
exclusive) is outstanding: closing memsets the entire data region,
which would mutate memory a live Ref/RefMut still points at.
Use close_unchecked only when the caller
can prove no borrow is live.
§Caveat
This low-level routine does not verify the caller has
ownership or application authority to close the account. Writability
and outstanding data borrows are checked locally. Solana’s runtime
also enforces account modification rules, but
higher-level APIs (e.g. hopper_runtime::AccountView::close_to)
should pre-check those rules. See account.rs::close_to for
the safe wrapper.
Sourcepub unsafe fn close_unchecked(&self)
pub unsafe fn close_unchecked(&self)
Sourcepub fn account_ptr(&self) -> *const RuntimeAccount
pub fn account_ptr(&self) -> *const RuntimeAccount
Raw pointer to the RuntimeAccount header.
Sourcepub fn require_signer(&self) -> ProgramResult
pub fn require_signer(&self) -> ProgramResult
Validate that this account is a signer, returning a typed error.
Sourcepub fn require_writable(&self) -> ProgramResult
pub fn require_writable(&self) -> ProgramResult
Validate that this account is writable.
Sourcepub fn require_owned_by(&self, program: &Address) -> ProgramResult
pub fn require_owned_by(&self, program: &Address) -> ProgramResult
Validate that this account is owned by the given program.
Sourcepub fn require_payer(&self) -> ProgramResult
pub fn require_payer(&self) -> ProgramResult
Validate signer + writable (common “payer” pattern).
Sourcepub fn disc(&self) -> u8
pub fn disc(&self) -> u8
Read the Hopper account discriminator (first byte of data).
Returns 0 if the account has no data.
Sourcepub fn version(&self) -> u8
pub fn version(&self) -> u8
Read the Hopper account version (second byte of data).
Returns 0 if the account has fewer than 2 bytes.
Sourcepub fn layout_id(&self) -> Option<&[u8; 8]>
pub fn layout_id(&self) -> Option<&[u8; 8]>
Read the 8-byte layout_id from the Hopper account header (bytes 4..12 of account data, per the canonical header format).
Returns None if the account has fewer than 12 bytes.
Sourcepub fn require_disc(&self, expected: u8) -> ProgramResult
pub fn require_disc(&self, expected: u8) -> ProgramResult
Verify that this account has the given discriminator.
Sourcepub fn check_signer(&self) -> Result<&Self, ProgramError>
pub fn check_signer(&self) -> Result<&Self, ProgramError>
Chainable signer check.
Sourcepub fn check_writable(&self) -> Result<&Self, ProgramError>
pub fn check_writable(&self) -> Result<&Self, ProgramError>
Chainable writable check.
Sourcepub fn check_owned_by(&self, program: &Address) -> Result<&Self, ProgramError>
pub fn check_owned_by(&self, program: &Address) -> Result<&Self, ProgramError>
Chainable ownership check.
Sourcepub fn check_disc(&self, expected: u8) -> Result<&Self, ProgramError>
pub fn check_disc(&self, expected: u8) -> Result<&Self, ProgramError>
Chainable discriminator check.
Sourcepub fn check_has_data(&self) -> Result<&Self, ProgramError>
pub fn check_has_data(&self) -> Result<&Self, ProgramError>
Chainable non-empty data check.
Sourcepub fn check_executable(&self) -> Result<&Self, ProgramError>
pub fn check_executable(&self) -> Result<&Self, ProgramError>
Chainable executable check.
Sourcepub fn check_address(&self, expected: &Address) -> Result<&Self, ProgramError>
pub fn check_address(&self, expected: &Address) -> Result<&Self, ProgramError>
Chainable address check.
Sourcepub fn check_data_len(&self, min_len: usize) -> Result<&Self, ProgramError>
pub fn check_data_len(&self, min_len: usize) -> Result<&Self, ProgramError>
Chainable minimum data length check.
Sourcepub fn read_owner(&self) -> Address
pub fn read_owner(&self) -> Address
Read the owner address as a copy (32-byte value).
Unlike owner() (which is unsafe due to reference invalidation
if assign() is called), this returns a copy that is always safe.
Costs 32 bytes of stack space but eliminates aliasing hazards.
Sourcepub fn flags(&self) -> u8
pub fn flags(&self) -> u8
Pack the account’s boolean flags into a single byte for fast comparison.
Bit layout:
- bit 0: is_signer
- bit 1: is_writable
- bit 2: executable
- bit 3: has data (data_len > 0)
Use with expect_flags() for single-instruction multi-check:
// Require: signer + writable + has data
account.expect_flags(0b1011)?;Sourcepub fn expect_flags(&self, required: u8) -> ProgramResult
pub fn expect_flags(&self, required: u8) -> ProgramResult
Check that the account’s flags contain all the required bits.
required is a bitmask of flags that must be set. See flags().
Sourcepub fn is_signer_writable(&self, need_signer: bool, need_writable: bool) -> bool
pub fn is_signer_writable(&self, need_signer: bool, need_writable: bool) -> bool
Fast fused signer/writable predicate over the packed header word.
Answers “are the requested signer/writable bytes both set” with a
single 4-byte header read and one masked compare
((header_u32 & mask) == expected), never touching data_len, unlike
flags, which also folds in the has-data bit via
is_data_empty(). need_signer/need_writable are compile-time
literals at every call site and this is #[inline(always)], so mask
and expected fold to constants and the whole check is one and plus
one cmp.
Behaviourally identical to today’s flags()-based signer/writable
gate: the loader serializes is_signer/is_writable as exactly 0 or
1, so for those bytes “equals the expected 1 pattern” and
“byte non-zero” coincide. Callers that need the precise per-condition
error must fall back to require_signer/require_writable on a false
return (see hopper_runtime::AccountView::expect_signer_writable).