Skip to main content

tycho_types/abi/value/
de.rs

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    /// Loads exactly one tuple from the specified slice requiring it to be fully consumed.
21    ///
22    /// Use [`NamedAbiValue::load_tuple_partial`] if you allow an ABI type to be a prefix.
23    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    /// Loads a tuple from the specified slice.
34    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    /// Loads a tuple from the specified slice with explicit decoder params.
43    ///
44    /// NOTE: this method does not check the remaining bits and refs in the root slice.
45    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    /// Loads exactly one ABI value from the specified slice requiring it to be fully consumed.
68    ///
69    /// Use [`NamedAbiValue::load_partial`] if you allow an ABI type to be a prefix.
70    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    /// Loads an ABI value from the specified slice.
77    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    /// Loads an ABI value from the specified slice with explicit decoder params.
86    ///
87    /// NOTE: this method does not check the remaining bits and refs in the root slice.
88    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    /// Checks whether the slice is empty and raises an error if we didn't expect it to be empty.
110    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    /// Loads exactly one unnamed tuple from the specified slice requiring it to be fully consumed.
119    ///
120    /// Use [`AbiValue::load_tuple_partial`] if you allow an ABI type to be a prefix.
121    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    /// Loads an unnamed tuple from the specified slice.
132    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    /// Loads an unnamed tuple from the specified slice with explicit decoder params.
141    ///
142    /// NOTE: this method does not check the remaining bits and refs in the root slice.
143    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    /// Loads exactly one ABI value from the specified slice requiring it to be fully consumed.
160    ///
161    /// Use [`AbiValue::load_partial`] if you allow an ABI type to be a prefix.
162    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    /// Loads an ABI value from the specified slice.
169    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    /// Loads an ABI value from the specified slice with explicit decoder params.
174    ///
175    /// NOTE: this method does not check the remaining bits and refs in the root slice.
176    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    /// Loads a corresponding value from the slice.
247    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    /// Skips all specified headers in slice.
263    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    /// Loads and ignores a corresponding value from the slice.
271    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    /// Loads a corresponding value from the slice.
293    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        // TODO: why `allow_partial` is not used here in a reference impl?
331        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                // Clone sign bit into all high bits
376                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    // TODO: manually use `twos_complement_le` to prevent useless cloning in `from_signed_bytes_le`
402    let bytes = ok!(load_varuint_raw(size, slice));
403    Ok(BigInt::from_signed_bytes_le(&bytes))
404}
405
406/// Loads a varuint as bytes in LE (!) order.
407fn 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    // NOTE: reverse and use `from_bytes_le` to prevent useless cloning in `from_bytes_be`
421    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        // ABI v1
798        {
799            load_simple(
800                AbiVersion::V1_0,
801                "te6ccgEBAgEABQABAAEAAA==", // one ref with empty cell
802                AbiValue::Cell(Cell::empty_cell()),
803            )?;
804
805            // 4 refs with empty cells
806            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            // 3 refs with empty cells + last ref with a cell with 1 ref
816            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==", // one ref with empty cell
831                AbiValue::Cell(Cell::empty_cell()),
832            )?;
833
834            // 4 refs with empty cells
835            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; // mark start
882                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'; // mark start
913                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        //
1103        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        //
1161        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        //
1203        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        //
1210        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        //
1232        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}