rialo_types/transaction_execution_results.rs
1// Copyright (c) Subzero Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4#[cfg(feature = "non-pdk")]
5use rialo_s_message::inner_instruction::InnerInstructionsList;
6use rialo_s_pubkey::Pubkey;
7use serde::{Deserialize, Serialize};
8
9/// Details about the fees associated with a transaction.
10///
11/// This structure contains information about both the base transaction fee
12/// and any additional prioritization fees that may have been applied.
13#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
14pub struct FeeDetails {
15 /// The base transaction fee required for processing the transaction
16 pub transaction_fee: u64,
17 /// Additional fee paid to prioritize the transaction
18 pub prioritization_fee: u64,
19}
20
21impl FeeDetails {
22 /// Creates a new `FeeDetails` instance with the specified fees.
23 ///
24 /// # Arguments
25 ///
26 /// * `transaction_fee` - The base transaction fee
27 /// * `prioritization_fee` - The additional prioritization fee
28 ///
29 /// # Returns
30 ///
31 /// A new `FeeDetails` instance with the specified fees
32 pub fn new(transaction_fee: u64, prioritization_fee: u64) -> Self {
33 Self {
34 transaction_fee,
35 prioritization_fee,
36 }
37 }
38
39 /// Calculates the total fee by adding the transaction fee and prioritization fee.
40 ///
41 /// Uses saturating addition to prevent overflow.
42 ///
43 /// # Returns
44 ///
45 /// The sum of the transaction fee and prioritization fee
46 pub fn total_fee(&self) -> u64 {
47 self.transaction_fee.saturating_add(self.prioritization_fee)
48 }
49}
50
51/// Re-export InstructionError from rialo-shared-types for backwards compatibility
52pub use rialo_shared_types::InstructionError;
53/// Re-export TransactionError from rialo-shared-types for backwards compatibility
54pub use rialo_shared_types::TransactionError;
55
56/// Execution results of a transaction.
57///
58/// This structure contains the complete execution results for a transaction,
59/// including timing information, block height, and detailed execution results.
60#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
61pub struct TransactionExecutionResults {
62 /// Unix timestamp when the transaction was executed
63 pub timestamp: u64,
64 /// Block height at which the transaction was included
65 pub block_height: u64,
66 /// Detailed execution results of the committed transaction
67 pub committed_transaction: CommittedTransaction,
68 /// The 0-based index of this transaction within its block.
69 #[serde(default)]
70 pub transaction_index_in_block: u32,
71 /// The pubkey of the subscription that triggered this transaction.
72 /// None if the transaction was not triggered by a subscription.
73 #[serde(default)]
74 pub subscription_pubkey: Option<Pubkey>,
75}
76
77/// Return data at the end of a transaction
78#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
79pub struct TransactionReturnData {
80 /// The program ID that returned the data
81 pub program_id: Pubkey,
82 /// The binary data returned by the program
83 pub data: Vec<u8>,
84}
85
86impl TransactionReturnData {
87 pub fn new(program_id: Pubkey, data: Vec<u8>) -> Self {
88 Self { program_id, data }
89 }
90}
91
92/// Statistics about accounts loaded during transaction execution.
93#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
94pub struct TransactionLoadedAccountsStats {
95 /// The total number of bytes of account data loaded
96 pub loaded_accounts_data_size: u32,
97 /// The total number of accounts (read or writable) loaded
98 pub loaded_accounts_count: usize,
99}
100
101impl TransactionLoadedAccountsStats {
102 pub fn new(loaded_accounts_data_size: u32, loaded_accounts_count: usize) -> Self {
103 Self {
104 loaded_accounts_data_size,
105 loaded_accounts_count,
106 }
107 }
108}
109
110/// The details of the transaction execution results.
111///
112/// Contains comprehensive information about a committed transaction,
113/// including logs, fees, and any errors that occurred during execution.
114#[derive(Clone, Debug, Default, Serialize, Deserialize)]
115pub struct CommittedTransaction {
116 /// Error that occurred during transaction execution, if any
117 pub transaction_error: Option<TransactionError>,
118 /// Optional log messages generated during transaction execution
119 /// by Rialo programs
120 pub log_messages: Option<Vec<String>>,
121 /// Inner instructions executed by the main program via CPI
122 #[cfg(feature = "non-pdk")]
123 pub inner_instructions: Option<InnerInstructionsList>,
124 /// Return data from the main invoked program in the transaction
125 pub return_data: Option<TransactionReturnData>,
126 /// Number of compute units used by the transaction execution
127 pub executed_units: u64,
128 /// Fee details for the transaction
129 pub fee_details: FeeDetails,
130 /// Statistics about accounts loaded during transaction execution
131 pub loaded_account_stats: TransactionLoadedAccountsStats,
132}
133
134#[cfg(any(test, feature = "testing", feature = "dev-context-only-utils"))]
135impl TransactionExecutionResults {
136 /// Creates a new `TransactionExecutionResults` instance for testing purposes.
137 ///
138 /// This method creates a minimal instance with default values,
139 /// primarily used in unit tests.
140 ///
141 /// # Returns
142 ///
143 /// A new instance with timestamp 0, block height 0, and default committed transaction
144 pub fn new_for_testing() -> Self {
145 Self {
146 timestamp: 0,
147 block_height: 0,
148 committed_transaction: CommittedTransaction::default(),
149 transaction_index_in_block: 0,
150 subscription_pubkey: None,
151 }
152 }
153
154 /// Creates a new `TransactionExecutionResults` instance for testing with a specific timestamp.
155 ///
156 /// # Arguments
157 ///
158 /// * `timestamp` - The unix timestamp to use for the transaction
159 ///
160 /// # Returns
161 ///
162 /// A new instance with the specified timestamp, block height 0, and default committed transaction
163 pub fn new_for_testing_with_timestamp(timestamp: u64) -> Self {
164 Self {
165 timestamp,
166 block_height: 0,
167 committed_transaction: CommittedTransaction::default(),
168 transaction_index_in_block: 0,
169 subscription_pubkey: None,
170 }
171 }
172
173 /// Creates a new `TransactionExecutionResults` instance for testing with detailed parameters.
174 ///
175 /// # Arguments
176 ///
177 /// * `timestamp` - The unix timestamp for the transaction
178 /// * `block_height` - The block height at which the transaction was included
179 /// * `log_messages` - Optional log messages generated during execution
180 ///
181 /// # Returns
182 ///
183 /// A new instance with the specified parameters and default fee details
184 pub fn new_for_testing_with_details(
185 timestamp: u64,
186 block_height: u64,
187 log_messages: Option<Vec<String>>,
188 ) -> Self {
189 Self {
190 timestamp,
191 block_height,
192 committed_transaction: CommittedTransaction {
193 transaction_error: None,
194 log_messages,
195 #[cfg(feature = "non-pdk")]
196 inner_instructions: None,
197 return_data: None,
198 executed_units: 0,
199 fee_details: FeeDetails::default(),
200 loaded_account_stats: TransactionLoadedAccountsStats::default(),
201 },
202 transaction_index_in_block: 0,
203 subscription_pubkey: None,
204 }
205 }
206}
207
208/// Metadata for address signatures.
209///
210/// Contains information about an address (account) within a transaction (signature).
211#[derive(Clone, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
212pub struct AddressSignatureMetadata {
213 /// Whether this address was marked as writable in the transaction
214 pub writeable: bool,
215}