use atlas_account::{AccountSharedData, ReadableAccount};
use atlas_instruction::error::InstructionError;
use atlas_pubkey::Pubkey;
use atlas_transaction_context::{IndexOfAccount, InstructionContext, TransactionContext};
use std::cell::{Ref, RefMut};
pub const MAX_INSTRUCTION_TRACE_LENGTH: usize = 64;
#[derive(Debug, Clone, Copy)]
pub struct VmSlice<T> {
pub vm_addr: u64,
pub len: u64,
pub _phantom: std::marker::PhantomData<T>,
}
impl<T> VmSlice<T> {
pub fn new(vm_addr: u64, len: u64) -> Self {
Self {
vm_addr,
len,
_phantom: std::marker::PhantomData,
}
}
pub fn ptr(&self) -> u64 {
self.vm_addr
}
pub fn len(&self) -> u64 {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
}
pub struct BorrowedInstructionAccount<'a> {
instruction_context: &'a InstructionContext<'a>,
account_index: IndexOfAccount,
transaction_context: &'a TransactionContext,
}
impl<'a> BorrowedInstructionAccount<'a> {
pub fn new(
instruction_context: &'a InstructionContext<'a>,
account_index: IndexOfAccount,
transaction_context: &'a TransactionContext,
) -> Self {
Self {
instruction_context,
account_index,
transaction_context,
}
}
pub fn get_index_in_transaction(&self) -> IndexOfAccount {
self.account_index
}
pub fn get_lamports(&self) -> u64 {
self.transaction_context
.accounts()
.try_borrow(self.account_index)
.map(|acc| (*acc).lamports())
.unwrap_or(0)
}
pub fn set_lamports(&mut self, _lamports: u64) -> Result<(), InstructionError> {
Ok(())
}
pub fn get_key(&self) -> &Pubkey {
static DEFAULT_PUBKEY: Pubkey = Pubkey::new_from_array([0; 32]);
self.transaction_context
.get_key_of_account_at_index(self.account_index)
.unwrap_or(&DEFAULT_PUBKEY)
}
pub fn get_data(&self) -> Vec<u8> {
self.transaction_context
.accounts()
.try_borrow(self.account_index)
.map(|acc| (*acc).data().to_vec())
.unwrap_or_default()
}
pub fn get_data_mut(&mut self) -> Result<Vec<u8>, InstructionError> {
Ok(self.get_data())
}
pub fn get_owner(&self) -> &Pubkey {
self.get_key() }
pub fn can_data_be_changed(&self) -> Result<(), InstructionError> {
if self.is_writable() {
Ok(())
} else {
Err(InstructionError::InvalidAccountData)
}
}
pub fn is_writable(&self) -> bool {
self.instruction_context
.is_instruction_account_writable(self.account_index)
.unwrap_or(false)
}
pub fn is_signer(&self) -> bool {
self.instruction_context
.is_instruction_account_signer(self.account_index)
.unwrap_or(false)
}
pub fn is_executable(&self) -> bool {
self.transaction_context
.accounts()
.try_borrow(self.account_index)
.map(|acc| (*acc).executable())
.unwrap_or(false)
}
pub fn get_rent_epoch(&self) -> u64 {
self.transaction_context
.accounts()
.try_borrow(self.account_index)
.map(|acc| (*acc).rent_epoch())
.unwrap_or(0)
}
pub fn set_data_from_slice(&mut self, _data: &[u8]) -> Result<(), InstructionError> {
Ok(())
}
pub fn set_data_length(&mut self, _new_len: usize) -> Result<(), InstructionError> {
Ok(())
}
pub fn set_owner(&mut self, _owner: &Pubkey) -> Result<(), InstructionError> {
Ok(())
}
pub fn can_data_be_resized(&self, _new_len: usize) -> Result<(), InstructionError> {
if self.is_writable() {
Ok(())
} else {
Err(InstructionError::InvalidAccountData)
}
}
pub fn is_shared(&self) -> bool {
false }
}