1use std::collections::BTreeMap;
2use std::num::NonZeroU8;
3
4use anyhow::Result;
5use bytes::Bytes;
6use num_bigint::{BigInt, BigUint};
7
8use crate::abi::error::AbiError;
9use crate::abi::{
10 AbiHeader, AbiHeaderType, AbiType, AbiValue, AbiVersion, NamedAbiType, NamedAbiValue,
11 PlainAbiType, PlainAbiValue,
12};
13use crate::cell::{Cell, CellSlice, Load, MAX_BIT_LEN, MAX_REF_COUNT};
14use crate::dict::{self, RawDict};
15use crate::error::Error;
16use crate::models::{AnyAddr, IntAddr};
17use crate::num::Tokens;
18
19impl NamedAbiValue {
20 pub fn load_tuple(
24 items: &[NamedAbiType],
25 version: AbiVersion,
26 slice: &mut CellSlice,
27 ) -> Result<Vec<Self>> {
28 let result = ok!(Self::load_tuple_ext(items, version, true, false, slice));
29 ok!(AbiValue::check_remaining(slice, false));
30 Ok(result)
31 }
32
33 pub fn load_tuple_partial(
35 items: &[NamedAbiType],
36 version: AbiVersion,
37 slice: &mut CellSlice,
38 ) -> Result<Vec<Self>> {
39 Self::load_tuple_ext(items, version, true, true, slice)
40 }
41
42 pub fn load_tuple_ext(
46 items: &[NamedAbiType],
47 version: AbiVersion,
48 last: bool,
49 allow_partial: bool,
50 slice: &mut CellSlice,
51 ) -> Result<Vec<Self>> {
52 let mut result = Vec::with_capacity(items.len());
53 let items_len = items.len();
54 for (i, item) in items.iter().enumerate() {
55 let last = last && i + 1 == items_len;
56 result.push(ok!(Self::load_ext(
57 item,
58 version,
59 last,
60 allow_partial,
61 slice
62 )));
63 }
64 Ok(result)
65 }
66
67 pub fn load(ty: &NamedAbiType, version: AbiVersion, slice: &mut CellSlice) -> Result<Self> {
71 let res = ok!(Self::load_ext(ty, version, true, false, slice));
72 ok!(AbiValue::check_remaining(slice, false));
73 Ok(res)
74 }
75
76 pub fn load_partial(
78 ty: &NamedAbiType,
79 version: AbiVersion,
80 slice: &mut CellSlice,
81 ) -> Result<Self> {
82 Self::load_ext(ty, version, true, true, slice)
83 }
84
85 pub fn load_ext(
89 ty: &NamedAbiType,
90 version: AbiVersion,
91 last: bool,
92 allow_partial: bool,
93 slice: &mut CellSlice,
94 ) -> Result<Self> {
95 Ok(Self {
96 value: ok!(AbiValue::load_ext(
97 &ty.ty,
98 version,
99 last,
100 allow_partial,
101 slice
102 )),
103 name: ty.name.clone(),
104 })
105 }
106}
107
108impl AbiValue {
109 pub fn check_remaining(slice: &mut CellSlice, allow_partial: bool) -> Result<()> {
111 anyhow::ensure!(
112 allow_partial || slice.is_data_empty() && slice.is_refs_empty(),
113 AbiError::IncompleteDeserialization
114 );
115 Ok(())
116 }
117
118 pub fn load_tuple(
122 types: &[AbiType],
123 version: AbiVersion,
124 slice: &mut CellSlice,
125 ) -> Result<Vec<Self>> {
126 let res = ok!(Self::load_tuple_ext(types, version, true, false, slice));
127 ok!(Self::check_remaining(slice, false));
128 Ok(res)
129 }
130
131 pub fn load_tuple_partial(
133 types: &[AbiType],
134 version: AbiVersion,
135 slice: &mut CellSlice,
136 ) -> Result<Vec<Self>> {
137 Self::load_tuple_ext(types, version, true, true, slice)
138 }
139
140 pub fn load_tuple_ext(
144 types: &[AbiType],
145 version: AbiVersion,
146 last: bool,
147 allow_partial: bool,
148 slice: &mut CellSlice,
149 ) -> Result<Vec<Self>> {
150 let mut result = Vec::with_capacity(types.len());
151 let types_len = types.len();
152 for (i, ty) in types.iter().enumerate() {
153 let last = last && i + 1 == types_len;
154 result.push(ok!(Self::load_ext(ty, version, last, allow_partial, slice)));
155 }
156 Ok(result)
157 }
158
159 pub fn load(ty: &AbiType, version: AbiVersion, slice: &mut CellSlice) -> Result<Self> {
163 let res = ok!(Self::load_ext(ty, version, true, false, slice));
164 ok!(Self::check_remaining(slice, false));
165 Ok(res)
166 }
167
168 pub fn load_partial(ty: &AbiType, version: AbiVersion, slice: &mut CellSlice) -> Result<Self> {
170 Self::load_ext(ty, version, true, true, slice)
171 }
172
173 pub fn load_ext(
177 ty: &AbiType,
178 version: AbiVersion,
179 last: bool,
180 allow_partial: bool,
181 slice: &mut CellSlice,
182 ) -> Result<Self> {
183 match ty {
184 AbiType::Uint(bits) => load_uint(*bits, slice).map(|value| Self::Uint(*bits, value)),
185 AbiType::Int(bits) => load_int(*bits, slice).map(|value| Self::Int(*bits, value)),
186 AbiType::VarUint(size) => {
187 load_varuint(*size, slice).map(|value| Self::VarUint(*size, value))
188 }
189 AbiType::VarInt(size) => {
190 load_varint(*size, slice).map(|value| Self::VarInt(*size, value))
191 }
192 AbiType::Bool => {
193 ok!(preload_bits(1, slice));
194 Ok(Self::Bool(slice.load_bit()?))
195 }
196 AbiType::Cell => load_cell(version, last, slice).map(Self::Cell),
197 AbiType::Address => {
198 ok!(preload_bits(1, slice));
199 Ok(Self::Address(AnyAddr::load_from(slice).map(Box::new)?))
200 }
201 AbiType::AddressStd => {
202 ok!(preload_bits(1, slice));
203 Ok(Self::AddressStd(match AnyAddr::load_from(slice)? {
204 AnyAddr::None => None,
205 AnyAddr::Std(addr) => Some(Box::new(addr)),
206 _ => anyhow::bail!("Expected StdAddr or None"),
207 }))
208 }
209 AbiType::Bytes => load_bytes(version, last, slice).map(Self::Bytes),
210 AbiType::FixedBytes(len) => {
211 load_fixed_bytes(*len, version, last, slice).map(Self::FixedBytes)
212 }
213 AbiType::String => load_string(version, last, slice).map(Self::String),
214 AbiType::Token => {
215 ok!(preload_bits(1, slice));
216 Ok(Self::Token(Tokens::load_from(slice)?))
217 }
218 AbiType::Tuple(items) => {
219 let values = ok!(NamedAbiValue::load_tuple_ext(
220 items,
221 version,
222 last,
223 allow_partial,
224 slice
225 ));
226 Ok(Self::Tuple(values))
227 }
228 AbiType::Array(ty) => load_array(ty, version, allow_partial, slice)
229 .map(|values| Self::Array(ty.clone(), values)),
230 AbiType::FixedArray(ty, len) => {
231 load_fixed_array(ty, *len, version, allow_partial, slice)
232 .map(|values| Self::FixedArray(ty.clone(), values))
233 }
234 AbiType::Map(key_ty, value_ty) => {
235 load_map(*key_ty, value_ty, version, allow_partial, slice)
236 .map(|value| Self::Map(*key_ty, value_ty.clone(), value))
237 }
238 AbiType::Optional(ty) => load_optional(ty, version, last, allow_partial, slice)
239 .map(|value| Self::Optional(ty.clone(), value)),
240 AbiType::Ref(ty) => load_ref(ty, version, last, allow_partial, slice).map(Self::Ref),
241 }
242 }
243}
244
245impl PlainAbiValue {
246 pub fn load(ty: PlainAbiType, slice: &mut CellSlice) -> Result<Self, Error> {
248 match ty {
249 PlainAbiType::Uint(bits) => {
250 load_uint_plain(bits, slice).map(|value| Self::Uint(bits, value))
251 }
252 PlainAbiType::Int(bits) => {
253 load_int_plain(bits, slice).map(|value| Self::Int(bits, value))
254 }
255 PlainAbiType::Bool => slice.load_bit().map(Self::Bool),
256 PlainAbiType::Address => IntAddr::load_from(slice).map(Box::new).map(Self::Address),
257 }
258 }
259}
260
261impl AbiHeader {
262 pub fn skip_all(headers: &[AbiHeaderType], slice: &mut CellSlice) -> Result<()> {
264 for header in headers {
265 ok!(Self::skip(*header, slice))
266 }
267 Ok(())
268 }
269
270 pub fn skip(ty: AbiHeaderType, slice: &mut CellSlice) -> Result<()> {
272 match ty {
273 AbiHeaderType::Time => {
274 ok!(preload_bits(64, slice));
275 slice.skip_first(64, 0)?;
276 }
277 AbiHeaderType::Expire => {
278 ok!(preload_bits(32, slice));
279 slice.skip_first(32, 0)?;
280 }
281 AbiHeaderType::PublicKey => {
282 ok!(preload_bits(1, slice));
283 if slice.load_bit()? {
284 ok!(preload_bits(256, slice));
285 slice.skip_first(256, 0)?;
286 }
287 }
288 }
289 Ok(())
290 }
291
292 pub fn load(ty: AbiHeaderType, slice: &mut CellSlice) -> Result<Self> {
294 Ok(match ty {
295 AbiHeaderType::Time => {
296 ok!(preload_bits(64, slice));
297 Self::Time(slice.load_u64()?)
298 }
299 AbiHeaderType::Expire => {
300 ok!(preload_bits(32, slice));
301 Self::Expire(slice.load_u32()?)
302 }
303 AbiHeaderType::PublicKey => {
304 ok!(preload_bits(1, slice));
305 Self::PublicKey(if slice.load_bit()? {
306 ok!(preload_bits(256, slice));
307 let Ok(pubkey) =
308 ed25519_dalek::VerifyingKey::from_bytes(slice.load_u256()?.as_array())
309 else {
310 anyhow::bail!(Error::InvalidPublicKey);
311 };
312 Some(Box::new(pubkey))
313 } else {
314 None
315 })
316 }
317 })
318 }
319}
320
321fn preload_bits(bits: u16, slice: &mut CellSlice) -> Result<()> {
322 if bits == 0 {
323 return Ok(());
324 }
325
326 let remaining_bits = slice.size_bits();
327 if remaining_bits == 0 {
328 let first_ref = slice.load_reference_as_slice()?;
329
330 anyhow::ensure!(slice.is_refs_empty(), AbiError::IncompleteDeserialization);
332
333 *slice = first_ref;
334 } else if remaining_bits < bits {
335 anyhow::bail!(Error::CellUnderflow);
336 }
337
338 Ok(())
339}
340
341fn load_uint(bits: u16, slice: &mut CellSlice) -> Result<BigUint> {
342 ok!(preload_bits(bits, slice));
343 load_uint_plain(bits, slice).map_err(From::from)
344}
345
346fn load_int(bits: u16, slice: &mut CellSlice) -> Result<BigInt> {
347 ok!(preload_bits(bits, slice));
348 load_int_plain(bits, slice).map_err(From::from)
349}
350
351fn load_uint_plain(bits: u16, slice: &mut CellSlice) -> Result<BigUint, Error> {
352 match bits {
353 0 => Ok(BigUint::default()),
354 1..=64 => slice.load_uint(bits).map(BigUint::from),
355 _ => {
356 let rem = bits % 8;
357 let mut buffer = vec![0u8; bits.div_ceil(8) as usize];
358 slice.load_raw(&mut buffer, bits)?;
359
360 buffer.reverse();
361 let mut int = BigUint::from_bytes_le(&buffer);
362 if rem != 0 {
363 int >>= 8 - rem;
364 }
365 Ok(int)
366 }
367 }
368}
369
370fn load_int_plain(bits: u16, slice: &mut CellSlice) -> Result<BigInt, Error> {
371 match bits {
372 0 => Ok(BigInt::default()),
373 1..=64 => slice.load_uint(bits).map(|mut int| {
374 if bits < 64 {
375 int |= ((int >> (bits - 1)) * u64::MAX) << (bits - 1);
377 }
378 BigInt::from(int as i64)
379 }),
380 _ => {
381 let rem = bits % 8;
382 let mut buffer = vec![0u8; bits.div_ceil(8) as usize];
383 slice.load_raw(&mut buffer, bits)?;
384
385 buffer.reverse();
386 let mut int = BigInt::from_signed_bytes_le(&buffer);
387 if rem != 0 {
388 int >>= 8 - rem;
389 }
390 Ok(int)
391 }
392 }
393}
394
395fn load_varuint(size: NonZeroU8, slice: &mut CellSlice) -> Result<BigUint> {
396 let bytes = ok!(load_varuint_raw(size, slice));
397 Ok(BigUint::from_bytes_le(&bytes))
398}
399
400fn load_varint(size: NonZeroU8, slice: &mut CellSlice) -> Result<BigInt> {
401 let bytes = ok!(load_varuint_raw(size, slice));
403 Ok(BigInt::from_signed_bytes_le(&bytes))
404}
405
406fn load_varuint_raw(size: NonZeroU8, slice: &mut CellSlice) -> Result<Vec<u8>> {
408 let value_size = size.get() - 1;
409
410 let len_bits = (8 - value_size.leading_zeros()) as u16;
411 ok!(preload_bits(len_bits, slice));
412
413 let value_bytes = slice.load_small_uint(len_bits)? as usize;
414 let value_bits = (value_bytes * 8) as u16;
415 ok!(preload_bits(value_bits, slice));
416
417 let mut bytes = vec![0u8; value_bytes];
418 slice.load_raw(&mut bytes, value_bits)?;
419
420 bytes.reverse();
422 Ok(bytes)
423}
424
425fn load_cell(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<Cell> {
426 if slice.size_refs() == 1
427 && (version.major == 1 && slice.cell().reference_count() as usize == MAX_REF_COUNT
428 || version.major > 1 && !last && slice.size_bits() == 0)
429 {
430 *slice = slice.load_reference_as_slice()?;
431 }
432 slice.load_reference_cloned().map_err(From::from)
433}
434
435fn load_bytes_raw(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<Vec<u8>> {
436 let cell = ok!(load_cell(version, last, slice));
437 let mut cell = cell.as_ref();
438
439 let mut bytes = Vec::new();
440 loop {
441 anyhow::ensure!(cell.bit_len() % 8 == 0, AbiError::ExpectedCellWithBytes);
442 bytes.extend_from_slice(cell.data());
443
444 match cell.reference(0) {
445 Some(child) => cell = child,
446 None => break Ok(bytes),
447 };
448 }
449}
450
451fn load_bytes(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<Bytes> {
452 load_bytes_raw(version, last, slice).map(Bytes::from)
453}
454
455fn load_fixed_bytes(
456 len: usize,
457 version: AbiVersion,
458 last: bool,
459 slice: &mut CellSlice,
460) -> Result<Bytes> {
461 if version >= AbiVersion::V2_4 {
462 let bit_len = len as u16 * 8;
463 ok!(preload_bits(bit_len, slice));
464 let mut buffer = vec![0u8; len];
465 let result = slice.load_raw(buffer.as_mut_slice(), bit_len)?;
466 Ok(Bytes::copy_from_slice(result))
467 } else {
468 let bytes = ok!(load_bytes(version, last, slice));
469 anyhow::ensure!(bytes.len() == len, AbiError::BytesSizeMismatch {
470 expected: len,
471 len: bytes.len()
472 });
473 Ok(bytes)
474 }
475}
476
477fn load_string(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<String> {
478 let bytes = ok!(load_bytes_raw(version, last, slice));
479 match String::from_utf8(bytes) {
480 Ok(str) => Ok(str),
481 Err(e) => Err(AbiError::InvalidString(e.utf8_error()).into()),
482 }
483}
484
485fn load_array_raw(
486 ty: &AbiType,
487 len: usize,
488 version: AbiVersion,
489 allow_partial: bool,
490 slice: &mut CellSlice,
491) -> Result<Vec<AbiValue>> {
492 ok!(preload_bits(1, slice));
493 let dict = RawDict::<32>::load_from(slice)?;
494
495 let mut result = Vec::with_capacity(len);
496 for value in dict.values().take(len) {
497 let slice = &mut value?;
498 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
499 ok!(AbiValue::check_remaining(slice, allow_partial));
500 result.push(value);
501 }
502
503 Ok(result)
504}
505
506fn load_array(
507 ty: &AbiType,
508 version: AbiVersion,
509 allow_partial: bool,
510 slice: &mut CellSlice,
511) -> Result<Vec<AbiValue>> {
512 ok!(preload_bits(32, slice));
513 let len = slice.load_u32()?;
514 load_array_raw(ty, len as usize, version, allow_partial, slice)
515}
516
517fn load_fixed_array(
518 ty: &AbiType,
519 len: usize,
520 version: AbiVersion,
521 allow_partial: bool,
522 slice: &mut CellSlice,
523) -> Result<Vec<AbiValue>> {
524 let values = ok!(load_array_raw(ty, len, version, allow_partial, slice));
525 anyhow::ensure!(values.len() == len, AbiError::ArraySizeMismatch {
526 expected: len,
527 len: values.len()
528 });
529 Ok(values)
530}
531
532fn load_map(
533 key_ty: PlainAbiType,
534 value_ty: &AbiType,
535 version: AbiVersion,
536 allow_partial: bool,
537 slice: &mut CellSlice,
538) -> Result<BTreeMap<PlainAbiValue, AbiValue>> {
539 ok!(preload_bits(1, slice));
540
541 let key_bits = key_ty.key_bits();
542 let dict = Option::<Cell>::load_from(slice)?;
543
544 let mut result = BTreeMap::new();
545 for entry in dict::RawIter::new(&dict, key_bits) {
546 let (key, mut slice) = entry?;
547 let key = PlainAbiValue::load(key_ty, &mut key.as_data_slice())?;
548 let value = ok!(AbiValue::load_ext(
549 value_ty,
550 version,
551 true,
552 allow_partial,
553 &mut slice
554 ));
555 result.insert(key, value);
556 }
557
558 Ok(result)
559}
560
561fn load_optional(
562 ty: &AbiType,
563 version: AbiVersion,
564 last: bool,
565 allow_partial: bool,
566 slice: &mut CellSlice,
567) -> Result<Option<Box<AbiValue>>> {
568 ok!(preload_bits(1, slice));
569
570 if !slice.load_bit()? {
571 return Ok(None);
572 }
573
574 let ty_size = ty.max_size(version);
575 if ty_size.bit_count < MAX_BIT_LEN as u64 && ty_size.cell_count < MAX_REF_COUNT as u64 {
576 let value = ok!(AbiValue::load_ext(ty, version, last, allow_partial, slice));
577 Ok(Some(Box::new(value)))
578 } else {
579 let cell = ok!(load_cell(version, last, slice));
580 let slice = &mut cell.as_slice()?;
581 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
582 ok!(AbiValue::check_remaining(slice, allow_partial));
583 Ok(Some(Box::new(value)))
584 }
585}
586
587fn load_ref(
588 ty: &AbiType,
589 version: AbiVersion,
590 last: bool,
591 allow_partial: bool,
592 slice: &mut CellSlice,
593) -> Result<Box<AbiValue>> {
594 let cell = ok!(load_cell(version, last, slice));
595 let slice = &mut cell.as_slice()?;
596 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
597 ok!(AbiValue::check_remaining(slice, allow_partial));
598 Ok(Box::new(value))
599}
600
601#[cfg(test)]
602mod tests {
603 use std::sync::Arc;
604
605 use super::*;
606 use crate::boc::Boc;
607 use crate::dict::Dict;
608 use crate::models::{StdAddr, VarAddr};
609 use crate::num::{Uint9, VarUint24, VarUint56};
610 use crate::prelude::{CellBuilder, CellFamily, HashBytes, Store};
611
612 trait BuildCell {
613 fn build_cell(&self) -> Result<Cell>;
614 }
615
616 impl<T: Store> BuildCell for T {
617 fn build_cell(&self) -> Result<Cell> {
618 CellBuilder::build_from(self).map_err(From::from)
619 }
620 }
621
622 impl BuildCell for &str {
623 fn build_cell(&self) -> Result<Cell> {
624 Boc::decode_base64(self).map_err(From::from)
625 }
626 }
627
628 fn load_simple<T>(version: AbiVersion, boc: T, expected: AbiValue) -> Result<()>
629 where
630 T: BuildCell,
631 {
632 let cell = boc.build_cell()?;
633 let ty = expected.get_type();
634 assert_eq!(
635 AbiValue::load(&ty, version, &mut cell.as_slice()?)?,
636 expected
637 );
638 Ok(())
639 }
640
641 fn load_tuple<T>(version: AbiVersion, boc: T, expected: &[AbiValue]) -> Result<()>
642 where
643 T: BuildCell,
644 {
645 let cell = boc.build_cell()?;
646 let ty = expected.iter().map(AbiValue::get_type).collect::<Vec<_>>();
647 assert_eq!(
648 AbiValue::load_tuple(&ty, version, &mut cell.as_slice()?)?,
649 expected
650 );
651 Ok(())
652 }
653
654 macro_rules! assert_basic_err {
655 ($expr:expr, $err:expr) => {{
656 match $expr {
657 Ok(_) => panic!("Expected basic error: {:?}, got success", $err),
658 Err(e) => {
659 if let Some(e) = e.downcast_ref::<Error>() {
660 assert_eq!(e, &($err));
661 } else {
662 panic!("Unexpected error: {e:?}");
663 }
664 }
665 }
666 }};
667 }
668
669 macro_rules! assert_abi_err {
670 ($expr:expr, $err:expr) => {{
671 match $expr {
672 Ok(_) => panic!("Expected ABI error: {:?}, got success", $err),
673 Err(e) => {
674 if let Some(e) = e.downcast_ref::<AbiError>() {
675 assert_eq!(e, &($err));
676 } else {
677 panic!("Unexpected error: {e:?}");
678 }
679 }
680 }
681 }};
682 }
683
684 const VX_X: [AbiVersion; 5] = [
685 AbiVersion::V1_0,
686 AbiVersion::V2_0,
687 AbiVersion::V2_1,
688 AbiVersion::V2_2,
689 AbiVersion::V2_3,
690 ];
691 const V2_X: [AbiVersion; 4] = [
692 AbiVersion::V2_0,
693 AbiVersion::V2_1,
694 AbiVersion::V2_2,
695 AbiVersion::V2_3,
696 ];
697
698 #[test]
699 fn failed_decode() -> Result<()> {
700 for v in VX_X {
701 assert_basic_err!(
702 load_simple(v, false, AbiValue::uint(32, 0u32)),
703 Error::CellUnderflow
704 );
705
706 assert_abi_err!(
707 load_simple(v, u64::MAX, AbiValue::uint(32, 0u32)),
708 AbiError::IncompleteDeserialization
709 );
710
711 assert_abi_err!(
712 load_tuple(v, u64::MAX, &[AbiValue::uint(32, u32::MAX)]),
713 AbiError::IncompleteDeserialization
714 );
715 }
716
717 Ok(())
718 }
719
720 #[test]
721 fn decode_int() -> Result<()> {
722 macro_rules! define_tests {
723 ($v:ident, { $($abi:ident($bits:literal) => [$($expr:expr),*$(,)?]),*$(,)? }) => {$(
724 $(load_simple($v, $expr, AbiValue::$abi($bits, $expr))?;)*
725 )*};
726 }
727
728 for v in VX_X {
729 define_tests!(v, {
730 uint(8) => [0u8, 123u8, u8::MAX],
731 uint(16) => [0u16, 1234u16, u16::MAX],
732 uint(32) => [0u32, 123456u32, u32::MAX],
733 uint(64) => [0u64, 123456789u64, u64::MAX],
734 uint(128) => [0u128, 123456789123123123123u128, u128::MAX],
735
736 int(8) => [0i8, 123i8, i8::MIN, i8::MAX],
737 int(16) => [0i16, 1234i16, i16::MIN, i16::MAX],
738 int(32) => [0i32, 123456i32, i32::MIN, i32::MAX],
739 int(64) => [0i64, 123456789i64, i64::MIN, i64::MAX],
740 int(128) => [0i128, 123456789123123123123i128, i128::MIN, i128::MAX],
741 });
742 }
743
744 Ok(())
745 }
746
747 #[test]
748 fn decode_varint() -> Result<()> {
749 for v in VX_X {
750 println!("ABIv{v}");
751 load_simple(v, VarUint24::ZERO, AbiValue::varuint(4, 0u32))?;
752 load_simple(v, VarUint24::MAX, AbiValue::varuint(4, u32::MAX >> 8))?;
753 load_simple(v, VarUint24::new(123321), AbiValue::varuint(4, 123321u32))?;
754
755 load_simple(v, VarUint56::ZERO, AbiValue::varuint(8, 0u32))?;
756 load_simple(v, VarUint56::MAX, AbiValue::varuint(8, u64::MAX >> 8))?;
757 load_simple(
758 v,
759 VarUint56::new(1233213213123123),
760 AbiValue::varuint(8, 1233213213123123u64),
761 )?;
762
763 load_simple(
764 v,
765 "te6ccgEBAQEABgAABzAeG5g=",
766 AbiValue::varuint(16, 123321u32),
767 )?;
768 load_simple(v, "te6ccgEBAQEABgAABzAeG5g=", AbiValue::varint(16, 123321))?;
769
770 load_simple(v, Tokens::ZERO, AbiValue::varuint(16, 0u32))?;
771 load_simple(v, Tokens::ZERO, AbiValue::Token(Tokens::ZERO))?;
772
773 let mut prev_value = 0;
774 for byte in 0..15 {
775 let value = (0xffu128 << (byte * 8)) | prev_value;
776 prev_value = value;
777 load_simple(v, Tokens::new(value), AbiValue::varuint(16, value))?;
778 load_simple(v, Tokens::new(value), AbiValue::Token(Tokens::new(value)))?;
779 }
780 }
781
782 Ok(())
783 }
784
785 #[test]
786 fn decode_bool() -> Result<()> {
787 for v in VX_X {
788 println!("ABIv{v}");
789 load_simple(v, false, AbiValue::Bool(false))?;
790 load_simple(v, true, AbiValue::Bool(true))?;
791 }
792 Ok(())
793 }
794
795 #[test]
796 fn decode_cell() -> Result<()> {
797 {
799 load_simple(
800 AbiVersion::V1_0,
801 "te6ccgEBAgEABQABAAEAAA==", AbiValue::Cell(Cell::empty_cell()),
803 )?;
804
805 let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
807 let slice = &mut cell.as_slice()?;
808 slice.skip_first(0, 3)?;
809
810 assert_basic_err!(
811 AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice),
812 Error::CellUnderflow
813 );
814
815 let cell = Boc::decode_base64("te6ccgEBAwEACwAEAAICAgEBAAIAAA==")?;
817 let slice = &mut cell.as_slice()?;
818 slice.skip_first(0, 3)?;
819
820 assert_eq!(
821 AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice)?,
822 AbiValue::Cell(Cell::empty_cell())
823 );
824 }
825
826 for v in V2_X {
827 println!("ABIv{v}");
828 load_simple(
829 v,
830 "te6ccgEBAgEABQABAAEAAA==", AbiValue::Cell(Cell::empty_cell()),
832 )?;
833
834 let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
836 let slice = &mut cell.as_slice()?;
837 slice.skip_first(0, 3)?;
838
839 assert_eq!(
840 AbiValue::load(&AbiType::Cell, v, slice)?,
841 AbiValue::Cell(Cell::empty_cell())
842 );
843 }
844
845 Ok(())
846 }
847
848 #[test]
849 fn decode_address() -> Result<()> {
850 for v in VX_X {
851 println!("ABIv{v}");
852 let addr: StdAddr = StdAddr::from((0i8, [0xffu8; 32]));
853 load_simple(
854 v,
855 addr.clone(),
856 AbiValue::Address(Box::new(AnyAddr::Std(addr))),
857 )?;
858
859 let addr: VarAddr = VarAddr {
860 address_len: Uint9::new(10 * 8),
861 anycast: None,
862 workchain: 123456,
863 address: vec![0xffu8; 10],
864 };
865 load_simple(
866 v,
867 addr.clone(),
868 AbiValue::Address(Box::new(AnyAddr::Var(addr))),
869 )?;
870 }
871
872 Ok(())
873 }
874
875 #[test]
876 fn decode_bytes() -> Result<()> {
877 for v in VX_X {
878 println!("ABIv{v}");
879 for len in 0..20 {
880 let mut bytes = vec![0xffu8; 1usize << len];
881 bytes[0] = 0x55; let bytes = Bytes::from(bytes);
883 let serialized = AbiValue::Bytes(bytes.clone()).make_cell(v)?;
884
885 load_simple(v, serialized.clone(), AbiValue::Bytes(bytes.clone()))?;
886 load_simple(v, serialized.clone(), AbiValue::FixedBytes(bytes.clone()))?;
887
888 let original = bytes.len();
889 assert_abi_err!(
890 load_simple(
891 v,
892 serialized.clone(),
893 AbiValue::FixedBytes(bytes.slice(..original / 2))
894 ),
895 AbiError::BytesSizeMismatch {
896 expected: original / 2,
897 len: original
898 }
899 )
900 }
901 }
902
903 Ok(())
904 }
905
906 #[test]
907 fn decode_string() -> Result<()> {
908 for v in VX_X {
909 println!("ABIv{v}");
910 for len in 0..20 {
911 let mut bytes = vec![b'a'; 1usize << len];
912 bytes[0] = b'f'; let string = String::from_utf8(bytes)?;
914
915 let serialized = AbiValue::String(string.clone()).make_cell(v)?;
916 load_simple(v, serialized.clone(), AbiValue::String(string))?;
917 }
918 }
919
920 Ok(())
921 }
922
923 #[test]
924 fn decode_nested_simple_tuple() -> Result<()> {
925 let cell = {
926 let mut builder = CellBuilder::new();
927 builder.store_u32(0)?;
928 builder.store_reference(Cell::empty_cell())?;
929 builder.store_bit_zero()?;
930 builder.store_u8(-15_i8 as _)?;
931 builder.store_u16(-9845_i16 as _)?;
932 builder.store_u32(-1_i32 as _)?;
933 builder.store_u64(12345678_i64 as _)?;
934 builder.store_u128(-12345678_i128 as _)?;
935 builder.store_u8(255)?;
936 builder.store_u16(0)?;
937 builder.store_u32(256)?;
938 builder.store_u64(123)?;
939 builder.store_u128(1234567890)?;
940 builder.build()?
941 };
942
943 let value = AbiValue::unnamed_tuple([
944 AbiValue::uint(32, 0u32),
945 AbiValue::Cell(Cell::empty_cell()),
946 AbiValue::Bool(false),
947 AbiValue::unnamed_tuple([
948 AbiValue::int(8, -15),
949 AbiValue::int(16, -9845),
950 AbiValue::unnamed_tuple([
951 AbiValue::int(32, -1),
952 AbiValue::int(64, 12345678),
953 AbiValue::int(128, -12345678),
954 ]),
955 ]),
956 AbiValue::unnamed_tuple([
957 AbiValue::uint(8, 255_u8),
958 AbiValue::uint(16, 0_u16),
959 AbiValue::unnamed_tuple([
960 AbiValue::uint(32, 256_u32),
961 AbiValue::uint(64, 123_u64),
962 AbiValue::uint(128, 1234567890_u128),
963 ]),
964 ]),
965 ]);
966
967 for v in VX_X {
968 println!("ABIv{v}");
969 load_simple(v, cell.clone(), value.clone())?;
970 }
971
972 Ok(())
973 }
974
975 #[test]
976 fn decode_tuple_four_refs_and_four_uint256() -> Result<()> {
977 let bytes = HashBytes([0xff; 32]);
978 let bytes_cell = CellBuilder::build_from(bytes)?;
979
980 let cell = {
981 let mut builder = CellBuilder::new();
982 builder.store_u32(0)?;
983 builder.store_reference(Cell::empty_cell())?;
984
985 builder.store_reference(bytes_cell.clone())?;
986 builder.store_reference(bytes_cell.clone())?;
987
988 let mut second_builder = CellBuilder::new();
989 second_builder.store_reference(bytes_cell.clone())?;
990 second_builder.store_u256(&bytes)?;
991 second_builder.store_u256(&bytes)?;
992 second_builder.store_u256(&bytes)?;
993
994 let mut third_builder = CellBuilder::new();
995 third_builder.store_u256(&bytes)?;
996
997 second_builder.store_reference(third_builder.build()?)?;
998 builder.store_reference(second_builder.build()?)?;
999
1000 builder.build()?
1001 };
1002
1003 let value = AbiValue::unnamed_tuple([
1004 AbiValue::uint(32, 0_u32),
1005 AbiValue::Cell(Cell::empty_cell()),
1006 AbiValue::Cell(bytes_cell.clone()),
1007 AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1008 AbiValue::Cell(bytes_cell),
1009 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1010 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1011 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1012 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1013 ]);
1014
1015 for v in VX_X {
1016 println!("ABIv{v}");
1017 load_simple(v, cell.clone(), value.clone())?;
1018 }
1019
1020 Ok(())
1021 }
1022
1023 #[test]
1024 fn decode_tuple_four_refs_and_one_uint256() -> Result<()> {
1025 let bytes = HashBytes([0x55; 32]);
1026 let bytes_cell = CellBuilder::build_from(bytes)?;
1027
1028 let mut builder = CellBuilder::new();
1029 builder.store_u32(0)?;
1030 builder.store_reference(Cell::empty_cell())?;
1031
1032 builder.store_reference(bytes_cell.clone())?;
1033 builder.store_reference(bytes_cell.clone())?;
1034
1035 let cell_v2 = {
1036 let mut builder = builder.clone();
1037 builder.store_reference(bytes_cell.clone())?;
1038 builder.store_u256(&bytes)?;
1039 builder.build()?
1040 };
1041
1042 let cell_v1 = {
1043 let mut child_builder = CellBuilder::new();
1044 child_builder.store_reference(bytes_cell.clone())?;
1045 child_builder.store_u256(&bytes)?;
1046
1047 builder.store_reference(child_builder.build()?)?;
1048 builder.build()?
1049 };
1050
1051 let value = AbiValue::unnamed_tuple([
1052 AbiValue::uint(32, 0_u32),
1053 AbiValue::Cell(Cell::empty_cell()),
1054 AbiValue::Cell(bytes_cell.clone()),
1055 AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1056 AbiValue::Cell(bytes_cell.clone()),
1057 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1058 ]);
1059
1060 load_simple(AbiVersion::V1_0, cell_v1, value.clone())?;
1061 for v in V2_X {
1062 println!("ABIv{v}");
1063 load_simple(v, cell_v2.clone(), value.clone())?;
1064 }
1065
1066 Ok(())
1067 }
1068
1069 #[test]
1070 fn decode_map_simple() -> Result<()> {
1071 let bytes = HashBytes([0x55; 32]);
1072 let bytes_cell = CellBuilder::build_from(bytes)?;
1073
1074 let mut bytes_map = Dict::<u8, Cell>::new();
1075 for i in 1..=3 {
1076 bytes_map.set(i, bytes_cell.clone())?;
1077 }
1078 let bytes_map_value = AbiValue::map([
1079 (1u8, Bytes::copy_from_slice(bytes.as_slice())),
1080 (2, Bytes::copy_from_slice(bytes.as_slice())),
1081 (3, Bytes::copy_from_slice(bytes.as_slice())),
1082 ]);
1083
1084 let mut int_map = Dict::<i16, i128>::new();
1085 for i in -1..=1 {
1086 int_map.set(i, i as i128)?;
1087 }
1088 let int_map_value = AbiValue::map([(-1i16, -1i128), (0, 0), (1, 1)]);
1089
1090 let mut tuples_map = Dict::<u128, (u32, bool)>::new();
1091 for i in 1..=5 {
1092 tuples_map.set(i as u128, (i, i % 2 != 0))?;
1093 }
1094 let tuples_map_value = AbiValue::map([
1095 (1u128, (1u32, true)),
1096 (2, (2, false)),
1097 (3, (3, true)),
1098 (4, (4, false)),
1099 (5, (5, true)),
1100 ]);
1101
1102 let context = Cell::empty_context();
1104 let mut builder = CellBuilder::new();
1105 builder.store_u32(0)?;
1106 builder.store_reference(Cell::empty_cell())?;
1107
1108 bytes_map.store_into(&mut builder, context)?;
1109 int_map.store_into(&mut builder, context)?;
1110
1111 let cell_v2 = {
1112 let mut builder = builder.clone();
1113 tuples_map.store_into(&mut builder, context)?;
1114 builder.store_bit_zero()?;
1115 builder.build()?
1116 };
1117
1118 let cell_v1 = {
1119 let mut child_builder = CellBuilder::new();
1120 tuples_map.store_into(&mut child_builder, context)?;
1121 child_builder.store_bit_zero()?;
1122
1123 builder.store_reference(child_builder.build()?)?;
1124 builder.build()?
1125 };
1126
1127 let value = AbiValue::unnamed_tuple([
1128 AbiValue::uint(32, 0u32),
1129 AbiValue::Cell(Cell::empty_cell()),
1130 bytes_map_value,
1131 int_map_value,
1132 tuples_map_value,
1133 AbiValue::map([] as [(HashBytes, bool); 0]),
1134 ]);
1135
1136 for v in VX_X {
1137 println!("ABIv{v}");
1138 load_simple(v, cell_v1.clone(), value.clone())?;
1139 }
1140
1141 for v in V2_X {
1142 println!("ABIv{v}");
1143 load_simple(v, cell_v2.clone(), value.clone())?;
1144 }
1145
1146 Ok(())
1147 }
1148
1149 #[test]
1150 fn decode_map_address() -> Result<()> {
1151 let addr1 = StdAddr::new(0, HashBytes([0x11; 32]));
1152 let addr2 = StdAddr::new(0, HashBytes([0x22; 32]));
1153
1154 let mut addr_map = Dict::<StdAddr, u32>::new();
1155 addr_map.set(&addr1, 123)?;
1156 addr_map.set(&addr2, 456)?;
1157
1158 let addr_map_value = AbiValue::map([(addr1, 123u32), (addr2, 456)]);
1159
1160 let cell = {
1162 let mut builder = CellBuilder::new();
1163 builder.store_u32(0)?;
1164 builder.store_reference(Cell::empty_cell())?;
1165 addr_map.store_into(&mut builder, Cell::empty_context())?;
1166 builder.build()?
1167 };
1168
1169 let value = AbiValue::unnamed_tuple([
1170 AbiValue::uint(32, 0u32),
1171 AbiValue::Cell(Cell::empty_cell()),
1172 addr_map_value,
1173 ]);
1174
1175 for v in VX_X {
1176 println!("ABIv{v}");
1177 load_simple(v, cell.clone(), value.clone())?;
1178 }
1179
1180 Ok(())
1181 }
1182
1183 #[test]
1184 fn decode_map_big_value() -> Result<()> {
1185 let mut map_value = CellBuilder::new();
1186 map_value.store_u128(0)?;
1187 map_value.store_u128(1)?;
1188 map_value.store_u128(0)?;
1189 map_value.store_u128(2)?;
1190 map_value.store_u128(0)?;
1191 map_value.store_u128(3)?;
1192 map_value.store_reference(CellBuilder::build_from((0u128, 4u128))?)?;
1193 let map_value = map_value.build()?;
1194
1195 let mut key = CellBuilder::new();
1196 key.store_u128(0)?;
1197 key.store_u128(123)?;
1198
1199 let mut map = RawDict::<256>::new();
1200 map.set(key.as_data_slice(), &map_value)?;
1201
1202 let mut key = CellBuilder::new();
1204 key.store_u32(0)?;
1205
1206 let mut array = RawDict::<32>::new();
1207 array.set(key.as_data_slice(), &map_value)?;
1208
1209 let tuple_value = AbiValue::unnamed_tuple([
1211 AbiValue::uint(256, 1_u32),
1212 AbiValue::uint(256, 2_u32),
1213 AbiValue::uint(256, 3_u32),
1214 AbiValue::uint(256, 4_u32),
1215 ]);
1216
1217 let value = AbiValue::unnamed_tuple([
1218 AbiValue::uint(32, 0u32),
1219 AbiValue::Cell(Cell::empty_cell()),
1220 AbiValue::Map(
1221 PlainAbiType::Uint(256),
1222 Arc::new(tuple_value.get_type()),
1223 BTreeMap::from([(
1224 PlainAbiValue::Uint(256, BigUint::from(123u32)),
1225 tuple_value.clone(),
1226 )]),
1227 ),
1228 AbiValue::Array(Arc::new(tuple_value.get_type()), vec![tuple_value]),
1229 ]);
1230
1231 let cell = {
1233 let context = Cell::empty_context();
1234 let mut builder = CellBuilder::new();
1235 builder.store_u32(0)?;
1236 builder.store_reference(Cell::empty_cell())?;
1237
1238 map.store_into(&mut builder, context)?;
1239
1240 builder.store_u32(1)?;
1241 array.store_into(&mut builder, context)?;
1242
1243 builder.build()?
1244 };
1245
1246 for v in V2_X {
1247 println!("ABIv{v}");
1248 load_simple(v, cell.clone(), value.clone())?;
1249 }
1250
1251 Ok(())
1252 }
1253
1254 #[test]
1255 fn decode_optional() -> Result<()> {
1256 const STR: &str = "Some string";
1257
1258 let string_cell = {
1259 let mut builder = CellBuilder::new();
1260 builder.store_raw(STR.as_bytes(), (STR.len() * 8) as u16)?;
1261 builder.build()?
1262 };
1263 let string_value = AbiValue::String(STR.to_owned());
1264
1265 let tuple_value = AbiValue::unnamed_tuple([
1266 string_value.clone(),
1267 string_value.clone(),
1268 string_value.clone(),
1269 string_value.clone(),
1270 ]);
1271
1272 let value = AbiValue::unnamed_tuple([
1273 AbiValue::uint(32, 0u32),
1274 AbiValue::Cell(Cell::empty_cell()),
1275 AbiValue::varint(16, -123),
1276 AbiValue::varuint(32, 456u32),
1277 AbiValue::optional(None::<bool>),
1278 AbiValue::Optional(
1279 Arc::new(AbiType::Uint(1022)),
1280 Some(Box::new(AbiValue::uint(1022, 1u32))),
1281 ),
1282 AbiValue::Optional(
1283 Arc::new(AbiType::varuint(128)),
1284 Some(Box::new(AbiValue::varuint(128, 123u32))),
1285 ),
1286 AbiValue::Optional(
1287 Arc::new(tuple_value.get_type()),
1288 Some(Box::new(tuple_value)),
1289 ),
1290 ]);
1291
1292 let cell = {
1293 let mut builder = CellBuilder::new();
1294 builder.store_u32(0)?;
1295 builder.store_reference(Cell::empty_cell())?;
1296
1297 builder.store_small_uint(1, 4)?;
1298 builder.store_u8(-123i8 as _)?;
1299
1300 builder.store_small_uint(2, 5)?;
1301 builder.store_u16(456)?;
1302
1303 builder.store_bit_zero()?;
1304
1305 builder.store_reference({
1306 let mut builder = CellBuilder::new();
1307 builder.store_bit_one()?;
1308 builder.store_zeros(127 * 8)?;
1309 builder.store_small_uint(1, 6)?;
1310
1311 builder.store_reference({
1312 let mut builder = CellBuilder::new();
1313 builder.store_bit_one()?;
1314 builder.store_reference({
1315 let mut builder = CellBuilder::new();
1316 builder.store_small_uint(1, 7)?;
1317 builder.store_u8(123)?;
1318 builder.build()?
1319 })?;
1320
1321 builder.store_bit_one()?;
1322 builder.store_reference(CellBuilder::build_from((
1323 string_cell.clone(),
1324 string_cell.clone(),
1325 string_cell.clone(),
1326 string_cell.clone(),
1327 ))?)?;
1328
1329 builder.build()?
1330 })?;
1331
1332 builder.build()?
1333 })?;
1334
1335 builder.build()?
1336 };
1337
1338 for v in V2_X {
1339 println!("ABIv{v}");
1340 load_simple(v, cell.clone(), value.clone())?;
1341 }
1342
1343 Ok(())
1344 }
1345
1346 #[test]
1347 fn decode_ref() -> Result<()> {
1348 let cell = {
1349 let mut builder = CellBuilder::new();
1350 builder.store_u32(0)?;
1351 builder.store_reference(Cell::empty_cell())?;
1352
1353 builder.store_reference(CellBuilder::build_from(123u64)?)?;
1354 builder.store_reference(CellBuilder::build_from((true, Cell::empty_cell()))?)?;
1355
1356 builder.build()?
1357 };
1358
1359 let value = AbiValue::unnamed_tuple([
1360 AbiValue::uint(32, 0u32),
1361 AbiValue::Cell(Cell::empty_cell()),
1362 AbiValue::reference(123u64),
1363 AbiValue::reference((true, Cell::empty_cell())),
1364 ]);
1365
1366 for v in V2_X {
1367 println!("ABIv{v}");
1368 load_simple(v, cell.clone(), value.clone())?;
1369 }
1370
1371 Ok(())
1372 }
1373}