1use crate::host::error_codes::match_result_code;
2
3use crate::core::types::account_id::AccountID;
4use crate::core::types::amount::Amount;
5use crate::host;
6use crate::host::Result;
7
8#[derive(Clone, Copy)]
10pub enum DataRepr {
11 AsUTF8 = 0,
13 AsHex = 1,
15}
16
17#[inline(always)] pub fn trace(msg: &str) -> Result<i32> {
29 let empty_data: &[u8] = &[];
32
33 let result_code = unsafe {
34 host::trace(
35 msg.as_ptr(),
36 msg.len(),
37 empty_data.as_ptr(),
38 0usize,
39 DataRepr::AsUTF8 as _,
40 )
41 };
42
43 match_result_code(result_code, || result_code)
44}
45
46#[inline(always)] pub fn trace_data(msg: &str, data: &[u8], data_repr: DataRepr) -> Result<i32> {
58 let result_code = unsafe {
59 let data_ptr = data.as_ptr();
60 let data_len = data.len();
61 host::trace(msg.as_ptr(), msg.len(), data_ptr, data_len, data_repr as _)
62 };
63
64 match_result_code(result_code, || result_code)
65}
66
67#[inline(always)]
79pub fn trace_num(msg: &str, number: i64) -> Result<i32> {
80 let result_code = unsafe { host::trace_num(msg.as_ptr(), msg.len(), number) };
81 match_result_code(result_code, || result_code)
82}
83
84#[inline(always)]
85pub fn trace_account_buf(msg: &str, account_id: &[u8; 20]) -> Result<i32> {
86 let result_code = unsafe {
87 host::trace_account(
88 msg.as_ptr(),
89 msg.len(),
90 account_id.as_ptr(),
91 account_id.len(),
92 )
93 };
94 match_result_code(result_code, || result_code)
95}
96
97#[inline(always)]
98pub fn trace_account(msg: &str, account_id: &AccountID) -> Result<i32> {
99 let result_code = unsafe {
100 host::trace_account(
101 msg.as_ptr(),
102 msg.len(),
103 account_id.0.as_ptr(),
104 account_id.0.len(),
105 )
106 };
107 match_result_code(result_code, || result_code)
108}
109
110#[inline(always)]
111pub fn trace_amount(msg: &str, amount: &Amount) -> Result<i32> {
112 let (amount_bytes, len) = amount.to_stamount_bytes();
114
115 let result_code =
116 unsafe { host::trace_amount(msg.as_ptr(), msg.len(), amount_bytes.as_ptr(), len) };
117
118 match_result_code(result_code, || result_code)
119}
120
121#[inline(always)]
123pub fn trace_float(msg: &str, f: &[u8; 8]) -> Result<i32> {
124 let result_code = unsafe { host::trace_opaque_float(msg.as_ptr(), msg.len(), f.as_ptr(), 8) };
125 match_result_code(result_code, || result_code)
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131 use crate::core::types::amount::Amount;
132
133 #[test]
134 fn test_trace_amount_xrp() {
135 let amount = Amount::XRP {
137 num_drops: 1_000_000,
138 };
139 let message = "Test XRP amount";
140
141 let result = trace_amount(message, &amount);
143
144 assert!(result.is_ok());
146 }
147
148 #[test]
149 fn test_trace_amount_mpt() {
150 use crate::core::types::account_id::AccountID;
152 use crate::core::types::mpt_id::MptId;
153
154 const VALUE: u64 = 500_000;
155 const SEQUENCE_NUM: u32 = 12345;
156 const ISSUER_BYTES: [u8; 20] = [1u8; 20];
157
158 let issuer = AccountID::from(ISSUER_BYTES);
159 let mpt_id = MptId::new(SEQUENCE_NUM, issuer);
160 let amount = Amount::MPT {
161 num_units: VALUE,
162 is_positive: true,
163 mpt_id,
164 };
165
166 let message = "Test MPT amount";
167
168 let result = trace_amount(message, &amount);
170
171 assert!(result.is_ok());
173 }
174
175 #[test]
176 fn test_trace_amount_iou() {
177 use crate::core::types::account_id::AccountID;
179 use crate::core::types::currency::Currency;
180 use crate::core::types::opaque_float::OpaqueFloat;
181
182 let currency_bytes = [2u8; 20];
183 let issuer_bytes = [3u8; 20];
184 let amount_bytes = [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39]; let currency = Currency::from(currency_bytes);
187 let issuer = AccountID::from(issuer_bytes);
188 let amount = OpaqueFloat(amount_bytes);
189
190 let amount = Amount::IOU {
191 amount,
192 issuer,
193 currency,
194 };
195
196 let message = "Test IOU amount";
197
198 let result = trace_amount(message, &amount);
200
201 assert!(result.is_ok());
203 }
204
205 #[test]
206 fn test_trace_amount_negative_xrp() {
207 let amount = Amount::XRP {
209 num_drops: -1_000_000,
210 };
211 let message = "Test negative XRP amount";
212
213 let result = trace_amount(message, &amount);
215
216 assert!(result.is_ok());
218 }
219
220 #[test]
221 fn test_trace_bytes_format() {
222 let xrp_amount = Amount::XRP {
224 num_drops: 1_000_000,
225 };
226 let (_bytes, len) = xrp_amount.to_stamount_bytes();
227 assert_eq!(len, 48); let fee_amount = Amount::XRP { num_drops: 10 };
231 let (bytes, len) = fee_amount.to_stamount_bytes();
232 assert_eq!(len, 48); let expected_bytes = [64, 0, 0, 0, 0, 0, 0, 10];
237 assert_eq!(&bytes[0..8], &expected_bytes);
238
239 use crate::core::types::account_id::AccountID;
241 use crate::core::types::currency::Currency;
242 use crate::core::types::opaque_float::OpaqueFloat;
243
244 let currency_bytes = [2u8; 20];
245 let issuer_bytes = [3u8; 20];
246 let amount_bytes = [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39];
247
248 let iou_amount = Amount::IOU {
249 amount: OpaqueFloat(amount_bytes),
250 issuer: AccountID::from(issuer_bytes),
251 currency: Currency::from(currency_bytes),
252 };
253 let (bytes, len) = iou_amount.to_stamount_bytes();
254 assert_eq!(len, 48); assert_eq!(&bytes[0..8], &amount_bytes); use crate::core::types::mpt_id::MptId;
259
260 const VALUE: u64 = 500_000;
261 const SEQUENCE_NUM: u32 = 12345;
262 const ISSUER_BYTES: [u8; 20] = [1u8; 20];
263
264 let issuer = AccountID::from(ISSUER_BYTES);
265 let mpt_id = MptId::new(SEQUENCE_NUM, issuer);
266 let mpt_amount = Amount::MPT {
267 num_units: VALUE,
268 is_positive: true,
269 mpt_id,
270 };
271 let (bytes, len) = mpt_amount.to_stamount_bytes();
272 assert_eq!(len, 48); assert_eq!(bytes[0], 0b_0110_0000); assert_eq!(&bytes[1..9], &VALUE.to_be_bytes()); }
276}