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