Skip to main content

xrpl/core/binarycodec/
binary_wrappers.rs

1use super::definitions::*;
2use super::types::TryFromParser;
3use super::types::{
4    AccountId, Amount, Blob, Hash128, Hash160, Hash192, Hash256, Issue, PathSet, STObject,
5    Vector256, XChainBridge,
6};
7use crate::core::binarycodec::exceptions::XRPLBinaryCodecException;
8use crate::core::binarycodec::utils::*;
9use crate::core::exceptions::XRPLCoreException;
10use crate::core::exceptions::XRPLCoreResult;
11use crate::utils::ToBytes;
12use crate::XRPLSerdeJsonError;
13use alloc::borrow::ToOwned;
14use alloc::string::String;
15use alloc::string::ToString;
16use alloc::vec;
17use alloc::vec::Vec;
18use core::convert::TryFrom;
19use core::convert::TryInto;
20use hex::ToHex;
21use serde::Serialize;
22use serde_json::{Map, Value};
23
24/// Serializes JSON to XRPL binary format.
25pub type BinarySerializer = Vec<u8>;
26
27/// Deserializes from hex-encoded XRPL binary format to
28/// serde JSON fields and values.
29///
30/// # Examples
31///
32/// ## Basic usage
33///
34/// ```
35/// use xrpl::core::binarycodec::BinaryParser;
36/// use xrpl::core::Parser;
37/// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
38///
39/// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
40/// let binary_parser: BinaryParser = BinaryParser::from(test_bytes);
41///
42/// assert_eq!(binary_parser, test_bytes[..]);
43/// ```
44#[derive(Debug, Clone)]
45pub struct BinaryParser(Vec<u8>);
46
47/// Helper function for length-prefixed fields including
48/// Blob types and some AccountID types. Calculates the
49/// prefix of variable length bytes.
50///
51/// The length of the prefix is 1-3 bytes depending on the
52/// length of the contents:
53/// Content length <= 192 bytes: prefix is 1 byte
54/// 192 bytes < Content length <= 12480 bytes: prefix is 2 bytes
55/// 12480 bytes < Content length <= 918744 bytes: prefix is 3 bytes
56///
57/// See Length Prefixing:
58/// `<https://xrpl.org/serialization.html#length-prefixing>`
59fn _encode_variable_length_prefix(length: &usize) -> XRPLCoreResult<Vec<u8>> {
60    if length <= &MAX_SINGLE_BYTE_LENGTH {
61        Ok([*length as u8].to_vec())
62    } else if length < &MAX_DOUBLE_BYTE_LENGTH {
63        let mut bytes = vec![];
64        let b_length = *length - (MAX_SINGLE_BYTE_LENGTH + 1);
65        let val_a: u8 = ((b_length >> 8) + (MAX_SINGLE_BYTE_LENGTH + 1))
66            .try_into()
67            .map_err(XRPLBinaryCodecException::TryFromIntError)?;
68        let val_b: u8 = (b_length & 0xFF)
69            .try_into()
70            .map_err(XRPLBinaryCodecException::TryFromIntError)?;
71
72        bytes.extend_from_slice(&[val_a]);
73        bytes.extend_from_slice(&[val_b]);
74
75        Ok(bytes)
76    } else if length <= &MAX_LENGTH_VALUE {
77        let mut bytes = vec![];
78        let b_length = *length - MAX_DOUBLE_BYTE_LENGTH;
79        let val_a: u8 = ((MAX_SECOND_BYTE_VALUE + 1) + (b_length >> 16))
80            .try_into()
81            .map_err(XRPLBinaryCodecException::TryFromIntError)?;
82        let val_b: u8 = ((b_length >> 8) & 0xFF)
83            .try_into()
84            .map_err(XRPLBinaryCodecException::TryFromIntError)?;
85        let val_c: u8 = (b_length & 0xFF)
86            .try_into()
87            .map_err(XRPLBinaryCodecException::TryFromIntError)?;
88
89        bytes.extend_from_slice(&[val_a]);
90        bytes.extend_from_slice(&[val_b]);
91        bytes.extend_from_slice(&[val_c]);
92
93        Ok(bytes)
94    } else {
95        Err(XRPLBinaryCodecException::InvalidVariableLengthTooLarge {
96            max: MAX_LENGTH_VALUE,
97        }
98        .into())
99    }
100}
101
102pub trait Parser {
103    /// Peek the first byte of the BinaryParser.
104    ///
105    /// # Examples
106    ///
107    /// ## Basic usage
108    ///
109    /// ```
110    /// use xrpl::core::binarycodec::BinaryParser;
111    /// use xrpl::core::Parser;
112    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
113    ///
114    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
115    /// let binary_parser: BinaryParser = BinaryParser::from(test_bytes);
116    /// let first_byte: Option<[u8; 1]> = binary_parser.peek();
117    ///
118    /// assert_eq!(Some([test_bytes[0]; 1]), first_byte);
119    /// ```
120    fn peek(&self) -> Option<[u8; 1]>;
121
122    /// Consume the first n bytes of the BinaryParser.
123    ///
124    /// # Examples
125    ///
126    /// ## Basic usage
127    ///
128    /// ```
129    /// use xrpl::core::binarycodec::BinaryParser;
130    /// use xrpl::core::Parser;
131    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
132    /// use xrpl::core::exceptions::XRPLCoreException;
133    ///
134    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
135    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
136    ///
137    /// match binary_parser.skip_bytes(4) {
138    ///     Ok(parser) => assert_eq!(*parser, test_bytes[4..]),
139    ///     Err(e) => match e {
140    ///         XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
141    ///             max: _,
142    ///             found: _,
143    ///         }) => assert!(false),
144    ///         _ => assert!(false)
145    ///     }
146    /// }
147    /// ```
148    fn skip_bytes(&mut self, n: usize) -> XRPLCoreResult<&Self>;
149
150    /// Consume and return the first n bytes of the BinaryParser.
151    ///
152    /// # Examples
153    ///
154    /// ## Basic usage
155    ///
156    /// ```
157    /// use xrpl::core::binarycodec::BinaryParser;
158    /// use xrpl::core::Parser;
159    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
160    /// use xrpl::core::exceptions::XRPLCoreException;
161    ///
162    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
163    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
164    ///
165    /// match binary_parser.read(5) {
166    ///     Ok(data) => assert_eq!(test_bytes[..5], data),
167    ///     Err(e) => match e {
168    ///         XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
169    ///             max: _,
170    ///             found: _,
171    ///         }) => assert!(false),
172    ///         _ => assert!(false)
173    ///     }
174    /// }
175    /// ```
176    fn read(&mut self, n: usize) -> XRPLCoreResult<Vec<u8>>;
177
178    /// Read 1 byte from parser and return as unsigned int.
179    ///
180    /// # Examples
181    ///
182    /// ## Basic usage
183    ///
184    /// ```
185    /// use xrpl::core::binarycodec::BinaryParser;
186    /// use xrpl::core::Parser;
187    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
188    /// use xrpl::core::exceptions::XRPLCoreException;
189    ///
190    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
191    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
192    ///
193    /// match binary_parser.read_uint8() {
194    ///     Ok(data) => assert_eq!(0, data),
195    ///     Err(e) => match e {
196    ///         XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
197    ///             max: _,
198    ///             found: _,
199    ///         }) => assert!(false),
200    ///         _ => assert!(false)
201    ///     }
202    /// }
203    /// ```
204    fn read_uint8(&mut self) -> XRPLCoreResult<u8>;
205
206    /// Read 2 bytes from parser and return as unsigned int.
207    ///
208    /// # Examples
209    ///
210    /// ## Basic usage
211    ///
212    /// ```
213    /// use xrpl::core::binarycodec::BinaryParser;
214    /// use xrpl::core::Parser;
215    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
216    /// use xrpl::core::exceptions::XRPLCoreException;
217    ///
218    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
219    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
220    ///
221    /// match binary_parser.read_uint16() {
222    ///     Ok(data) => assert_eq!(17, data),
223    ///     Err(e) => match e {
224    ///         XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
225    ///             max: _,
226    ///             found: _,
227    ///         }) => assert!(false),
228    ///         _ => assert!(false)
229    ///     }
230    /// }
231    /// ```
232    fn read_uint16(&mut self) -> XRPLCoreResult<u16>;
233
234    /// Read 4 bytes from parser and return as unsigned int.
235    ///
236    /// # Examples
237    ///
238    /// ## Basic usage
239    ///
240    /// ```
241    /// use xrpl::core::binarycodec::BinaryParser;
242    /// use xrpl::core::Parser;
243    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
244    /// use xrpl::core::exceptions::XRPLCoreException;
245    ///
246    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
247    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
248    ///
249    /// match binary_parser.read_uint32() {
250    ///     Ok(data) => assert_eq!(1122867, data),
251    ///     Err(e) => match e {
252    ///         XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
253    ///             max: _,
254    ///             found: _,
255    ///         }) => assert!(false),
256    ///         _ => assert!(false)
257    ///     }
258    /// }
259    /// ```
260    fn read_uint32(&mut self) -> XRPLCoreResult<u32>;
261
262    /// Returns whether the binary parser has finished
263    /// parsing (e.g. there is nothing left in the buffer
264    /// that needs to be processed).
265    ///
266    /// # Examples
267    ///
268    /// ## Basic usage
269    ///
270    /// ```
271    /// use xrpl::core::binarycodec::BinaryParser;
272    /// use xrpl::core::Parser;
273    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
274    /// use xrpl::core::exceptions::XRPLCoreException;
275    /// extern crate alloc;
276    /// use alloc::vec;
277    ///
278    /// let empty: &[u8] = &[];
279    /// let mut buffer: Vec<u8> = vec![];
280    /// let test_bytes: &[u8] = &[0, 17, 34, 51, 68, 85, 102];
281    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
282    ///
283    /// while !binary_parser.is_end(None) {
284    ///     match binary_parser.read(1) {
285    ///         Ok(data) => buffer.extend_from_slice(&data),
286    ///         Err(e) => match e {
287    ///             XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
288    ///                 max: _,
289    ///                 found: _,
290    ///             }) => assert!(false),
291    ///             _ => assert!(false)
292    ///         }
293    ///     }
294    /// }
295    ///
296    /// assert_eq!(test_bytes, &buffer[..]);
297    /// // The BinaryParser is emptied as it is read.
298    /// assert_eq!(binary_parser, empty[..]);
299    ///
300    /// ```
301    fn is_end(&self, custom_end: Option<usize>) -> bool;
302
303    /// Reads a variable length encoding prefix and returns
304    /// the encoded length. The formula for decoding a length
305    /// prefix is described in Length Prefixing.
306    ///
307    /// See Length Prefixing:
308    /// `<https://xrpl.org/serialization.html#length-prefixing>`
309    ///
310    /// # Examples
311    ///
312    /// ## Basic usage
313    ///
314    /// ```
315    /// use xrpl::core::binarycodec::BinaryParser;
316    /// use xrpl::core::Parser;
317    /// use xrpl::core::binarycodec::exceptions::XRPLBinaryCodecException;
318    /// use xrpl::core::exceptions::XRPLCoreException;
319    ///
320    /// let test_bytes: &[u8] = &[6, 17, 34, 51, 68, 85, 102];
321    /// let mut binary_parser: BinaryParser = BinaryParser::from(test_bytes);
322    ///
323    /// match binary_parser.read_length_prefix() {
324    ///     Ok(data) => assert_eq!(6, data),
325    ///     Err(e) => match e {
326    ///         XRPLCoreException::XRPLBinaryCodecError(XRPLBinaryCodecException::UnexpectedLengthPrefixRange {
327    ///             min: _, max: _
328    ///         }) => assert!(false),
329    ///         _ => assert!(false)
330    ///     }
331    /// }
332    fn read_length_prefix(&mut self) -> XRPLCoreResult<usize>;
333
334    /// Reads field ID from BinaryParser and returns as
335    /// a FieldHeader object.
336    fn read_field_header(&mut self) -> XRPLCoreResult<FieldHeader>;
337
338    /// Read the field ordinal at the head of the
339    /// BinaryParser and return a FieldInstance object
340    /// representing information about the field
341    /// containedin the following bytes.
342    fn read_field(&mut self) -> XRPLCoreResult<FieldInstance>;
343
344    /// Read next bytes from BinaryParser as the given type.
345    fn read_type<T: TryFromParser>(&mut self) -> XRPLCoreResult<T, T::Error>;
346
347    /// Read value of the type specified by field from
348    /// the BinaryParser.
349    fn read_field_value<T: TryFromParser>(
350        &mut self,
351        field: &FieldInstance,
352    ) -> XRPLCoreResult<T, T::Error>
353    where
354        T::Error: From<XRPLCoreException>;
355}
356
357pub trait Serialization {
358    /// Write given bytes to this BinarySerializer.
359    ///
360    /// # Examples
361    ///
362    /// ## Basic usage
363    ///
364    /// ```
365    /// use xrpl::core::binarycodec::BinarySerializer;
366    /// use xrpl::core::binarycodec::Serialization;
367    ///
368    /// let mut test_bytes: Vec<u8> = [0, 17, 34, 51, 68, 85, 102].to_vec();
369    /// let mut serializer: BinarySerializer = BinarySerializer::new();
370    ///
371    /// serializer.append(&mut test_bytes.to_owned());
372    /// assert_eq!(test_bytes, serializer);
373    /// ```
374    fn append(&mut self, bytes: &[u8]) -> &Self;
375
376    /// Write a variable length encoded value to
377    /// the BinarySerializer.
378    ///
379    /// # Examples
380    ///
381    /// ## Basic usage
382    ///
383    /// ```
384    /// use xrpl::core::binarycodec::BinarySerializer;
385    /// use xrpl::core::binarycodec::Serialization;
386    ///
387    /// let expected: Vec<u8> = [3, 0, 17, 34].to_vec();
388    /// let mut test_bytes: Vec<u8> = [0, 17, 34].to_vec();
389    /// let mut serializer: BinarySerializer = BinarySerializer::new();
390    ///
391    /// serializer.write_length_encoded(&mut test_bytes, true);
392    /// assert_eq!(expected, serializer);
393    /// ```
394    fn write_length_encoded(&mut self, value: &[u8], encode_value: bool) -> &Self;
395
396    /// Write field and value to the buffer.
397    ///
398    /// # Examples
399    ///
400    /// ## Basic usage
401    ///
402    /// ```
403    /// use xrpl::core::binarycodec::BinarySerializer;
404    /// use xrpl::core::binarycodec::Serialization;
405    /// use xrpl::core::binarycodec::definitions::FieldInstance;
406    /// use xrpl::core::binarycodec::definitions::FieldInfo;
407    /// use xrpl::core::binarycodec::definitions::FieldHeader;
408    ///
409    /// let field_header: FieldHeader = FieldHeader {
410    ///     type_code: -2,
411    ///     field_code: 0,
412    /// };
413    ///
414    /// let field_info: FieldInfo = FieldInfo {
415    ///     nth: 0,
416    ///     is_vl_encoded: false,
417    ///     is_serialized: false,
418    ///     is_signing_field: false,
419    ///     r#type: "Unknown".to_string(),
420    /// };
421    ///
422    /// let field_instance = FieldInstance::new(&field_info, "Generic", field_header);
423    /// let expected: Vec<u8> = [224, 0, 17, 34].to_vec();
424    /// let test_bytes: Vec<u8> = [0, 17, 34].to_vec();
425    /// let mut serializer: BinarySerializer = BinarySerializer::new();
426    ///
427    /// serializer.write_field_and_value(field_instance, &test_bytes, false);
428    /// assert_eq!(expected, serializer);
429    /// ```
430    fn write_field_and_value(
431        &mut self,
432        field: FieldInstance,
433        value: &[u8],
434        is_unl_modify_workaround: bool,
435    ) -> &Self;
436}
437
438impl Serialization for BinarySerializer {
439    fn append(&mut self, bytes: &[u8]) -> &Self {
440        self.extend_from_slice(bytes);
441        self
442    }
443
444    fn write_length_encoded(&mut self, value: &[u8], encode_value: bool) -> &Self {
445        let mut byte_object: Vec<u8> = Vec::new();
446        if encode_value {
447            // write value to byte_object
448            byte_object.extend_from_slice(value);
449        }
450        // TODO Handle unwrap better
451        let length_prefix = _encode_variable_length_prefix(&byte_object.len()).unwrap();
452
453        self.extend_from_slice(&length_prefix);
454        self.extend_from_slice(&byte_object);
455
456        self
457    }
458
459    fn write_field_and_value(
460        &mut self,
461        field: FieldInstance,
462        value: &[u8],
463        is_unl_modify_workaround: bool,
464    ) -> &Self {
465        self.extend_from_slice(&field.header.to_bytes());
466
467        if field.is_vl_encoded {
468            self.write_length_encoded(value, !is_unl_modify_workaround);
469        } else {
470            self.extend_from_slice(value);
471        }
472
473        self
474    }
475}
476
477/// Peek the first byte of the BinaryParser.
478impl Parser for BinaryParser {
479    fn peek(&self) -> Option<[u8; 1]> {
480        if !self.0.is_empty() {
481            Some(self.0[0].to_be_bytes())
482        } else {
483            None
484        }
485    }
486
487    fn skip_bytes(&mut self, n: usize) -> XRPLCoreResult<&Self> {
488        if n > self.0.len() {
489            Err(XRPLBinaryCodecException::UnexpectedParserSkipOverflow {
490                max: self.0.len(),
491                found: n,
492            }
493            .into())
494        } else {
495            self.0 = self.0[n..].to_vec();
496            Ok(self)
497        }
498    }
499
500    fn read(&mut self, n: usize) -> XRPLCoreResult<Vec<u8>> {
501        let first_n_bytes = self.0[..n].to_owned();
502
503        self.skip_bytes(n)?;
504        Ok(first_n_bytes)
505    }
506
507    fn read_uint8(&mut self) -> XRPLCoreResult<u8> {
508        let result = self.read(1)?;
509        Ok(u8::from_be_bytes(result.try_into().or(Err(
510            XRPLBinaryCodecException::InvalidReadFromBytesValue,
511        ))?))
512    }
513
514    fn read_uint16(&mut self) -> XRPLCoreResult<u16> {
515        let result = self.read(2)?;
516        Ok(u16::from_be_bytes(result.try_into().or(Err(
517            XRPLBinaryCodecException::InvalidReadFromBytesValue,
518        ))?))
519    }
520
521    fn read_uint32(&mut self) -> XRPLCoreResult<u32> {
522        let result = self.read(4)?;
523        Ok(u32::from_be_bytes(result.try_into().or(Err(
524            XRPLBinaryCodecException::InvalidReadFromBytesValue,
525        ))?))
526    }
527
528    fn is_end(&self, custom_end: Option<usize>) -> bool {
529        if let Some(end) = custom_end {
530            self.0.len() <= end
531        } else {
532            self.0.is_empty()
533        }
534    }
535
536    fn read_length_prefix(&mut self) -> XRPLCoreResult<usize> {
537        let byte1: usize = self.read_uint8()? as usize;
538
539        match byte1 {
540            // If the field contains 0 to 192 bytes of data,
541            // the first byte defines the length of the contents.
542            x if x <= MAX_SINGLE_BYTE_LENGTH => Ok(byte1),
543            // If the field contains 193 to 12480 bytes of data,
544            // the first two bytes indicate the length of the
545            // field with the following formula:
546            // 193 + ((byte1 - 193) * 256) + byte2
547            x if x <= MAX_SECOND_BYTE_VALUE => {
548                let byte2: usize = self.read_uint8()? as usize;
549                Ok((MAX_SINGLE_BYTE_LENGTH + 1)
550                    + ((byte1 - (MAX_SINGLE_BYTE_LENGTH + 1)) * MAX_BYTE_VALUE)
551                    + byte2)
552            }
553            // If the field contains 12481 to 918744 bytes of data,
554            // the first three bytes indicate the length of the
555            // field with the following formula:
556            // 12481 + ((byte1 - 241) * 65536) + (byte2 * 256) + byte3
557            x if x <= 254 => {
558                let byte2: usize = self.read_uint8()? as usize;
559                let byte3: usize = self.read_uint8()? as usize;
560
561                Ok(MAX_DOUBLE_BYTE_LENGTH
562                    + ((byte1 - (MAX_SECOND_BYTE_VALUE + 1)) * MAX_DOUBLE_BYTE_VALUE)
563                    + (byte2 * MAX_BYTE_VALUE)
564                    + byte3)
565            }
566            _ => {
567                Err(XRPLBinaryCodecException::UnexpectedLengthPrefixRange { min: 1, max: 3 }.into())
568            }
569        }
570    }
571
572    fn read_field_header(&mut self) -> XRPLCoreResult<FieldHeader> {
573        let mut type_code: i16 = self.read_uint8()? as i16;
574        let mut field_code: i16 = type_code & 15;
575
576        type_code >>= 4;
577
578        if type_code == 0 {
579            type_code = self.read_uint8()? as i16;
580
581            if type_code == 0 || type_code < 16 {
582                return Err(
583                    XRPLBinaryCodecException::UnexpectedTypeCodeRange { min: 1, max: 16 }.into(),
584                );
585            };
586        };
587
588        if field_code == 0 {
589            field_code = self.read_uint8()? as i16;
590
591            if field_code == 0 || field_code < 16 {
592                return Err(
593                    XRPLBinaryCodecException::UnexpectedFieldCodeRange { min: 1, max: 16 }.into(),
594                );
595            };
596        };
597
598        Ok(FieldHeader {
599            type_code,
600            field_code,
601        })
602    }
603
604    fn read_field(&mut self) -> XRPLCoreResult<FieldInstance> {
605        let field_header = self.read_field_header()?;
606        let field_name = get_field_name_from_header(&field_header);
607
608        if let Some(name) = field_name {
609            if let Some(instance) = get_field_instance(name) {
610                return Ok(instance);
611            };
612        };
613
614        Err(XRPLBinaryCodecException::UnknownFieldName.into())
615    }
616
617    fn read_type<T: TryFromParser>(&mut self) -> XRPLCoreResult<T, T::Error> {
618        T::from_parser(self, None)
619    }
620
621    fn read_field_value<T: TryFromParser>(
622        &mut self,
623        field: &FieldInstance,
624    ) -> XRPLCoreResult<T, T::Error>
625    where
626        T::Error: From<XRPLCoreException>,
627    {
628        if field.is_vl_encoded {
629            let length = self.read_length_prefix()?;
630            T::from_parser(self, Some(length))
631        } else {
632            T::from_parser(self, None)
633        }
634    }
635}
636
637impl From<&[u8]> for BinaryParser {
638    fn from(hex_bytes: &[u8]) -> Self {
639        BinaryParser(hex_bytes.to_vec())
640    }
641}
642
643impl From<Vec<u8>> for BinaryParser {
644    fn from(hex_bytes: Vec<u8>) -> Self {
645        BinaryParser(hex_bytes)
646    }
647}
648
649impl TryFrom<&str> for BinaryParser {
650    type Error = XRPLCoreException;
651
652    fn try_from(hex_bytes: &str) -> XRPLCoreResult<Self, Self::Error> {
653        Ok(BinaryParser(hex::decode(hex_bytes)?))
654    }
655}
656
657impl PartialEq<[u8]> for BinaryParser {
658    fn eq(&self, bytes: &[u8]) -> bool {
659        self.0 == bytes
660    }
661}
662
663impl PartialEq<Vec<u8>> for BinaryParser {
664    fn eq(&self, bytes: &Vec<u8>) -> bool {
665        &self.0 == bytes
666    }
667}
668
669impl ExactSizeIterator for BinaryParser {
670    fn len(&self) -> usize {
671        self.0.len()
672    }
673}
674
675impl Iterator for BinaryParser {
676    type Item = u8;
677
678    fn next(&mut self) -> Option<Self::Item> {
679        if self.is_end(None) {
680            None
681        } else {
682            Some(self.read_uint8().expect("BinaryParser::next"))
683        }
684    }
685}
686
687// =========================================================================
688// Internal serialization/deserialization functions
689// (not part of the public API)
690// =========================================================================
691
692pub(crate) const TRANSACTION_SIGNATURE_PREFIX: i32 = 0x53545800;
693pub(crate) const TRANSACTION_MULTISIG_PREFIX: [u8; 4] = (0x534D5400u32).to_be_bytes();
694pub(crate) const PAYMENT_CHANNEL_CLAIM_PREFIX: [u8; 4] = (0x434C4D00u32).to_be_bytes();
695pub(crate) const BATCH_PREFIX: [u8; 4] = (0x42434800u32).to_be_bytes();
696
697/// UInt64 fields that should be encoded/decoded as base-10 strings instead of hex.
698pub(crate) const BASE10_UINT64_FIELDS: &[&str] = &[
699    "MaximumAmount",
700    "OutstandingAmount",
701    "MPTAmount",
702    "LockedAmount",
703];
704
705/// Serialize a JSON transaction to hex-encoded binary.
706pub(crate) fn serialize_json<T>(
707    prepared_transaction: &T,
708    prefix: Option<&[u8]>,
709    suffix: Option<&[u8]>,
710    signing_only: bool,
711) -> XRPLCoreResult<String>
712where
713    T: Serialize,
714{
715    let mut buffer = Vec::new();
716    if let Some(p) = prefix {
717        buffer.extend(p);
718    }
719
720    let json_value =
721        serde_json::to_value(prepared_transaction).map_err(XRPLSerdeJsonError::from)?;
722    let st_object = STObject::try_from_value(json_value, signing_only)?;
723    buffer.extend(st_object.as_ref());
724
725    if let Some(s) = suffix {
726        buffer.extend(s);
727    }
728    let hex_string = buffer.encode_hex_upper::<String>();
729
730    Ok(hex_string)
731}
732
733/// Decode a single field value from a BinaryParser based on the field's type.
734/// Returns the JSON value for the field.
735fn decode_field_value(parser: &mut BinaryParser, field: &FieldInstance) -> XRPLCoreResult<Value> {
736    let type_name = field.associated_type.as_str();
737
738    // Handle VL prefix for variable-length encoded fields
739    let length = if field.is_vl_encoded {
740        Some(parser.read_length_prefix()?)
741    } else {
742        None
743    };
744
745    match type_name {
746        "AccountID" => {
747            let account = AccountId::from_parser(parser, length)?;
748            Ok(serde_json::to_value(&account).map_err(XRPLSerdeJsonError::from)?)
749        }
750        "Amount" => {
751            let amount = Amount::from_parser(parser, length)?;
752            Ok(serde_json::to_value(&amount).map_err(XRPLSerdeJsonError::from)?)
753        }
754        "Blob" => {
755            let blob = Blob::from_parser(parser, length)?;
756            Ok(serde_json::to_value(&blob).map_err(XRPLSerdeJsonError::from)?)
757        }
758        "Hash128" => {
759            let hash = Hash128::from_parser(parser, length)?;
760            Ok(serde_json::to_value(&hash).map_err(XRPLSerdeJsonError::from)?)
761        }
762        "Hash160" => {
763            let hash = Hash160::from_parser(parser, length)?;
764            Ok(serde_json::to_value(&hash).map_err(XRPLSerdeJsonError::from)?)
765        }
766        "Hash192" => {
767            let hash = Hash192::from_parser(parser, length)?;
768            Ok(serde_json::to_value(&hash).map_err(XRPLSerdeJsonError::from)?)
769        }
770        "Hash256" => {
771            let hash = Hash256::from_parser(parser, length)?;
772            Ok(serde_json::to_value(&hash).map_err(XRPLSerdeJsonError::from)?)
773        }
774        "UInt8" => {
775            let val = parser.read_uint8()?;
776            if field.name == "TransactionResult" {
777                let code = val as i16;
778                if let Some(name) = get_transaction_result_name(&code) {
779                    return Ok(Value::String(name.clone()));
780                }
781            }
782            Ok(Value::Number(val.into()))
783        }
784        "UInt16" => {
785            let val = parser.read_uint16()?;
786            if field.name == "TransactionType" {
787                let code = val as i16;
788                if let Some(name) = get_transaction_type_name(&code) {
789                    return Ok(Value::String(name.clone()));
790                }
791            } else if field.name == "LedgerEntryType" {
792                let code = val as i16;
793                if let Some(name) = get_ledger_entry_type_name(&code) {
794                    return Ok(Value::String(name.clone()));
795                }
796            } else if field.name == "TransactionResult" {
797                let code = val as i16;
798                if let Some(name) = get_transaction_result_name(&code) {
799                    return Ok(Value::String(name.clone()));
800                }
801            }
802            Ok(Value::Number(val.into()))
803        }
804        "UInt32" => {
805            let val = parser.read_uint32()?;
806            if field.name == "PermissionValue" {
807                let code = val as i32;
808                if let Some(name) = get_delegatable_permission_name(&code) {
809                    return Ok(Value::String(name.clone()));
810                }
811            }
812            Ok(Value::Number(val.into()))
813        }
814        "UInt64" => {
815            let bytes = parser.read(8)?;
816            if BASE10_UINT64_FIELDS.contains(&field.name.as_str()) {
817                let val = u64::from_be_bytes(
818                    bytes
819                        .as_slice()
820                        .try_into()
821                        .map_err(|_| XRPLBinaryCodecException::InvalidReadFromBytesValue)?,
822                );
823                Ok(Value::String(val.to_string()))
824            } else {
825                Ok(Value::String(hex::encode_upper(&bytes)))
826            }
827        }
828        "Int32" => {
829            let bytes = parser.read(4)?;
830            let val = i32::from_be_bytes(
831                bytes
832                    .as_slice()
833                    .try_into()
834                    .map_err(|_| XRPLBinaryCodecException::InvalidReadFromBytesValue)?,
835            );
836            Ok(Value::Number(val.into()))
837        }
838        "STObject" => decode_st_object(parser),
839        "STArray" => decode_st_array(parser),
840        "PathSet" => {
841            let path_set = PathSet::from_parser(parser, length)?;
842            Ok(serde_json::to_value(&path_set).map_err(XRPLSerdeJsonError::from)?)
843        }
844        "Vector256" => {
845            let vector = Vector256::from_parser(parser, length)?;
846            Ok(serde_json::to_value(&vector).map_err(XRPLSerdeJsonError::from)?)
847        }
848        "Currency" => {
849            let currency = crate::core::binarycodec::types::Currency::from_parser(parser, length)?;
850            Ok(serde_json::to_value(&currency).map_err(XRPLSerdeJsonError::from)?)
851        }
852        "Issue" => {
853            let issue = Issue::from_parser(parser, length)?;
854            Ok(serde_json::to_value(&issue).map_err(XRPLSerdeJsonError::from)?)
855        }
856        "XChainBridge" => {
857            let bridge = XChainBridge::from_parser(parser, length)?;
858            Ok(serde_json::to_value(&bridge).map_err(XRPLSerdeJsonError::from)?)
859        }
860        "Number" => {
861            let number = crate::core::binarycodec::types::Number::from_parser(parser, length)?;
862            Ok(serde_json::to_value(&number).map_err(XRPLSerdeJsonError::from)?)
863        }
864        _ => {
865            if let Some(len) = length {
866                let bytes = parser.read(len)?;
867                Ok(Value::String(hex::encode_upper(&bytes)))
868            } else {
869                Err(XRPLCoreException::XRPLUtilsError(alloc::format!(
870                    "Unknown field type '{}' with no length prefix",
871                    field.associated_type
872                )))
873            }
874        }
875    }
876}
877
878/// Decode an STObject from the parser. Reads fields until ObjectEndMarker (0xE1)
879/// or end of parser data.
880pub(crate) fn decode_st_object(parser: &mut BinaryParser) -> XRPLCoreResult<Value> {
881    let mut accumulator = Map::new();
882
883    while !parser.is_end(None) {
884        let field = parser.read_field()?;
885
886        if field.name == "ObjectEndMarker" {
887            break;
888        }
889
890        let value = decode_field_value(parser, &field)?;
891        accumulator.insert(field.name, value);
892    }
893
894    Ok(Value::Object(accumulator))
895}
896
897/// Decode an STArray from the parser. Reads wrapper objects until
898/// ArrayEndMarker (0xF1) or end of parser data.
899fn decode_st_array(parser: &mut BinaryParser) -> XRPLCoreResult<Value> {
900    let mut result: Vec<Value> = Vec::new();
901
902    while !parser.is_end(None) {
903        let field = parser.read_field()?;
904
905        if field.name == "ArrayEndMarker" {
906            break;
907        }
908
909        let inner = decode_st_object(parser)?;
910        let mut wrapper = Map::new();
911        wrapper.insert(field.name, inner);
912        result.push(Value::Object(wrapper));
913    }
914
915    Ok(Value::Array(result))
916}
917
918/// Decode a serialized ledger header from hex into JSON.
919pub(crate) fn decode_ledger_data_inner(hex_string: &str) -> XRPLCoreResult<Value> {
920    let mut parser = BinaryParser::try_from(hex_string)?;
921
922    let ledger_index = parser.read_uint32()?;
923
924    let coins_bytes = parser.read(8)?;
925    let total_coins = u64::from_be_bytes(
926        coins_bytes
927            .as_slice()
928            .try_into()
929            .map_err(|_| XRPLBinaryCodecException::InvalidReadFromBytesValue)?,
930    );
931
932    let parent_hash_bytes = parser.read(32)?;
933    let transaction_hash_bytes = parser.read(32)?;
934    let account_hash_bytes = parser.read(32)?;
935
936    let parent_close_time = parser.read_uint32()?;
937    let close_time = parser.read_uint32()?;
938    let close_time_resolution = parser.read_uint8()?;
939    let close_flags = parser.read_uint8()?;
940
941    let mut map = Map::new();
942    map.insert("ledger_index".into(), Value::Number(ledger_index.into()));
943    map.insert("total_coins".into(), Value::String(total_coins.to_string()));
944    map.insert(
945        "parent_hash".into(),
946        Value::String(hex::encode_upper(&parent_hash_bytes)),
947    );
948    map.insert(
949        "transaction_hash".into(),
950        Value::String(hex::encode_upper(&transaction_hash_bytes)),
951    );
952    map.insert(
953        "account_hash".into(),
954        Value::String(hex::encode_upper(&account_hash_bytes)),
955    );
956    map.insert(
957        "parent_close_time".into(),
958        Value::Number(parent_close_time.into()),
959    );
960    map.insert("close_time".into(), Value::Number(close_time.into()));
961    map.insert(
962        "close_time_resolution".into(),
963        Value::Number(close_time_resolution.into()),
964    );
965    map.insert("close_flags".into(), Value::Number(close_flags.into()));
966
967    Ok(Value::Object(map))
968}
969
970#[cfg(test)]
971mod test {
972    use super::*;
973    use crate::alloc::string::ToString;
974    use alloc::string::String;
975
976    const TEST_HEX: &str = "00112233445566";
977
978    #[test]
979    fn test_binaryparser_from() {
980        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
981        let ref_bytes: &[u8] = test_bytes.as_ref();
982        let slice_parser = BinaryParser::from(ref_bytes);
983        let vec_parser = BinaryParser::from(test_bytes.to_owned());
984
985        assert_eq!(slice_parser, test_bytes[..]);
986        assert_eq!(vec_parser, test_bytes[..]);
987    }
988
989    #[test]
990    fn test_binaryparser_try_from() {
991        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
992        let string_parser = BinaryParser::try_from(TEST_HEX).unwrap();
993
994        assert_eq!(string_parser, test_bytes[..]);
995    }
996
997    #[test]
998    fn test_peek() {
999        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
1000        let binary_parser = BinaryParser::from(test_bytes.as_ref());
1001
1002        assert_eq!(binary_parser.peek(), Some([test_bytes[0]; 1]));
1003    }
1004
1005    #[test]
1006    fn test_skip_bytes() {
1007        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
1008        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1009
1010        assert!(binary_parser.skip_bytes(4).is_ok());
1011        assert_eq!(binary_parser, test_bytes[4..]);
1012    }
1013
1014    #[test]
1015    fn test_read() {
1016        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
1017        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1018        let result = binary_parser.read(5);
1019
1020        assert!(result.is_ok());
1021        assert_eq!(result.unwrap(), test_bytes[..5]);
1022    }
1023
1024    #[test]
1025    fn test_read_uint8() {
1026        let test_hex: &str = "01000200000003";
1027        let test_bytes: Vec<u8> = hex::decode(test_hex).expect("");
1028        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1029        let result = binary_parser.read_uint8();
1030
1031        assert!(result.is_ok());
1032        assert_eq!(result, Ok(1));
1033    }
1034
1035    #[test]
1036    fn test_read_uint16() {
1037        let test_hex: &str = "000200000003";
1038        let test_bytes: Vec<u8> = hex::decode(test_hex).expect("");
1039        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1040        let result = binary_parser.read_uint16();
1041
1042        assert!(result.is_ok());
1043        assert_eq!(result, Ok(2));
1044    }
1045
1046    #[test]
1047    fn test_read_uint32() {
1048        let test_hex: &str = "00000003";
1049        let test_bytes: Vec<u8> = hex::decode(test_hex).expect("");
1050        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1051        let result = binary_parser.read_uint32();
1052
1053        assert!(result.is_ok());
1054        assert_eq!(result, Ok(3));
1055    }
1056
1057    #[test]
1058    fn test_read_length_prefix() {
1059        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
1060        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1061        let result = binary_parser.read_length_prefix();
1062
1063        assert!(result.is_ok());
1064        assert_eq!(result, Ok(0));
1065    }
1066
1067    // TODO Finish tests
1068    #[test]
1069    fn test_read_field_header() {}
1070
1071    #[test]
1072    fn test_read_field_value() {}
1073
1074    #[test]
1075    fn test_read_field_and_value() {}
1076
1077    #[test]
1078    fn test_read_type() {}
1079
1080    #[test]
1081    fn accept_peek_skip_read() {
1082        let test_bytes: Vec<u8> = hex::decode(TEST_HEX).expect("");
1083        let mut binary_parser = BinaryParser::from(test_bytes.as_ref());
1084
1085        assert_eq!(binary_parser.peek(), Some([test_bytes[0]; 1]));
1086        assert!(binary_parser.skip_bytes(3).is_ok());
1087        assert_eq!(binary_parser, test_bytes[3..]);
1088
1089        let result = binary_parser.read(2);
1090
1091        assert!(result.is_ok());
1092        assert_eq!(result.unwrap(), test_bytes[3..5]);
1093    }
1094
1095    #[test]
1096    fn test_binaryserializer_write_field_and_value() {
1097        let field_header = FieldHeader {
1098            type_code: -2,
1099            field_code: 0,
1100        };
1101
1102        let field_info = FieldInfo {
1103            nth: 0,
1104            is_vl_encoded: false,
1105            is_serialized: false,
1106            is_signing_field: false,
1107            r#type: "Unknown".to_string(),
1108        };
1109
1110        let field_instance = FieldInstance::new(&field_info, "Generic", field_header);
1111        let expected: Vec<u8> = [224, 0, 17, 34].to_vec();
1112        let test_bytes: Vec<u8> = [0, 17, 34].to_vec();
1113        let mut serializer: BinarySerializer = BinarySerializer::new();
1114
1115        serializer.write_field_and_value(field_instance, &test_bytes, false);
1116        assert_eq!(expected, serializer);
1117    }
1118
1119    /// Test that decode_field_value returns an error for unknown field types
1120    /// with no length prefix, rather than silently returning Null.
1121    /// Mirrors xrpl.js behavior where readFieldValue throws on unsupported types.
1122    #[test]
1123    fn test_decode_field_value_unknown_type_no_length_errors() {
1124        use super::decode_field_value;
1125        use crate::core::binarycodec::definitions::{FieldHeader, FieldInfo, FieldInstance};
1126
1127        let field_info = FieldInfo {
1128            nth: 1,
1129            is_vl_encoded: false,
1130            is_serialized: true,
1131            is_signing_field: true,
1132            r#type: "FutureType".to_string(),
1133        };
1134        let field_header = FieldHeader {
1135            type_code: 99,
1136            field_code: 1,
1137        };
1138        let field = FieldInstance::new(&field_info, "FutureField", field_header);
1139
1140        let mut parser = BinaryParser::from(&[0xAB, 0xCD][..]);
1141        let result = decode_field_value(&mut parser, &field);
1142
1143        assert!(
1144            result.is_err(),
1145            "Expected error for unknown type with no length prefix"
1146        );
1147        let err_msg = result.unwrap_err().to_string();
1148        assert!(
1149            err_msg.contains("Unknown field type 'FutureType'"),
1150            "Error should mention the unknown type name, got: {}",
1151            err_msg
1152        );
1153        // Parser should not have advanced (no bytes consumed)
1154        assert_eq!(
1155            parser.0.len(),
1156            2,
1157            "Parser should not have consumed any bytes"
1158        );
1159    }
1160
1161    /// Test that decode_field_value handles unknown VL-encoded types
1162    /// by reading the bytes and returning them as hex.
1163    #[test]
1164    fn test_decode_field_value_unknown_type_with_vl_returns_hex() {
1165        use super::decode_field_value;
1166        use crate::core::binarycodec::definitions::{FieldHeader, FieldInfo, FieldInstance};
1167
1168        let field_info = FieldInfo {
1169            nth: 1,
1170            is_vl_encoded: true,
1171            is_serialized: true,
1172            is_signing_field: true,
1173            r#type: "FutureVLType".to_string(),
1174        };
1175        let field_header = FieldHeader {
1176            type_code: 99,
1177            field_code: 1,
1178        };
1179        let field = FieldInstance::new(&field_info, "FutureVLField", field_header);
1180
1181        // VL prefix 0x03 = 3 bytes, followed by 3 bytes of data
1182        let mut parser = BinaryParser::from(&[0x03, 0xAA, 0xBB, 0xCC][..]);
1183        let result = decode_field_value(&mut parser, &field);
1184
1185        assert!(result.is_ok(), "VL-encoded unknown type should succeed");
1186        assert_eq!(
1187            result.unwrap(),
1188            serde_json::Value::String("AABBCC".to_string())
1189        );
1190        assert!(parser.0.is_empty(), "Parser should have consumed all bytes");
1191    }
1192
1193    /// This is currently a sanity check for private
1194    /// [`_encode_variable_length_prefix`], which is called by
1195    /// BinarySerializer.write_length_encoded.
1196    #[test]
1197    fn test_encode_variable_length_prefix() {
1198        for case in [100_usize, 1000, 20_000] {
1199            let blob = (0..case).map(|_| "A2").collect::<String>();
1200            let mut binary_serializer: BinarySerializer = BinarySerializer::new();
1201
1202            binary_serializer.write_length_encoded(&hex::decode(blob).expect(""), true);
1203
1204            let mut binary_parser: BinaryParser = BinaryParser::from(binary_serializer.as_ref());
1205            let decoded_length = binary_parser.read_length_prefix();
1206
1207            assert!(decoded_length.is_ok());
1208            assert_eq!(decoded_length, Ok(case));
1209        }
1210    }
1211}