1use core::fmt::Error;
7
8use super::Hashable;
9use alloc::{vec, vec::Vec};
10use ark_ff::{BigInteger, PrimeField};
11use bitvec::{prelude::*, view::AsBits};
12use mina_curves::pasta::{Fp, Fq};
13use o1_utils::FieldHelpers;
14
15const SER_HEADER_SIZE: usize = 8;
17const SINGLE_HEADER_SIZE: usize = 4;
19
20#[derive(Default, Debug, Clone, PartialEq, Eq)]
69pub struct ROInput {
70 fields: Vec<Fp>,
71 bits: BitVec<u8>,
72}
73
74impl ROInput {
75 pub fn new() -> Self {
77 ROInput {
78 fields: vec![],
79 bits: BitVec::new(),
80 }
81 }
82
83 pub fn append_hashable(self, input: &impl Hashable) -> Self {
85 self.append_roinput(input.to_roinput())
86 }
87
88 pub fn append_roinput(mut self, mut roi: ROInput) -> Self {
90 self.fields.append(&mut roi.fields);
91 self.bits.extend(roi.bits);
92 self
93 }
94
95 pub fn append_field(mut self, f: Fp) -> Self {
97 self.fields.push(f);
98 self
99 }
100
101 pub fn append_scalar(mut self, s: Fq) -> Self {
142 let bytes = s.to_bytes();
144 let bits = &bytes.as_bits::<Lsb0>()[..Fq::MODULUS_BIT_SIZE as usize];
145 self.bits.extend(bits);
146 self
147 }
148
149 pub fn append_bool(mut self, b: bool) -> Self {
151 self.bits.push(b);
152 self
153 }
154
155 pub fn append_bytes(mut self, bytes: &[u8]) -> Self {
157 self.bits.extend_from_bitslice(bytes.as_bits::<Lsb0>());
158 self
159 }
160
161 pub fn append_u32(self, x: u32) -> Self {
163 self.append_bytes(&x.to_le_bytes())
164 }
165
166 pub fn append_u64(self, x: u64) -> Self {
168 self.append_bytes(&x.to_le_bytes())
169 }
170
171 pub fn to_bytes(&self) -> Vec<u8> {
173 let mut bits: BitVec<u8> = self.fields.iter().fold(BitVec::new(), |mut acc, fe| {
174 acc.extend_from_bitslice(
175 &fe.to_bytes().as_bits::<Lsb0>()[..Fp::MODULUS_BIT_SIZE as usize],
176 );
177
178 acc
179 });
180
181 bits.extend(&self.bits);
182
183 bits.into()
184 }
185
186 pub fn to_fields(&self) -> Vec<Fp> {
190 let mut fields: Vec<Fp> = self.fields.clone();
191
192 let bits_as_fields =
193 self.bits
194 .chunks(Fp::MODULUS_BIT_SIZE as usize - 1)
195 .fold(vec![], |mut acc, chunk| {
196 let mut bv = BitVec::<u8>::new();
210 bv.resize(chunk.len(), false);
211 bv.clone_from_bitslice(chunk);
212
213 bv.resize(Fp::MODULUS_BIT_SIZE as usize, false);
215
216 acc.push(
217 Fp::from_bytes(&bv.into_vec())
218 .expect("failed to create base field element"),
219 );
220
221 acc
222 });
223
224 fields.extend(bits_as_fields);
225
226 fields
227 }
228
229 pub fn serialize(&self) -> Vec<u8> {
231 let fields_len = self.fields.len() as u32;
233 let bits_len = self.bits.len() as u32;
234
235 let mut bytes = Vec::with_capacity(SER_HEADER_SIZE + self.to_bytes().len());
236 bytes.extend_from_slice(&fields_len.to_le_bytes());
237 bytes.extend_from_slice(&bits_len.to_le_bytes());
238 bytes.extend_from_slice(&self.to_bytes());
239 bytes
240 }
241
242 pub fn deserialize(input: &[u8]) -> Result<Self, Error> {
244 if input.len() < SER_HEADER_SIZE {
245 return Err(Error);
246 }
247
248 let fields_len =
250 u32::from_le_bytes(input[0..SINGLE_HEADER_SIZE].try_into().unwrap()) as usize;
251 let bits_len = u32::from_le_bytes(
252 input[SINGLE_HEADER_SIZE..SER_HEADER_SIZE]
253 .try_into()
254 .unwrap(),
255 ) as usize;
256
257 let bits = input[SER_HEADER_SIZE..].view_bits::<Lsb0>();
259
260 let expected_len_bits = fields_len * Fp::MODULUS_BIT_SIZE as usize + bits_len;
262 let expected_len = (expected_len_bits + 7) / 8 + SER_HEADER_SIZE;
264 if input.len() != expected_len {
265 return Err(Error);
266 }
267
268 let mut fields = Vec::with_capacity(fields_len);
270
271 for chunk in bits.chunks(Fp::MODULUS_BIT_SIZE as usize).take(fields_len) {
272 let bools: Vec<bool> = chunk.iter().by_vals().collect();
273 let repr = <Fp as PrimeField>::BigInt::from_bits_le(&bools);
275 let elt = Fp::from_bigint(repr).ok_or(Error)?;
277 fields.push(elt);
278 }
279
280 let remainder = &bits[fields_len * Fp::MODULUS_BIT_SIZE as usize..];
281 let bits = remainder.iter().take(bits_len).collect::<BitVec<u8>>();
283
284 let roi = ROInput { fields, bits };
285
286 Ok(roi)
287 }
288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293 use crate::{
294 alloc::string::{String, ToString},
295 Hashable,
296 };
297
298 #[test]
299 fn append_bool() {
300 let roi = ROInput::new().append_bool(true);
301 assert!(roi.bits.len() == 1);
302 assert!(roi.bits.as_raw_slice() == [0x01]);
303 }
304
305 #[test]
306 fn append_two_bits() {
307 let roi = ROInput::new().append_bool(false).append_bool(true);
308 assert!(roi.bits.len() == 2);
309 assert!(roi.bits.as_raw_slice() == [0x02]);
310 }
311
312 #[test]
313 fn append_five_bits() {
314 let roi = ROInput::new()
315 .append_bool(false)
316 .append_bool(true)
317 .append_bool(false)
318 .append_bool(false)
319 .append_bool(true);
320 assert!(roi.bits.len() == 5);
321 assert!(roi.bits.as_raw_slice() == [0x12]);
322 }
323
324 #[test]
325 fn append_byte() {
326 let roi = ROInput::new().append_bytes(&[0x01]);
327 assert!(roi.bits.len() == 8);
328 assert!(roi.bits.as_raw_slice() == [0x01]);
329 }
330
331 #[test]
332 fn append_two_bytes() {
333 let roi = ROInput::new().append_bytes(&[0x10, 0xac]);
334 assert!(roi.bits.len() == 16);
335 assert!(roi.bits.as_raw_slice() == [0x10, 0xac]);
336 }
337
338 #[test]
339 fn append_five_bytes() {
340 let roi = ROInput::new().append_bytes(&[0x10, 0xac, 0x01, 0xeb, 0xca]);
341 assert!(roi.bits.len() == 40);
342 assert!(roi.bits.as_raw_slice() == [0x10, 0xac, 0x01, 0xeb, 0xca]);
343 }
344
345 #[test]
346 fn append_scalar() {
347 let scalar =
348 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
349 .expect("failed to create scalar");
350 let roi = ROInput::new().append_scalar(scalar);
351 assert_eq!(roi.bits.len(), 255);
352 assert_eq!(
353 roi.bits.as_raw_slice(),
354 [
355 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
356 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
357 0x17, 0x44, 0x42, 0x16
358 ]
359 );
360 assert_eq!(
361 roi.to_bytes(),
362 [
363 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
364 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
365 0x17, 0x44, 0x42, 0x16
366 ]
367 );
368 }
369
370 #[test]
371 fn append_scalar_and_byte() {
372 let scalar =
373 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
374 .expect("failed to create scalar");
375 let roi = ROInput::new().append_scalar(scalar).append_bytes(&[0x01]);
376 assert!(roi.bits.len() == 263);
377 assert!(
378 roi.bits.as_raw_slice()
379 == [
380 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
381 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
382 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0x00
383 ]
384 );
385 }
386
387 #[test]
388 fn append_two_scalars() {
389 let scalar1 =
390 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
391 .expect("failed to create scalar");
392 let scalar2 =
393 Fq::from_hex("a1b1e948835be341277548134e0effabdbcb95b742e8c5e967e9bf13eb4ae805")
394 .expect("failed to create scalar");
395 let roi = ROInput::new().append_scalar(scalar1).append_scalar(scalar2);
396 assert!(roi.bits.len() == 510);
397 assert!(
398 roi.bits.as_raw_slice()
399 == [
400 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
401 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
402 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0xd0, 0xd8, 0x74, 0xa4, 0xc1, 0xad, 0xf1,
403 0xa0, 0x93, 0x3a, 0xa4, 0x09, 0x27, 0x87, 0xff, 0xd5, 0xed, 0xe5, 0xca, 0x5b,
404 0x21, 0xf4, 0xe2, 0xf4, 0xb3, 0xf4, 0xdf, 0x89, 0x75, 0x25, 0xf4, 0x02
405 ]
406 );
407 }
408
409 #[test]
410 fn append_two_scalars_and_byte() {
411 let scalar1 =
412 Fq::from_hex("60db6f4f5b8ce1c7cb747fba9e324cc3268c7a6e3f43cd82d451ae99a7b2bd1f")
413 .expect("failed to create scalar");
414 let scalar2 =
415 Fq::from_hex("fe7775b106bceb58f3e23e5a4eb99f404b8ed8cf2afeef9c9d1800f12138cd07")
416 .expect("failed to create scalar");
417 let roi = ROInput::new()
418 .append_scalar(scalar1)
419 .append_bytes(&[0x2a])
420 .append_scalar(scalar2);
421 assert!(roi.bits.len() == 518);
422 assert!(
423 roi.bits.as_raw_slice()
424 == [
425 0x60, 0xdb, 0x6f, 0x4f, 0x5b, 0x8c, 0xe1, 0xc7, 0xcb, 0x74, 0x7f, 0xba, 0x9e,
426 0x32, 0x4c, 0xc3, 0x26, 0x8c, 0x7a, 0x6e, 0x3f, 0x43, 0xcd, 0x82, 0xd4, 0x51,
427 0xae, 0x99, 0xa7, 0xb2, 0xbd, 0x1f, 0x15, 0xff, 0xbb, 0xba, 0x58, 0x03, 0xde,
428 0x75, 0xac, 0x79, 0x71, 0x1f, 0x2d, 0xa7, 0xdc, 0x4f, 0xa0, 0x25, 0x47, 0xec,
429 0x67, 0x15, 0xff, 0x77, 0xce, 0x4e, 0x0c, 0x80, 0xf8, 0x10, 0x9c, 0xe6, 0x03
430 ]
431 );
432 }
433
434 #[test]
435 fn test_append_scalar_max_value() {
436 let max_scalar = Fq::from(0u64) - Fq::from(1u64); let roi = ROInput::new().append_scalar(max_scalar);
439
440 assert_eq!(roi.bits.len(), 255);
442 assert_eq!(roi.fields.len(), 0);
443
444 let reconstructed_bytes = roi.bits.as_raw_slice();
446 let expected_bytes = max_scalar.to_bytes();
447
448 assert_eq!(&reconstructed_bytes[..31], &expected_bytes[..31]);
450
451 let last_byte_mask = 0x7F; assert_eq!(
454 reconstructed_bytes[31] & last_byte_mask,
455 expected_bytes[31] & last_byte_mask
456 );
457
458 let serialized_bytes = roi.to_bytes();
460 assert_eq!(serialized_bytes.len(), 32); let fields = roi.to_fields();
464 assert_eq!(fields.len(), 2); let roi_double = ROInput::new()
468 .append_scalar(max_scalar)
469 .append_scalar(max_scalar);
470 assert_eq!(roi_double.bits.len(), 510); let fields_double = roi_double.to_fields();
473 assert_eq!(fields_double.len(), 3); }
475
476 #[test]
477 fn append_u32() {
478 let roi = ROInput::new().append_u32(1984u32);
479 assert!(roi.bits.len() == 32);
480 assert!(roi.bits.as_raw_slice() == [0xc0, 0x07, 0x00, 0x00]);
481 }
482
483 #[test]
484 fn append_two_u32_and_bit() {
485 let roi = ROInput::new()
486 .append_u32(1729u32)
487 .append_bool(false)
488 .append_u32(u32::MAX);
489 assert!(roi.bits.len() == 65);
490 assert!(roi.bits.as_raw_slice() == [0xc1, 0x06, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01]);
491 }
492
493 #[test]
494 fn append_u64() {
495 let roi = ROInput::new().append_u64(6174u64);
496 assert!(roi.bits.len() == 64);
497 assert!(roi.bits.as_raw_slice() == [0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
498 }
499
500 #[test]
501 fn append_two_u64_and_bits() {
502 let roi = ROInput::new()
503 .append_bool(true)
504 .append_u64(u64::MAX / 6174u64)
505 .append_bool(false)
506 .append_u64(u64::MAX / 1111u64);
507 assert!(roi.bits.len() == 130);
508 assert!(
509 roi.bits.as_raw_slice()
510 == [
511 0xe1, 0x29, 0x89, 0xd6, 0xcb, 0x3a, 0x15, 0x00, 0x08, 0x17, 0xc4, 0x9b, 0x04,
512 0xf4, 0xeb, 0x00, 0x00
513 ]
514 );
515 }
516
517 #[test]
518 fn all_1() {
519 let roi = ROInput::new()
520 .append_bool(true)
521 .append_scalar(
522 Fq::from_hex("01d1755db21c8cd2a9cf5a3436178da3d70f484cd4b4c8834b799921e7d7a102")
523 .expect("failed to create scalar"),
524 )
525 .append_u64(18446744073709551557)
526 .append_bytes(&[0xba, 0xdc, 0x0f, 0xfe])
527 .append_scalar(
528 Fq::from_hex("e70187e9b125524489d0433da76fd8287fa652eaebde147b45fa0cd86f171810")
529 .expect("failed to create scalar"),
530 )
531 .append_bool(false)
532 .append_u32(2147483647)
533 .append_bool(true);
534
535 assert!(roi.bits.len() == 641);
536 assert!(
537 roi.bits.as_raw_slice()
538 == [
539 0x03, 0xa2, 0xeb, 0xba, 0x64, 0x39, 0x18, 0xa5, 0x53, 0x9f, 0xb5, 0x68, 0x6c,
540 0x2e, 0x1a, 0x47, 0xaf, 0x1f, 0x90, 0x98, 0xa8, 0x69, 0x91, 0x07, 0x97, 0xf2,
541 0x32, 0x43, 0xce, 0xaf, 0x43, 0x05, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
542 0xff, 0xba, 0xdc, 0x0f, 0xfe, 0xe7, 0x01, 0x87, 0xe9, 0xb1, 0x25, 0x52, 0x44,
543 0x89, 0xd0, 0x43, 0x3d, 0xa7, 0x6f, 0xd8, 0x28, 0x7f, 0xa6, 0x52, 0xea, 0xeb,
544 0xde, 0x14, 0x7b, 0x45, 0xfa, 0x0c, 0xd8, 0x6f, 0x17, 0x18, 0x10, 0xff, 0xff,
545 0xff, 0x7f, 0x01
546 ]
547 );
548 }
549
550 #[test]
551 fn transaction_bits() {
552 let roi = ROInput::new()
553 .append_u64(1000000) .append_u64(1) .append_bool(true) .append_u32(0) .append_u32(u32::MAX) .append_bytes(&[0; 34]) .append_bool(false) .append_bool(false) .append_bool(false) .append_bool(true) .append_bool(false) .append_u64(1) .append_u64(10000000000) .append_bool(false) .append_scalar(
568 Fq::from_hex("de217a3017ca0b7a278e75f63c09890e3894be532d8dbadd30a7d450055f6d2d")
569 .expect("failed to create scalar"),
570 )
571 .append_bytes(&[0x01]);
572 assert_eq!(roi.bits.len(), 862);
573 assert_eq!(
574 roi.bits.as_raw_slice(),
575 [
576 0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x02,
581 0x95, 0x00, 0x00, 0x00, 0x00, 0xef, 0x10, 0x3d, 0x98, 0x0b, 0xe5, 0x05, 0xbd, 0x13,
582 0xc7, 0x3a, 0x7b, 0x9e, 0x84, 0x44, 0x07, 0x1c, 0x4a, 0xdf, 0xa9, 0x96, 0x46, 0xdd,
583 0x6e, 0x98, 0x53, 0x6a, 0xa8, 0x82, 0xaf, 0xb6, 0x56, 0x00
584 ]
585 )
586 }
587
588 #[test]
589 fn append_field() {
590 let roi = ROInput::new().append_field(
591 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
592 .expect("failed to create field"),
593 );
594
595 assert_eq!(
596 roi.to_bytes(),
597 [
598 0x2e, 0xae, 0xda, 0xe4, 0x2a, 0x74, 0x61, 0xd5, 0x95, 0x2d, 0x27, 0xb9, 0x7e, 0xca,
599 0xd0, 0x68, 0xb6, 0x98, 0xeb, 0xb9, 0x4e, 0x8a, 0x0e, 0x4c, 0x45, 0x38, 0x8b, 0xb6,
600 0x13, 0xde, 0x7e, 0x08
601 ]
602 );
603 }
604
605 #[test]
606 fn append_two_fields() {
607 let roi = ROInput::new()
608 .append_field(
609 Fp::from_hex("0cdaf334e9632268a5aa959c2781fb32bf45565fe244ae42c849d3fdc7c6441d")
610 .expect("failed to create field"),
611 )
612 .append_field(
613 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
614 .expect("failed to create field"),
615 );
616
617 assert_eq!(
618 roi.to_bytes(),
619 [
620 0x0c, 0xda, 0xf3, 0x34, 0xe9, 0x63, 0x22, 0x68, 0xa5, 0xaa, 0x95, 0x9c, 0x27, 0x81,
621 0xfb, 0x32, 0xbf, 0x45, 0x56, 0x5f, 0xe2, 0x44, 0xae, 0x42, 0xc8, 0x49, 0xd3, 0xfd,
622 0xc7, 0xc6, 0x44, 0x1d, 0x17, 0x57, 0x6d, 0x72, 0x15, 0xba, 0xb0, 0xea, 0xca, 0x96,
623 0x93, 0x5c, 0x3f, 0x65, 0x68, 0x34, 0x5b, 0xcc, 0xf5, 0x5c, 0x27, 0x45, 0x07, 0xa6,
624 0x22, 0x9c, 0x45, 0xdb, 0x09, 0x6f, 0x3f, 0x04
625 ]
626 );
627 }
628
629 #[test]
630 fn append_three_fields() {
631 let roi = ROInput::new()
632 .append_field(
633 Fp::from_hex("1f3f142986041b54427aa2032632e34df2fa9bde9bce70c04c5034266619e529")
634 .expect("failed to create field"),
635 )
636 .append_field(
637 Fp::from_hex("37f4433b85e753a91a1d79751645f1448954c433f9492e36a933ca7f3df61a04")
638 .expect("failed to create field"),
639 )
640 .append_field(
641 Fp::from_hex("6cf4772d3e1aab98a2b514b73a4f6e0df1fb4f703ecfa762196b22c26da4341c")
642 .expect("failed to create field"),
643 );
644
645 assert_eq!(
646 roi.to_bytes(),
647 [
648 0x1f, 0x3f, 0x14, 0x29, 0x86, 0x04, 0x1b, 0x54, 0x42, 0x7a, 0xa2, 0x03, 0x26, 0x32,
649 0xe3, 0x4d, 0xf2, 0xfa, 0x9b, 0xde, 0x9b, 0xce, 0x70, 0xc0, 0x4c, 0x50, 0x34, 0x26,
650 0x66, 0x19, 0xe5, 0xa9, 0x1b, 0xfa, 0xa1, 0x9d, 0xc2, 0xf3, 0xa9, 0x54, 0x8d, 0x8e,
651 0xbc, 0x3a, 0x8b, 0xa2, 0x78, 0xa2, 0x44, 0x2a, 0xe2, 0x99, 0xfc, 0x24, 0x17, 0x9b,
652 0xd4, 0x19, 0xe5, 0xbf, 0x1e, 0x7b, 0x0d, 0x02, 0x1b, 0xfd, 0x5d, 0x8b, 0x8f, 0xc6,
653 0x2a, 0xa6, 0x68, 0x2d, 0xc5, 0xad, 0xce, 0x93, 0x5b, 0x43, 0xfc, 0xfe, 0x13, 0x9c,
654 0xcf, 0xf3, 0xa9, 0x58, 0xc6, 0x9a, 0x88, 0x70, 0x1b, 0x29, 0x0d, 0x07
655 ]
656 );
657 }
658
659 #[test]
660 fn append_field_and_scalar() {
661 let roi = ROInput::new()
662 .append_field(
663 Fp::from_hex("64cde530327a36fcb88b6d769adca9b7c5d266e7d0042482203f3fd3a0d71721")
664 .expect("failed to create field"),
665 )
666 .append_scalar(
667 Fq::from_hex("604355d0daa455db783fd7ee11c5bd9b04d67ba64c27c95bef95e379f98c6432")
668 .expect("failed to create scalar"),
669 );
670
671 assert_eq!(
672 roi.to_bytes(),
673 [
674 0x64, 0xcd, 0xe5, 0x30, 0x32, 0x7a, 0x36, 0xfc, 0xb8, 0x8b, 0x6d, 0x76, 0x9a, 0xdc,
675 0xa9, 0xb7, 0xc5, 0xd2, 0x66, 0xe7, 0xd0, 0x04, 0x24, 0x82, 0x20, 0x3f, 0x3f, 0xd3,
676 0xa0, 0xd7, 0x17, 0x21, 0xb0, 0xa1, 0x2a, 0x68, 0x6d, 0xd2, 0xaa, 0x6d, 0xbc, 0x9f,
677 0x6b, 0xf7, 0x88, 0xe2, 0xde, 0x4d, 0x02, 0xeb, 0x3d, 0x53, 0xa6, 0x93, 0xe4, 0xad,
678 0xf7, 0xca, 0xf1, 0xbc, 0x7c, 0x46, 0x32, 0x19
679 ]
680 );
681 }
682
683 #[test]
684 fn append_field_bit_and_scalar() {
685 let roi = ROInput::new()
686 .append_field(
687 Fp::from_hex("d897c7a8b811d8acd3eeaa4adf42292802eed80031c2ad7c8989aea1fe94322c")
688 .expect("failed to create field"),
689 )
690 .append_bool(false)
691 .append_scalar(
692 Fq::from_hex("79586cc6b8b53c8991b2abe0ca76508f056ca50f06836ce4d818c2ff73d42b28")
693 .expect("failed to create scalar"),
694 );
695
696 assert_eq!(
697 roi.to_bytes(),
698 [
699 0xd8, 0x97, 0xc7, 0xa8, 0xb8, 0x11, 0xd8, 0xac, 0xd3, 0xee, 0xaa, 0x4a, 0xdf, 0x42,
700 0x29, 0x28, 0x02, 0xee, 0xd8, 0x00, 0x31, 0xc2, 0xad, 0x7c, 0x89, 0x89, 0xae, 0xa1,
701 0xfe, 0x94, 0x32, 0x2c, 0x79, 0x58, 0x6c, 0xc6, 0xb8, 0xb5, 0x3c, 0x89, 0x91, 0xb2,
702 0xab, 0xe0, 0xca, 0x76, 0x50, 0x8f, 0x05, 0x6c, 0xa5, 0x0f, 0x06, 0x83, 0x6c, 0xe4,
703 0xd8, 0x18, 0xc2, 0xff, 0x73, 0xd4, 0x2b, 0x28
704 ]
705 );
706 }
707
708 #[test]
709 fn to_bytes() {
710 let roi = ROInput::new()
711 .append_field(
712 Fp::from_hex("a5984f2bd00906f9a86e75bfb4b2c3625f1a0d1cfacc1501e8e82ae7041efc14")
713 .expect("failed to create field"),
714 )
715 .append_field(
716 Fp::from_hex("8af0bc770d49a5b9fcabfcdd033bab470b2a211ef80b710efe71315cfa818c0a")
717 .expect("failed to create field"),
718 )
719 .append_bool(false)
720 .append_u32(314u32)
721 .append_scalar(
722 Fq::from_hex("c23c43a23ddc1516578b0f0d81b93cdbbc97744acc697cfc8c5dfd01cc448323")
723 .expect("failed to create scalar"),
724 );
725
726 assert_eq!(
727 roi.to_bytes(),
728 [
729 0xa5, 0x98, 0x4f, 0x2b, 0xd0, 0x09, 0x06, 0xf9, 0xa8, 0x6e, 0x75, 0xbf, 0xb4, 0xb2,
730 0xc3, 0x62, 0x5f, 0x1a, 0x0d, 0x1c, 0xfa, 0xcc, 0x15, 0x01, 0xe8, 0xe8, 0x2a, 0xe7,
731 0x04, 0x1e, 0xfc, 0x14, 0x45, 0x78, 0xde, 0xbb, 0x86, 0xa4, 0xd2, 0x5c, 0xfe, 0x55,
732 0xfe, 0xee, 0x81, 0x9d, 0xd5, 0xa3, 0x05, 0x95, 0x10, 0x0f, 0xfc, 0x85, 0x38, 0x07,
733 0xff, 0xb8, 0x18, 0x2e, 0xfd, 0x40, 0x46, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x61, 0x9e,
734 0x21, 0xd1, 0x1e, 0xee, 0x0a, 0x8b, 0xab, 0xc5, 0x87, 0x86, 0xc0, 0x5c, 0x9e, 0x6d,
735 0xde, 0x4b, 0x3a, 0x25, 0xe6, 0x34, 0x3e, 0x7e, 0xc6, 0xae, 0xfe, 0x00, 0x66, 0xa2,
736 0xc1, 0x11
737 ]
738 );
739 }
740
741 #[test]
742 fn to_fields_1_scalar() {
743 let roi = ROInput::new().append_scalar(
744 Fq::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
745 .expect("failed to create scalar"),
746 );
747
748 assert_eq!(
749 roi.to_bytes(),
750 [
751 0x5d, 0x49, 0x6d, 0xd8, 0xff, 0x63, 0xf6, 0x40, 0xc0, 0x06, 0x88, 0x70, 0x98, 0x09,
752 0x2b, 0x16, 0xbc, 0x8c, 0x78, 0x50, 0x4f, 0x84, 0xfa, 0x1e, 0xe3, 0xa0, 0xb5, 0x4f,
753 0x85, 0xf0, 0xa6, 0x25
754 ]
755 );
756
757 assert_eq!(
758 roi.to_fields(),
759 [
760 Fp::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
761 .expect("failed to create field"),
762 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
763 .expect("failed to create field"),
764 ]
765 );
766 }
767
768 #[test]
769 fn to_fields_1_scalar_2_bits() {
770 let roi = ROInput::new()
771 .append_scalar(
772 Fq::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
773 .expect("failed to create scalar"),
774 )
775 .append_bool(false)
776 .append_bool(true);
777
778 assert_eq!(
779 roi.to_bytes(),
780 [
781 0xe8, 0xa9, 0x96, 0x1c, 0x8c, 0x41, 0x7b, 0x0d, 0x0e, 0x3d, 0x73, 0x66, 0xf6, 0xb0,
782 0xe6, 0xef, 0x90, 0xa6, 0xda, 0xd1, 0x23, 0x07, 0x0f, 0x71, 0x5e, 0x8a, 0x9e, 0xaa,
783 0x02, 0xe4, 0x73, 0x30, 0x01
784 ]
785 );
786
787 assert_eq!(
788 roi.to_fields(),
789 [
790 Fp::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
791 .expect("failed to create field"),
792 Fp::from_hex("0400000000000000000000000000000000000000000000000000000000000000")
793 .expect("failed to create field"),
794 ]
795 );
796 }
797
798 #[test]
799 fn to_fields_2_scalars() {
800 let roi = ROInput::new()
801 .append_scalar(
802 Fq::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
803 .expect("failed to create scalar"),
804 )
805 .append_scalar(
806 Fq::from_hex("c356dbb39478508818e0320dffa6c1ef512564366ec885ee2fc4d385dd36df0f")
807 .expect("failed to create scalar"),
808 );
809
810 assert_eq!(
811 roi.to_bytes(),
812 [
813 0xe0, 0x5c, 0x25, 0xd2, 0xc1, 0x7e, 0xc2, 0x0d, 0x6b, 0xc8, 0xfd, 0x21, 0x20, 0x4a,
814 0xf5, 0x28, 0x08, 0x45, 0x10, 0x76, 0xcf, 0xf6, 0x87, 0x40, 0x71, 0x64, 0xa2, 0x1d,
815 0x35, 0x2d, 0xdd, 0xa2, 0x61, 0xab, 0xed, 0x59, 0x4a, 0x3c, 0x28, 0x44, 0x0c, 0x70,
816 0x99, 0x86, 0x7f, 0xd3, 0xe0, 0xf7, 0xa8, 0x12, 0x32, 0x1b, 0x37, 0xe4, 0x42, 0xf7,
817 0x17, 0xe2, 0xe9, 0xc2, 0x6e, 0x9b, 0xef, 0x07
818 ]
819 );
820
821 assert_eq!(
822 roi.to_fields(),
823 [
824 Fp::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
825 .expect("failed to create field"),
826 Fp::from_hex("86adb66729f1a01031c0651afe4d83dfa34ac86cdc900bdd5f88a70bbb6dbe1f")
827 .expect("failed to create field"),
828 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
829 .expect("failed to create field"),
830 ]
831 );
832 }
833
834 #[test]
835 fn to_fields_2_bits_scalar_u32() {
836 let roi = ROInput::new()
837 .append_bool(true)
838 .append_bool(false)
839 .append_scalar(
840 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
841 .expect("failed to create scalar"),
842 )
843 .append_u32(834803);
844
845 assert_eq!(
846 roi.to_bytes(),
847 [
848 0xa1, 0x59, 0xd2, 0x78, 0x8f, 0xec, 0x18, 0x94, 0x68, 0x00, 0xb2, 0xf6, 0xd9, 0x13,
849 0x0d, 0x4a, 0x9e, 0x9c, 0xd4, 0xf9, 0xa9, 0x6b, 0x70, 0xbf, 0x31, 0x3c, 0x62, 0x10,
850 0x05, 0x3d, 0x87, 0x37, 0xe6, 0x79, 0x19, 0x00, 0x00
851 ]
852 );
853
854 assert_eq!(
855 roi.to_fields(),
856 [
857 Fp::from_hex("a159d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
858 .expect("failed to create field"),
859 Fp::from_hex("98e7650000000000000000000000000000000000000000000000000000000000")
860 .expect("failed to create field"),
861 ]
862 );
863 }
864
865 #[test]
866 fn to_fields_2_bits_field_scalar() {
867 let roi = ROInput::new()
868 .append_bool(false)
869 .append_bool(true)
870 .append_field(
871 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
872 .expect("failed to create field"),
873 )
874 .append_scalar(
875 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
876 .expect("failed to create scalar"),
877 );
878
879 assert_eq!(
880 roi.to_bytes(),
881 [
882 0x90, 0x92, 0x6b, 0x62, 0x0a, 0xd0, 0x9e, 0xd6, 0x16, 0xd5, 0xdf, 0x15, 0x85, 0x04,
883 0xfa, 0xed, 0x42, 0x92, 0x87, 0x19, 0xc5, 0x8a, 0xe6, 0x19, 0xd9, 0xec, 0xcc, 0x06,
884 0x2f, 0x92, 0x04, 0x11, 0xd1, 0x2c, 0x69, 0xbc, 0x47, 0x76, 0x0c, 0x4a, 0x34, 0x00,
885 0x59, 0xfb, 0xec, 0x89, 0x06, 0x25, 0x4f, 0x4e, 0xea, 0xfc, 0xd4, 0x35, 0xb8, 0xdf,
886 0x18, 0x1e, 0x31, 0x88, 0x82, 0x9e, 0xc3, 0x1b
887 ]
888 );
889
890 assert_eq!(
891 roi.to_fields(),
892 [
893 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
894 .expect("failed to create field"),
895 Fp::from_hex("a259d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
896 .expect("failed to create field"),
897 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
898 .expect("failed to create field"),
899 ]
900 );
901 }
902
903 #[test]
904 fn transaction_test_1() {
905 let roi = ROInput::new()
906 .append_field(
907 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
908 .expect("failed to create field"),
909 ) .append_field(
911 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
912 .expect("failed to create field"),
913 ) .append_field(
915 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
916 .expect("failed to create field"),
917 ) .append_u64(1000000) .append_u64(1) .append_bool(true) .append_u32(0) .append_u32(u32::MAX) .append_bytes(&[0; 34]) .append_bool(false) .append_bool(false) .append_bool(false) .append_bool(true) .append_bool(false) .append_u64(1) .append_u64(10000000000) .append_bool(false); assert_eq!(roi.bits.len() + roi.fields.len() * 255, 1364);
933 assert_eq!(
934 roi.to_bytes(),
935 [
936 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
937 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
938 0xa7, 0x42, 0xca, 0xa2, 0x4c, 0x16, 0x6d, 0xf9, 0x4f, 0xff, 0x0a, 0x59, 0x5e, 0xf5,
939 0x2e, 0x00, 0x72, 0xcc, 0xf6, 0xa7, 0xff, 0xe8, 0x8b, 0xe0, 0x4b, 0xf8, 0xfc, 0x42,
940 0x43, 0xf2, 0x82, 0x7b, 0x17, 0x7c, 0x47, 0xc0, 0x8f, 0xee, 0xd3, 0xe9, 0x86, 0x73,
941 0x43, 0xff, 0x7d, 0x02, 0xf6, 0x89, 0x11, 0x8c, 0x8d, 0x75, 0x0a, 0x05, 0xd6, 0xf7,
942 0xfb, 0xdd, 0x8b, 0xbd, 0xd7, 0x61, 0x6f, 0xdb, 0x86, 0x87, 0x81, 0x0a, 0x48, 0xe8,
943 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
944 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
946 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
947 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x5f, 0xa0, 0x12, 0x00,
948 0x00, 0x00, 0x00
949 ]
950 );
951
952 assert_eq!(
953 roi.to_fields(),
954 [
955 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
956 .expect("failed to create field"),
957 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
958 .expect("failed to create field"),
959 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
960 .expect("failed to create field"),
961 Fp::from_hex("40420f0000000000010000000000000001000000feffffff0100000000000000")
962 .expect("failed to create field"),
963 Fp::from_hex("0000000000000000000000000000000000000000000000000000400100000000")
964 .expect("failed to create field"),
965 Fp::from_hex("00000000902f5009000000000000000000000000000000000000000000000000")
966 .expect("failed to create field"),
967 ]
968 );
969 }
970
971 #[test]
972 fn nested_roinput_test() {
973 #[derive(Clone, Debug)]
974 struct A {
975 x: u32,
976 y: bool,
977 z: u32,
978 }
979
980 impl Hashable for A {
981 type D = ();
982
983 fn to_roinput(&self) -> ROInput {
984 ROInput::new()
985 .append_u32(self.x)
986 .append_bool(self.y)
987 .append_u32(self.z)
988 }
989
990 fn domain_string(_: Self::D) -> Option<String> {
991 "A".to_string().into()
992 }
993 }
994
995 #[derive(Clone, Debug)]
996 struct B1 {
997 a: A,
998 b: u64,
999 c: bool,
1000 }
1001
1002 impl Hashable for B1 {
1003 type D = ();
1004
1005 fn to_roinput(&self) -> ROInput {
1006 self.a.to_roinput().append_u64(self.b).append_bool(self.c)
1007 }
1008
1009 fn domain_string(_: Self::D) -> Option<String> {
1010 "B".to_string().into()
1011 }
1012 }
1013
1014 #[derive(Clone, Debug)]
1015 struct B2 {
1016 a: A,
1017 b: u64,
1018 c: bool,
1019 }
1020
1021 impl Hashable for B2 {
1022 type D = ();
1023
1024 fn to_roinput(&self) -> ROInput {
1025 self.a
1026 .to_roinput()
1027 .append_roinput(ROInput::new().append_u64(self.b).append_bool(self.c))
1028 }
1029
1030 fn domain_string(_: Self::D) -> Option<String> {
1031 "B".to_string().into()
1032 }
1033 }
1034
1035 let a = A {
1036 x: 16830533,
1037 y: false,
1038 z: 39827791,
1039 };
1040 let b1 = B1 {
1041 a,
1042 b: 124819,
1043 c: true,
1044 };
1045 let b2 = B2 {
1046 a: b1.a.clone(),
1047 b: b1.b,
1048 c: b1.c,
1049 };
1050
1051 assert_eq!(b1.to_roinput(), b2.to_roinput());
1052
1053 let b2 = B2 {
1054 a: b1.a.clone(),
1055 b: b1.b,
1056 c: false,
1057 };
1058 assert_ne!(b1.to_roinput(), b2.to_roinput());
1059
1060 let b2 = B2 {
1061 a: b1.a.clone(),
1062 b: b1.b + 1,
1063 c: b1.c,
1064 };
1065 assert_ne!(b1.to_roinput(), b2.to_roinput());
1066 }
1067
1068 #[test]
1069 fn serialize_empty() {
1070 let roi = ROInput::new();
1071
1072 let serialized = roi.serialize();
1073
1074 assert_eq!(
1075 serialized,
1076 vec![0; SER_HEADER_SIZE],
1077 "Serialized empty ROInput should be zero bytes"
1078 );
1079
1080 let deserialized_roi =
1081 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1082 assert_eq!(
1083 roi, deserialized_roi,
1084 "Serialized and deserialized ROInput do not match"
1085 );
1086 }
1087
1088 #[test]
1089 fn serialize_single_field() {
1090 let roi = ROInput::new().append_field(
1091 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1092 .expect("failed to create field"),
1093 );
1094
1095 let serialized = roi.serialize();
1096 let expected_length = SER_HEADER_SIZE + 32; assert_eq!(
1098 serialized.len(),
1099 expected_length,
1100 "Serialized ROInput length mismatch"
1101 );
1102 assert_eq!(
1103 serialized,
1104 [
1105 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
1108 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
1109 0xa7, 0x42, 0xca, 0x22
1110 ]
1111 .to_vec(),
1112 "Serialized ROInput does not match expected output"
1113 );
1114
1115 assert_eq!(
1116 roi,
1117 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1118 "Serialized and deserialized ROInput do not match"
1119 )
1120 }
1121
1122 #[test]
1123 fn serialize_single_bool() {
1124 let roi = ROInput::new().append_bool(true);
1125
1126 let serialized = roi.serialize();
1127 let expected_length = SER_HEADER_SIZE + 1; assert_eq!(
1129 serialized.len(),
1130 expected_length,
1131 "Serialized ROInput length mismatch"
1132 );
1133 assert_eq!(
1134 serialized,
1135 [
1136 0x00, 0x00, 0x00, 0x00,
1137 0x01, 0x00, 0x00, 0x00,
1138 0x01 ]
1140 .to_vec(),
1141 "Serialized ROInput does not match expected output"
1142 );
1143
1144 assert_eq!(
1145 roi,
1146 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1147 "Serialized and deserialized ROInput do not match"
1148 );
1149 }
1150
1151 #[test]
1152 fn serialize_multiple_bools_length() {
1153 for i in 0..1024 {
1154 let roi = ROInput::new().append_bool(i % 2 == 0);
1155 let serialized = roi.serialize();
1156
1157 let deserialized_roi =
1159 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1160 assert_eq!(
1161 roi, deserialized_roi,
1162 "Serialized and deserialized ROInput do not match for i={}",
1163 i
1164 );
1165 }
1166 }
1167
1168 #[test]
1169 fn deserialize_invalid() {
1170 let invalid_data = vec![0x01, 0x00, 0x00, 0x00]; let result = ROInput::deserialize(&invalid_data);
1173 assert!(
1174 result.is_err(),
1175 "Deserialization should fail for invalid data"
1176 );
1177 }
1178
1179 #[test]
1180 fn deserialize_invalid_inconsistent_bitlen() {
1181 let invalid_data = vec![
1182 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, ];
1187
1188 let result = ROInput::deserialize(&invalid_data);
1189 assert!(
1190 result.is_err(),
1191 "Deserialization should fail for inconsistent bit length"
1192 );
1193 }
1194
1195 #[test]
1196 fn deserialize_invalid_message() {
1197 let msg = b"Test message for Mina compatibility".to_vec();
1198 let result = ROInput::deserialize(&msg);
1199 assert!(
1200 result.is_err(),
1201 "Deserialization should fail for invalid message format"
1202 );
1203 }
1204
1205 #[test]
1206 fn deserialize_invalid_fieldheader() {
1207 let invalid_data = vec![
1208 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x01, ];
1213
1214 let result = ROInput::deserialize(&invalid_data);
1215 assert!(
1216 result.is_err(),
1217 "Deserialization should fail for overflow in field header"
1218 );
1219 }
1220
1221 #[test]
1222 fn serialize_tx() {
1223 let tx_roi = ROInput::new()
1224 .append_field(
1225 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1226 .expect("failed to create field"),
1227 )
1228 .append_field(
1229 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
1230 .expect("failed to create field"),
1231 ) .append_field(
1233 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
1234 .expect("failed to create field"),
1235 ) .append_u64(1000000) .append_u64(1) .append_bool(true) .append_u32(0) .append_u32(u32::MAX) .append_bytes(&[0; 34]) .append_bool(false) .append_bool(false) .append_bool(false) .append_bool(true) .append_bool(false) .append_u64(1) .append_u64(10000000000) .append_bool(false); let tx_bytes = tx_roi.serialize();
1252
1253 let deserialized_roi =
1254 ROInput::deserialize(&tx_bytes).expect("Failed to deserialize ROInput");
1255
1256 assert_eq!(
1257 tx_roi, deserialized_roi,
1258 "Serialized and deserialized ROInput do not match"
1259 );
1260 }
1261}