Skip to main content

thru_base/
tn_runtime_utils.rs

1//! Runtime error utilities for converting error codes to human-readable strings
2
3/// Transaction Runtime Error Codes - ported from src/thru/runtime/tn_runtime_errors.h
4
5// Error class definitions
6const TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE: i32 = 0xFFFFFF00_u32 as i32;
7const TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE: i32 = 0xFFFFFE00_u32 as i32;
8const TN_RUNTIME_ERR_CLASS__TXN_IN_EXECUTE: i32 = 0xFFFFFD00_u32 as i32;
9
10// Success code
11const TN_RUNTIME_TXN_EXECUTE_SUCCESS: i32 = 0;
12
13// Transaction Validation Errors
14const TN_RUNTIME_TXN_ERR_INVALID_FORMAT: i32 = 0x01 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
15const TN_RUNTIME_TXN_ERR_INVALID_VERSION: i32 = 0x02 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
16const TN_RUNTIME_TXN_ERR_INVALID_FLAGS: i32 = 0x03 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
17const TN_RUNTIME_TXN_ERR_INVALID_SIGNATURE: i32 = 0x04 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
18const TN_RUNTIME_TXN_ERR_DUPLICATE_ACCOUNT: i32 = 0x05 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
19const TN_RUNTIME_TXN_ERR_UNSORTED_ACCOUNTS: i32 = 0x06 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
20const TN_RUNTIME_TXN_ERR_UNSORTED_READWRITE_ACCOUNTS: i32 =
21    0x07 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
22const TN_RUNTIME_TXN_ERR_UNSORTED_READONLY_ACCOUNTS: i32 =
23    0x08 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
24const TN_RUNTIME_TXN_ERR_ACCOUNT_COUNT_LIMIT_EXCEEDED: i32 =
25    0x09 | TN_RUNTIME_ERR_CLASS__TXN_IN_VALIDATE;
26
27// Transaction Pre-Execute Errors
28const TN_RUNTIME_TXN_ERR_NONCE_TOO_LOW: i32 = 0x01 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
29const TN_RUNTIME_TXN_ERR_NONCE_TOO_HIGH: i32 = 0x02 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
30const TN_RUNTIME_TXN_ERR_INSUFFICIENT_FEE_PAYER_BALANCE: i32 =
31    0x03 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
32const TN_RUNTIME_TXN_ERR_FEE_PAYER_ACCOUNT_DOES_NOT_EXIST: i32 =
33    0x04 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
34const TN_RUNTIME_TXN_ERR_NOT_LIVE_YET: i32 = 0x05 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
35const TN_RUNTIME_TXN_ERR_EXPIRED: i32 = 0x06 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
36const TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF: i32 =
37    0x07 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
38const TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_TYPE: i32 =
39    0x08 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
40const TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_SLOT: i32 =
41    0x09 | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
42const TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_ACCOUNT_OWNER: i32 =
43    0x0A | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
44const TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_ACCOUNT_OWNER: i32 =
45    0x0B | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
46const TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_ACCOUNT_META_DATA_SZ: i32 =
47    0x0C | TN_RUNTIME_ERR_CLASS__TXN_IN_PRE_EXECUTE;
48
49// Transaction Execute Errors
50const TN_RUNTIME_TXN_ERR_VM_FAILED: i32 = 0x01 | TN_RUNTIME_ERR_CLASS__TXN_IN_EXECUTE;
51const TN_RUNTIME_TXN_ERR_INVALID_PROGRAM_ACCOUNT: i32 = 0x02 | TN_RUNTIME_ERR_CLASS__TXN_IN_EXECUTE;
52const TN_RUNTIME_TXN_ERR_VM_REVERT: i32 = 0x03 | TN_RUNTIME_ERR_CLASS__TXN_IN_EXECUTE;
53const TN_RUNTIME_TXN_ERR_CU_EXHAUSTED: i32 = 0x04 | TN_RUNTIME_ERR_CLASS__TXN_IN_EXECUTE;
54const TN_RUNTIME_TXN_ERR_SU_EXHAUSTED: i32 = 0x05 | TN_RUNTIME_ERR_CLASS__TXN_IN_EXECUTE;
55
56/// Convert VM error code to human-readable string
57///
58/// This is a Rust port of the `tn_runtime_error_to_str` function from
59/// `src/thru/runtime/tn_runtime_errors.c`
60///
61/// # Arguments
62/// * `err` - The error code to convert
63///
64/// # Returns
65/// * `Some(&str)` - Human-readable error string if error code is recognized
66/// * `None` - If error code is not recognized
67pub fn tn_vm_error_str(err: i32) -> Option<&'static str> {
68    match err {
69        TN_RUNTIME_TXN_EXECUTE_SUCCESS => Some("TN_RUNTIME_TXN_EXECUTE_SUCCESS"),
70        TN_RUNTIME_TXN_ERR_INVALID_FORMAT => Some("TN_RUNTIME_TXN_ERR_INVALID_FORMAT"),
71        TN_RUNTIME_TXN_ERR_INVALID_VERSION => Some("TN_RUNTIME_TXN_ERR_INVALID_VERSION"),
72        TN_RUNTIME_TXN_ERR_INVALID_FLAGS => Some("TN_RUNTIME_TXN_ERR_INVALID_FLAGS"),
73        TN_RUNTIME_TXN_ERR_INVALID_SIGNATURE => Some("TN_RUNTIME_TXN_ERR_INVALID_SIGNATURE"),
74        TN_RUNTIME_TXN_ERR_DUPLICATE_ACCOUNT => Some("TN_RUNTIME_TXN_ERR_DUPLICATE_ACCOUNT"),
75        TN_RUNTIME_TXN_ERR_UNSORTED_ACCOUNTS => Some("TN_RUNTIME_TXN_ERR_UNSORTED_ACCOUNTS"),
76        TN_RUNTIME_TXN_ERR_UNSORTED_READWRITE_ACCOUNTS => {
77            Some("TN_RUNTIME_TXN_ERR_UNSORTED_READWRITE_ACCOUNTS")
78        }
79        TN_RUNTIME_TXN_ERR_UNSORTED_READONLY_ACCOUNTS => {
80            Some("TN_RUNTIME_TXN_ERR_UNSORTED_READONLY_ACCOUNTS")
81        }
82        TN_RUNTIME_TXN_ERR_ACCOUNT_COUNT_LIMIT_EXCEEDED => {
83            Some("TN_RUNTIME_TXN_ERR_ACCOUNT_COUNT_LIMIT_EXCEEDED")
84        }
85        TN_RUNTIME_TXN_ERR_NONCE_TOO_LOW => Some("TN_RUNTIME_TXN_ERR_NONCE_TOO_LOW"),
86        TN_RUNTIME_TXN_ERR_NONCE_TOO_HIGH => Some("TN_RUNTIME_TXN_ERR_NONCE_TOO_HIGH"),
87        TN_RUNTIME_TXN_ERR_INSUFFICIENT_FEE_PAYER_BALANCE => {
88            Some("TN_RUNTIME_TXN_ERR_INSUFFICIENT_FEE_PAYER_BALANCE")
89        }
90        TN_RUNTIME_TXN_ERR_FEE_PAYER_ACCOUNT_DOES_NOT_EXIST => {
91            Some("TN_RUNTIME_TXN_ERR_FEE_PAYER_ACCOUNT_DOES_NOT_EXIST")
92        }
93        TN_RUNTIME_TXN_ERR_NOT_LIVE_YET => Some("TN_RUNTIME_TXN_ERR_NOT_LIVE_YET"),
94        TN_RUNTIME_TXN_ERR_EXPIRED => Some("TN_RUNTIME_TXN_ERR_EXPIRED"),
95        TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF => {
96            Some("TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF")
97        }
98        TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_TYPE => {
99            Some("TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_TYPE")
100        }
101        TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_SLOT => {
102            Some("TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_SLOT")
103        }
104        TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_ACCOUNT_OWNER => {
105            Some("TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_ACCOUNT_OWNER")
106        }
107        TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_ACCOUNT_OWNER => {
108            Some("TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_ACCOUNT_OWNER")
109        }
110        TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_ACCOUNT_META_DATA_SZ => {
111            Some("TN_RUNTIME_TXN_ERR_INVALID_FEE_PAYER_STATE_PROOF_ACCOUNT_META_DATA_SZ")
112        }
113        TN_RUNTIME_TXN_ERR_VM_FAILED => Some("TN_RUNTIME_TXN_ERR_VM_FAILED"),
114        TN_RUNTIME_TXN_ERR_INVALID_PROGRAM_ACCOUNT => {
115            Some("TN_RUNTIME_TXN_ERR_INVALID_PROGRAM_ACCOUNT")
116        }
117        TN_RUNTIME_TXN_ERR_VM_REVERT => Some("TN_RUNTIME_TXN_ERR_VM_REVERT"),
118        TN_RUNTIME_TXN_ERR_CU_EXHAUSTED => Some("TN_RUNTIME_TXN_ERR_CU_EXHAUSTED"),
119        TN_RUNTIME_TXN_ERR_SU_EXHAUSTED => Some("TN_RUNTIME_TXN_ERR_SU_EXHAUSTED"),
120        _ => None,
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn test_tn_vm_error_str_success() {
130        assert_eq!(
131            tn_vm_error_str(TN_RUNTIME_TXN_EXECUTE_SUCCESS),
132            Some("TN_RUNTIME_TXN_EXECUTE_SUCCESS")
133        );
134    }
135
136    #[test]
137    fn test_tn_vm_error_str_validation_errors() {
138        assert_eq!(
139            tn_vm_error_str(TN_RUNTIME_TXN_ERR_INVALID_FORMAT),
140            Some("TN_RUNTIME_TXN_ERR_INVALID_FORMAT")
141        );
142        assert_eq!(
143            tn_vm_error_str(TN_RUNTIME_TXN_ERR_INVALID_VERSION),
144            Some("TN_RUNTIME_TXN_ERR_INVALID_VERSION")
145        );
146        assert_eq!(
147            tn_vm_error_str(TN_RUNTIME_TXN_ERR_INVALID_FLAGS),
148            Some("TN_RUNTIME_TXN_ERR_INVALID_FLAGS")
149        );
150        assert_eq!(
151            tn_vm_error_str(TN_RUNTIME_TXN_ERR_INVALID_SIGNATURE),
152            Some("TN_RUNTIME_TXN_ERR_INVALID_SIGNATURE")
153        );
154        assert_eq!(
155            tn_vm_error_str(TN_RUNTIME_TXN_ERR_DUPLICATE_ACCOUNT),
156            Some("TN_RUNTIME_TXN_ERR_DUPLICATE_ACCOUNT")
157        );
158    }
159
160    #[test]
161    fn test_tn_vm_error_str_pre_execute_errors() {
162        assert_eq!(
163            tn_vm_error_str(TN_RUNTIME_TXN_ERR_NONCE_TOO_LOW),
164            Some("TN_RUNTIME_TXN_ERR_NONCE_TOO_LOW")
165        );
166        assert_eq!(
167            tn_vm_error_str(TN_RUNTIME_TXN_ERR_NONCE_TOO_HIGH),
168            Some("TN_RUNTIME_TXN_ERR_NONCE_TOO_HIGH")
169        );
170        assert_eq!(
171            tn_vm_error_str(TN_RUNTIME_TXN_ERR_INSUFFICIENT_FEE_PAYER_BALANCE),
172            Some("TN_RUNTIME_TXN_ERR_INSUFFICIENT_FEE_PAYER_BALANCE")
173        );
174    }
175
176    #[test]
177    fn test_tn_vm_error_str_execute_errors() {
178        assert_eq!(
179            tn_vm_error_str(TN_RUNTIME_TXN_ERR_VM_FAILED),
180            Some("TN_RUNTIME_TXN_ERR_VM_FAILED")
181        );
182        assert_eq!(
183            tn_vm_error_str(TN_RUNTIME_TXN_ERR_VM_REVERT),
184            Some("TN_RUNTIME_TXN_ERR_VM_REVERT")
185        );
186        assert_eq!(
187            tn_vm_error_str(TN_RUNTIME_TXN_ERR_CU_EXHAUSTED),
188            Some("TN_RUNTIME_TXN_ERR_CU_EXHAUSTED")
189        );
190    }
191
192    #[test]
193    fn test_tn_vm_error_str_unknown() {
194        assert_eq!(tn_vm_error_str(999999), None);
195        assert_eq!(tn_vm_error_str(-1), None);
196    }
197}