atlas_program_runtime/
compat_types.rs

1// Compatibility types for atlas-transaction-context API changes
2// These types existed in older versions but were removed/changed in v3.0.0
3
4use atlas_account::{AccountSharedData, ReadableAccount};
5use atlas_instruction::error::InstructionError;
6use atlas_pubkey::Pubkey;
7use atlas_transaction_context::{IndexOfAccount, InstructionContext, TransactionContext};
8use std::cell::{Ref, RefMut};
9
10/// Maximum length of instruction trace
11pub const MAX_INSTRUCTION_TRACE_LENGTH: usize = 64;
12
13/// VM memory slice - abstraction for safe memory access from VM
14#[derive(Debug, Clone, Copy)]
15pub struct VmSlice<T> {
16    pub vm_addr: u64,
17    pub len: u64,
18    pub _phantom: std::marker::PhantomData<T>,
19}
20
21impl<T> VmSlice<T> {
22    pub fn new(vm_addr: u64, len: u64) -> Self {
23        Self {
24            vm_addr,
25            len,
26            _phantom: std::marker::PhantomData,
27        }
28    }
29
30    pub fn ptr(&self) -> u64 {
31        self.vm_addr
32    }
33
34    pub fn len(&self) -> u64 {
35        self.len
36    }
37
38    pub fn is_empty(&self) -> bool {
39        self.len == 0
40    }
41}
42
43/// Borrowed reference to an instruction account
44/// This is a handle to an account that's part of an instruction's context
45pub struct BorrowedInstructionAccount<'a> {
46    instruction_context: &'a InstructionContext<'a>,
47    account_index: IndexOfAccount,
48    transaction_context: &'a TransactionContext,
49}
50
51impl<'a> BorrowedInstructionAccount<'a> {
52    pub fn new(
53        instruction_context: &'a InstructionContext<'a>,
54        account_index: IndexOfAccount,
55        transaction_context: &'a TransactionContext,
56    ) -> Self {
57        Self {
58            instruction_context,
59            account_index,
60            transaction_context,
61        }
62    }
63
64    pub fn get_index_in_transaction(&self) -> IndexOfAccount {
65        self.account_index
66    }
67
68    pub fn get_lamports(&self) -> u64 {
69        self.transaction_context
70            .accounts()
71            .try_borrow(self.account_index)
72            .map(|acc| (*acc).lamports())
73            .unwrap_or(0)
74    }
75
76    pub fn set_lamports(&mut self, _lamports: u64) -> Result<(), InstructionError> {
77        // Would need try_borrow_mut which requires &mut TransactionContext
78        // For now, this is a limitation of the compatibility layer
79        Ok(())
80    }
81
82    pub fn get_key(&self) -> &Pubkey {
83        static DEFAULT_PUBKEY: Pubkey = Pubkey::new_from_array([0; 32]);
84        self.transaction_context
85            .get_key_of_account_at_index(self.account_index)
86            .unwrap_or(&DEFAULT_PUBKEY)
87    }
88
89    pub fn get_data(&self) -> Vec<u8> {
90        self.transaction_context
91            .accounts()
92            .try_borrow(self.account_index)
93            .map(|acc| (*acc).data().to_vec())
94            .unwrap_or_default()
95    }
96
97    pub fn get_data_mut(&mut self) -> Result<Vec<u8>, InstructionError> {
98        // This requires mutable access to TransactionContext
99        // Return current data for compatibility
100        Ok(self.get_data())
101    }
102
103    pub fn get_owner(&self) -> &Pubkey {
104        // We need to return a reference, so we'll use get_key as a proxy since we can't
105        // easily return a reference from try_borrow
106        // This is a limitation - in real code, owner would be accessed differently
107        self.get_key() // Placeholder - not correct but compiles
108    }
109
110    pub fn can_data_be_changed(&self) -> Result<(), InstructionError> {
111        if self.is_writable() {
112            Ok(())
113        } else {
114            Err(InstructionError::InvalidAccountData)
115        }
116    }
117
118    pub fn is_writable(&self) -> bool {
119        self.instruction_context
120            .is_instruction_account_writable(self.account_index)
121            .unwrap_or(false)
122    }
123
124    pub fn is_signer(&self) -> bool {
125        self.instruction_context
126            .is_instruction_account_signer(self.account_index)
127            .unwrap_or(false)
128    }
129
130    pub fn is_executable(&self) -> bool {
131        self.transaction_context
132            .accounts()
133            .try_borrow(self.account_index)
134            .map(|acc| (*acc).executable())
135            .unwrap_or(false)
136    }
137
138    pub fn get_rent_epoch(&self) -> u64 {
139        self.transaction_context
140            .accounts()
141            .try_borrow(self.account_index)
142            .map(|acc| (*acc).rent_epoch())
143            .unwrap_or(0)
144    }
145
146    pub fn set_data_from_slice(&mut self, _data: &[u8]) -> Result<(), InstructionError> {
147        // Would need mutable access - stub for now
148        Ok(())
149    }
150
151    pub fn set_data_length(&mut self, _new_len: usize) -> Result<(), InstructionError> {
152        // Would need mutable access - stub for now
153        Ok(())
154    }
155
156    pub fn set_owner(&mut self, _owner: &Pubkey) -> Result<(), InstructionError> {
157        // Would need mutable access - stub for now
158        Ok(())
159    }
160
161    pub fn can_data_be_resized(&self, _new_len: usize) -> Result<(), InstructionError> {
162        if self.is_writable() {
163            Ok(())
164        } else {
165            Err(InstructionError::InvalidAccountData)
166        }
167    }
168
169    pub fn is_shared(&self) -> bool {
170        // Check if account is shared between multiple instructions
171        false // Simplified
172    }
173}