everscale_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 + 7) / 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 + 7) / 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!(
455        bytes.len() == len,
456        AbiError::BytesSizeMismatch {
457            expected: len,
458            len: bytes.len()
459        }
460    );
461    Ok(bytes)
462}
463
464fn load_string(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<String> {
465    let bytes = ok!(load_bytes_raw(version, last, slice));
466    match String::from_utf8(bytes) {
467        Ok(str) => Ok(str),
468        Err(e) => Err(AbiError::InvalidString(e.utf8_error()).into()),
469    }
470}
471
472fn load_array_raw(
473    ty: &AbiType,
474    len: usize,
475    version: AbiVersion,
476    allow_partial: bool,
477    slice: &mut CellSlice,
478) -> Result<Vec<AbiValue>> {
479    ok!(preload_bits(1, slice));
480    let dict = RawDict::<32>::load_from(slice)?;
481
482    let mut result = Vec::with_capacity(len);
483    for value in dict.values().take(len) {
484        let slice = &mut value?;
485        let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
486        ok!(AbiValue::check_remaining(slice, allow_partial));
487        result.push(value);
488    }
489
490    Ok(result)
491}
492
493fn load_array(
494    ty: &AbiType,
495    version: AbiVersion,
496    allow_partial: bool,
497    slice: &mut CellSlice,
498) -> Result<Vec<AbiValue>> {
499    ok!(preload_bits(32, slice));
500    let len = slice.load_u32()?;
501    load_array_raw(ty, len as usize, version, allow_partial, slice)
502}
503
504fn load_fixed_array(
505    ty: &AbiType,
506    len: usize,
507    version: AbiVersion,
508    allow_partial: bool,
509    slice: &mut CellSlice,
510) -> Result<Vec<AbiValue>> {
511    let values = ok!(load_array_raw(ty, len, version, allow_partial, slice));
512    anyhow::ensure!(
513        values.len() == len,
514        AbiError::ArraySizeMismatch {
515            expected: len,
516            len: values.len()
517        }
518    );
519    Ok(values)
520}
521
522fn load_map(
523    key_ty: PlainAbiType,
524    value_ty: &AbiType,
525    version: AbiVersion,
526    allow_partial: bool,
527    slice: &mut CellSlice,
528) -> Result<BTreeMap<PlainAbiValue, AbiValue>> {
529    ok!(preload_bits(1, slice));
530
531    let key_bits = key_ty.key_bits();
532    let dict = Option::<Cell>::load_from(slice)?;
533
534    let mut result = BTreeMap::new();
535    for entry in dict::RawIter::new(&dict, key_bits) {
536        let (key, mut slice) = entry?;
537        let key = PlainAbiValue::load(key_ty, &mut key.as_data_slice())?;
538        let value = ok!(AbiValue::load_ext(
539            value_ty,
540            version,
541            true,
542            allow_partial,
543            &mut slice
544        ));
545        result.insert(key, value);
546    }
547
548    Ok(result)
549}
550
551fn load_optional(
552    ty: &AbiType,
553    version: AbiVersion,
554    last: bool,
555    allow_partial: bool,
556    slice: &mut CellSlice,
557) -> Result<Option<Box<AbiValue>>> {
558    ok!(preload_bits(1, slice));
559
560    if !slice.load_bit()? {
561        return Ok(None);
562    }
563
564    let ty_size = ty.max_size();
565    if ty_size.bit_count < MAX_BIT_LEN as u64 && ty_size.cell_count < MAX_REF_COUNT as u64 {
566        let value = ok!(AbiValue::load_ext(ty, version, last, allow_partial, slice));
567        Ok(Some(Box::new(value)))
568    } else {
569        let cell = ok!(load_cell(version, last, slice));
570        let slice = &mut cell.as_slice()?;
571        let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
572        ok!(AbiValue::check_remaining(slice, allow_partial));
573        Ok(Some(Box::new(value)))
574    }
575}
576
577fn load_ref(
578    ty: &AbiType,
579    version: AbiVersion,
580    last: bool,
581    allow_partial: bool,
582    slice: &mut CellSlice,
583) -> Result<Box<AbiValue>> {
584    let cell = ok!(load_cell(version, last, slice));
585    let slice = &mut cell.as_slice()?;
586    let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
587    ok!(AbiValue::check_remaining(slice, allow_partial));
588    Ok(Box::new(value))
589}
590
591#[cfg(test)]
592mod tests {
593    use std::sync::Arc;
594
595    use crate::boc::Boc;
596    use crate::dict::Dict;
597    use crate::models::{StdAddr, VarAddr};
598    use crate::num::{Uint9, VarUint24, VarUint56};
599    use crate::prelude::{CellBuilder, CellFamily, HashBytes, Store};
600
601    use super::*;
602
603    trait BuildCell {
604        fn build_cell(&self) -> Result<Cell>;
605    }
606
607    impl<T: Store> BuildCell for T {
608        fn build_cell(&self) -> Result<Cell> {
609            CellBuilder::build_from(self).map_err(From::from)
610        }
611    }
612
613    impl BuildCell for &str {
614        fn build_cell(&self) -> Result<Cell> {
615            Boc::decode_base64(self).map_err(From::from)
616        }
617    }
618
619    fn load_simple<T>(version: AbiVersion, boc: T, expected: AbiValue) -> Result<()>
620    where
621        T: BuildCell,
622    {
623        let cell = boc.build_cell()?;
624        let ty = expected.get_type();
625        assert_eq!(
626            AbiValue::load(&ty, version, &mut cell.as_slice()?)?,
627            expected
628        );
629        Ok(())
630    }
631
632    fn load_tuple<T>(version: AbiVersion, boc: T, expected: &[AbiValue]) -> Result<()>
633    where
634        T: BuildCell,
635    {
636        let cell = boc.build_cell()?;
637        let ty = expected.iter().map(AbiValue::get_type).collect::<Vec<_>>();
638        assert_eq!(
639            AbiValue::load_tuple(&ty, version, &mut cell.as_slice()?)?,
640            expected
641        );
642        Ok(())
643    }
644
645    macro_rules! assert_basic_err {
646        ($expr:expr, $err:expr) => {{
647            match $expr {
648                Ok(_) => panic!("Expected basic error: {:?}, got success", $err),
649                Err(e) => {
650                    if let Some(e) = e.downcast_ref::<Error>() {
651                        assert_eq!(e, &($err));
652                    } else {
653                        panic!("Unexpected error: {e:?}");
654                    }
655                }
656            }
657        }};
658    }
659
660    macro_rules! assert_abi_err {
661        ($expr:expr, $err:expr) => {{
662            match $expr {
663                Ok(_) => panic!("Expected ABI error: {:?}, got success", $err),
664                Err(e) => {
665                    if let Some(e) = e.downcast_ref::<AbiError>() {
666                        assert_eq!(e, &($err));
667                    } else {
668                        panic!("Unexpected error: {e:?}");
669                    }
670                }
671            }
672        }};
673    }
674
675    const VX_X: [AbiVersion; 5] = [
676        AbiVersion::V1_0,
677        AbiVersion::V2_0,
678        AbiVersion::V2_1,
679        AbiVersion::V2_2,
680        AbiVersion::V2_3,
681    ];
682    const V2_X: [AbiVersion; 4] = [
683        AbiVersion::V2_0,
684        AbiVersion::V2_1,
685        AbiVersion::V2_2,
686        AbiVersion::V2_3,
687    ];
688
689    #[test]
690    fn failed_decode() -> Result<()> {
691        for v in VX_X {
692            assert_basic_err!(
693                load_simple(v, false, AbiValue::uint(32, 0u32)),
694                Error::CellUnderflow
695            );
696
697            assert_abi_err!(
698                load_simple(v, u64::MAX, AbiValue::uint(32, 0u32)),
699                AbiError::IncompleteDeserialization
700            );
701
702            assert_abi_err!(
703                load_tuple(v, u64::MAX, &[AbiValue::uint(32, u32::MAX)]),
704                AbiError::IncompleteDeserialization
705            );
706        }
707
708        Ok(())
709    }
710
711    #[test]
712    fn decode_int() -> Result<()> {
713        macro_rules! define_tests {
714            ($v:ident, { $($abi:ident($bits:literal) => [$($expr:expr),*$(,)?]),*$(,)? }) => {$(
715                $(load_simple($v, $expr, AbiValue::$abi($bits, $expr))?;)*
716            )*};
717        }
718
719        for v in VX_X {
720            define_tests!(v, {
721                uint(8) => [0u8, 123u8, u8::MAX],
722                uint(16) => [0u16, 1234u16, u16::MAX],
723                uint(32) => [0u32, 123456u32, u32::MAX],
724                uint(64) => [0u64, 123456789u64, u64::MAX],
725                uint(128) => [0u128, 123456789123123123123u128, u128::MAX],
726
727                int(8) => [0i8, 123i8, i8::MIN, i8::MAX],
728                int(16) => [0i16, 1234i16, i16::MIN, i16::MAX],
729                int(32) => [0i32, 123456i32, i32::MIN, i32::MAX],
730                int(64) => [0i64, 123456789i64, i64::MIN, i64::MAX],
731                int(128) => [0i128, 123456789123123123123i128, i128::MIN, i128::MAX],
732            });
733        }
734
735        Ok(())
736    }
737
738    #[test]
739    fn decode_varint() -> Result<()> {
740        for v in VX_X {
741            println!("ABIv{v}");
742            load_simple(v, VarUint24::ZERO, AbiValue::varuint(4, 0u32))?;
743            load_simple(v, VarUint24::MAX, AbiValue::varuint(4, u32::MAX >> 8))?;
744            load_simple(v, VarUint24::new(123321), AbiValue::varuint(4, 123321u32))?;
745
746            load_simple(v, VarUint56::ZERO, AbiValue::varuint(8, 0u32))?;
747            load_simple(v, VarUint56::MAX, AbiValue::varuint(8, u64::MAX >> 8))?;
748            load_simple(
749                v,
750                VarUint56::new(1233213213123123),
751                AbiValue::varuint(8, 1233213213123123u64),
752            )?;
753
754            load_simple(
755                v,
756                "te6ccgEBAQEABgAABzAeG5g=",
757                AbiValue::varuint(16, 123321u32),
758            )?;
759            load_simple(v, "te6ccgEBAQEABgAABzAeG5g=", AbiValue::varint(16, 123321))?;
760
761            load_simple(v, Tokens::ZERO, AbiValue::varuint(16, 0u32))?;
762            load_simple(v, Tokens::ZERO, AbiValue::Token(Tokens::ZERO))?;
763
764            let mut prev_value = 0;
765            for byte in 0..15 {
766                let value = (0xffu128 << (byte * 8)) | prev_value;
767                prev_value = value;
768                load_simple(v, Tokens::new(value), AbiValue::varuint(16, value))?;
769                load_simple(v, Tokens::new(value), AbiValue::Token(Tokens::new(value)))?;
770            }
771        }
772
773        Ok(())
774    }
775
776    #[test]
777    fn decode_bool() -> Result<()> {
778        for v in VX_X {
779            println!("ABIv{v}");
780            load_simple(v, false, AbiValue::Bool(false))?;
781            load_simple(v, true, AbiValue::Bool(true))?;
782        }
783        Ok(())
784    }
785
786    #[test]
787    fn decode_cell() -> Result<()> {
788        // ABI v1
789        {
790            load_simple(
791                AbiVersion::V1_0,
792                "te6ccgEBAgEABQABAAEAAA==", // one ref with empty cell
793                AbiValue::Cell(Cell::empty_cell()),
794            )?;
795
796            // 4 refs with empty cells
797            let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
798            let slice = &mut cell.as_slice()?;
799            slice.skip_first(0, 3)?;
800
801            assert_basic_err!(
802                AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice),
803                Error::CellUnderflow
804            );
805
806            // 3 refs with empty cells + last ref with a cell with 1 ref
807            let cell = Boc::decode_base64("te6ccgEBAwEACwAEAAICAgEBAAIAAA==")?;
808            let slice = &mut cell.as_slice()?;
809            slice.skip_first(0, 3)?;
810
811            assert_eq!(
812                AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice)?,
813                AbiValue::Cell(Cell::empty_cell())
814            );
815        }
816
817        for v in V2_X {
818            println!("ABIv{v}");
819            load_simple(
820                v,
821                "te6ccgEBAgEABQABAAEAAA==", // one ref with empty cell
822                AbiValue::Cell(Cell::empty_cell()),
823            )?;
824
825            // 4 refs with empty cells
826            let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
827            let slice = &mut cell.as_slice()?;
828            slice.skip_first(0, 3)?;
829
830            assert_eq!(
831                AbiValue::load(&AbiType::Cell, v, slice)?,
832                AbiValue::Cell(Cell::empty_cell())
833            );
834        }
835
836        Ok(())
837    }
838
839    #[test]
840    fn decode_address() -> Result<()> {
841        for v in VX_X {
842            println!("ABIv{v}");
843            let addr: StdAddr = StdAddr::from((0i8, [0xffu8; 32]));
844            load_simple(
845                v,
846                addr.clone(),
847                AbiValue::Address(Box::new(IntAddr::Std(addr))),
848            )?;
849
850            let addr: VarAddr = VarAddr {
851                address_len: Uint9::new(10 * 8),
852                anycast: None,
853                workchain: 123456,
854                address: vec![0xffu8; 10],
855            };
856            load_simple(
857                v,
858                addr.clone(),
859                AbiValue::Address(Box::new(IntAddr::Var(addr))),
860            )?;
861        }
862
863        Ok(())
864    }
865
866    #[test]
867    fn decode_bytes() -> Result<()> {
868        for v in VX_X {
869            println!("ABIv{v}");
870            for len in 0..20 {
871                let mut bytes = vec![0xffu8; 1usize << len];
872                bytes[0] = 0x55; // mark start
873                let bytes = Bytes::from(bytes);
874                let serialized = AbiValue::Bytes(bytes.clone()).make_cell(v)?;
875
876                load_simple(v, serialized.clone(), AbiValue::Bytes(bytes.clone()))?;
877                load_simple(v, serialized.clone(), AbiValue::FixedBytes(bytes.clone()))?;
878
879                let original = bytes.len();
880                assert_abi_err!(
881                    load_simple(
882                        v,
883                        serialized.clone(),
884                        AbiValue::FixedBytes(bytes.slice(..original / 2))
885                    ),
886                    AbiError::BytesSizeMismatch {
887                        expected: original / 2,
888                        len: original
889                    }
890                )
891            }
892        }
893
894        Ok(())
895    }
896
897    #[test]
898    fn decode_string() -> Result<()> {
899        for v in VX_X {
900            println!("ABIv{v}");
901            for len in 0..20 {
902                let mut bytes = vec![b'a'; 1usize << len];
903                bytes[0] = b'f'; // mark start
904                let string = String::from_utf8(bytes)?;
905
906                let serialized = AbiValue::String(string.clone()).make_cell(v)?;
907                load_simple(v, serialized.clone(), AbiValue::String(string))?;
908            }
909        }
910
911        Ok(())
912    }
913
914    #[test]
915    fn decode_nested_simple_tuple() -> Result<()> {
916        let cell = {
917            let mut builder = CellBuilder::new();
918            builder.store_u32(0)?;
919            builder.store_reference(Cell::empty_cell())?;
920            builder.store_bit_zero()?;
921            builder.store_u8(-15_i8 as _)?;
922            builder.store_u16(-9845_i16 as _)?;
923            builder.store_u32(-1_i32 as _)?;
924            builder.store_u64(12345678_i64 as _)?;
925            builder.store_u128(-12345678_i128 as _)?;
926            builder.store_u8(255)?;
927            builder.store_u16(0)?;
928            builder.store_u32(256)?;
929            builder.store_u64(123)?;
930            builder.store_u128(1234567890)?;
931            builder.build()?
932        };
933
934        let value = AbiValue::unnamed_tuple([
935            AbiValue::uint(32, 0u32),
936            AbiValue::Cell(Cell::empty_cell()),
937            AbiValue::Bool(false),
938            AbiValue::unnamed_tuple([
939                AbiValue::int(8, -15),
940                AbiValue::int(16, -9845),
941                AbiValue::unnamed_tuple([
942                    AbiValue::int(32, -1),
943                    AbiValue::int(64, 12345678),
944                    AbiValue::int(128, -12345678),
945                ]),
946            ]),
947            AbiValue::unnamed_tuple([
948                AbiValue::uint(8, 255_u8),
949                AbiValue::uint(16, 0_u16),
950                AbiValue::unnamed_tuple([
951                    AbiValue::uint(32, 256_u32),
952                    AbiValue::uint(64, 123_u64),
953                    AbiValue::uint(128, 1234567890_u128),
954                ]),
955            ]),
956        ]);
957
958        for v in VX_X {
959            println!("ABIv{v}");
960            load_simple(v, cell.clone(), value.clone())?;
961        }
962
963        Ok(())
964    }
965
966    #[test]
967    fn decode_tuple_four_refs_and_four_uint256() -> Result<()> {
968        let bytes = HashBytes([0xff; 32]);
969        let bytes_cell = CellBuilder::build_from(bytes)?;
970
971        let cell = {
972            let mut builder = CellBuilder::new();
973            builder.store_u32(0)?;
974            builder.store_reference(Cell::empty_cell())?;
975
976            builder.store_reference(bytes_cell.clone())?;
977            builder.store_reference(bytes_cell.clone())?;
978
979            let mut second_builder = CellBuilder::new();
980            second_builder.store_reference(bytes_cell.clone())?;
981            second_builder.store_u256(&bytes)?;
982            second_builder.store_u256(&bytes)?;
983            second_builder.store_u256(&bytes)?;
984
985            let mut third_builder = CellBuilder::new();
986            third_builder.store_u256(&bytes)?;
987
988            second_builder.store_reference(third_builder.build()?)?;
989            builder.store_reference(second_builder.build()?)?;
990
991            builder.build()?
992        };
993
994        let value = AbiValue::unnamed_tuple([
995            AbiValue::uint(32, 0_u32),
996            AbiValue::Cell(Cell::empty_cell()),
997            AbiValue::Cell(bytes_cell.clone()),
998            AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
999            AbiValue::Cell(bytes_cell),
1000            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1001            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1002            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1003            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1004        ]);
1005
1006        for v in VX_X {
1007            println!("ABIv{v}");
1008            load_simple(v, cell.clone(), value.clone())?;
1009        }
1010
1011        Ok(())
1012    }
1013
1014    #[test]
1015    fn decode_tuple_four_refs_and_one_uint256() -> Result<()> {
1016        let bytes = HashBytes([0x55; 32]);
1017        let bytes_cell = CellBuilder::build_from(bytes)?;
1018
1019        let mut builder = CellBuilder::new();
1020        builder.store_u32(0)?;
1021        builder.store_reference(Cell::empty_cell())?;
1022
1023        builder.store_reference(bytes_cell.clone())?;
1024        builder.store_reference(bytes_cell.clone())?;
1025
1026        let cell_v2 = {
1027            let mut builder = builder.clone();
1028            builder.store_reference(bytes_cell.clone())?;
1029            builder.store_u256(&bytes)?;
1030            builder.build()?
1031        };
1032
1033        let cell_v1 = {
1034            let mut child_builder = CellBuilder::new();
1035            child_builder.store_reference(bytes_cell.clone())?;
1036            child_builder.store_u256(&bytes)?;
1037
1038            builder.store_reference(child_builder.build()?)?;
1039            builder.build()?
1040        };
1041
1042        let value = AbiValue::unnamed_tuple([
1043            AbiValue::uint(32, 0_u32),
1044            AbiValue::Cell(Cell::empty_cell()),
1045            AbiValue::Cell(bytes_cell.clone()),
1046            AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1047            AbiValue::Cell(bytes_cell.clone()),
1048            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1049        ]);
1050
1051        load_simple(AbiVersion::V1_0, cell_v1, value.clone())?;
1052        for v in V2_X {
1053            println!("ABIv{v}");
1054            load_simple(v, cell_v2.clone(), value.clone())?;
1055        }
1056
1057        Ok(())
1058    }
1059
1060    #[test]
1061    fn decode_map_simple() -> Result<()> {
1062        let bytes = HashBytes([0x55; 32]);
1063        let bytes_cell = CellBuilder::build_from(bytes)?;
1064
1065        let mut bytes_map = Dict::<u8, Cell>::new();
1066        for i in 1..=3 {
1067            bytes_map.set(i, bytes_cell.clone())?;
1068        }
1069        let bytes_map_value = AbiValue::map([
1070            (1u8, Bytes::copy_from_slice(bytes.as_slice())),
1071            (2, Bytes::copy_from_slice(bytes.as_slice())),
1072            (3, Bytes::copy_from_slice(bytes.as_slice())),
1073        ]);
1074
1075        let mut int_map = Dict::<i16, i128>::new();
1076        for i in -1..=1 {
1077            int_map.set(i, i as i128)?;
1078        }
1079        let int_map_value = AbiValue::map([(-1i16, -1i128), (0, 0), (1, 1)]);
1080
1081        let mut tuples_map = Dict::<u128, (u32, bool)>::new();
1082        for i in 1..=5 {
1083            tuples_map.set(i as u128, (i, i % 2 != 0))?;
1084        }
1085        let tuples_map_value = AbiValue::map([
1086            (1u128, (1u32, true)),
1087            (2, (2, false)),
1088            (3, (3, true)),
1089            (4, (4, false)),
1090            (5, (5, true)),
1091        ]);
1092
1093        //
1094        let context = &mut Cell::empty_context();
1095        let mut builder = CellBuilder::new();
1096        builder.store_u32(0)?;
1097        builder.store_reference(Cell::empty_cell())?;
1098
1099        bytes_map.store_into(&mut builder, context)?;
1100        int_map.store_into(&mut builder, context)?;
1101
1102        let cell_v2 = {
1103            let mut builder = builder.clone();
1104            tuples_map.store_into(&mut builder, context)?;
1105            builder.store_bit_zero()?;
1106            builder.build()?
1107        };
1108
1109        let cell_v1 = {
1110            let mut child_builder = CellBuilder::new();
1111            tuples_map.store_into(&mut child_builder, context)?;
1112            child_builder.store_bit_zero()?;
1113
1114            builder.store_reference(child_builder.build()?)?;
1115            builder.build()?
1116        };
1117
1118        let value = AbiValue::unnamed_tuple([
1119            AbiValue::uint(32, 0u32),
1120            AbiValue::Cell(Cell::empty_cell()),
1121            bytes_map_value,
1122            int_map_value,
1123            tuples_map_value,
1124            AbiValue::map([] as [(HashBytes, bool); 0]),
1125        ]);
1126
1127        for v in VX_X {
1128            println!("ABIv{v}");
1129            load_simple(v, cell_v1.clone(), value.clone())?;
1130        }
1131
1132        for v in V2_X {
1133            println!("ABIv{v}");
1134            load_simple(v, cell_v2.clone(), value.clone())?;
1135        }
1136
1137        Ok(())
1138    }
1139
1140    #[test]
1141    fn decode_map_address() -> Result<()> {
1142        let addr1 = StdAddr::new(0, HashBytes([0x11; 32]));
1143        let addr2 = StdAddr::new(0, HashBytes([0x22; 32]));
1144
1145        let mut addr_map = Dict::<StdAddr, u32>::new();
1146        addr_map.set(&addr1, 123)?;
1147        addr_map.set(&addr2, 456)?;
1148
1149        let addr_map_value = AbiValue::map([(addr1, 123u32), (addr2, 456)]);
1150
1151        //
1152        let cell = {
1153            let mut builder = CellBuilder::new();
1154            builder.store_u32(0)?;
1155            builder.store_reference(Cell::empty_cell())?;
1156            addr_map.store_into(&mut builder, &mut Cell::empty_context())?;
1157            builder.build()?
1158        };
1159
1160        let value = AbiValue::unnamed_tuple([
1161            AbiValue::uint(32, 0u32),
1162            AbiValue::Cell(Cell::empty_cell()),
1163            addr_map_value,
1164        ]);
1165
1166        for v in VX_X {
1167            println!("ABIv{v}");
1168            load_simple(v, cell.clone(), value.clone())?;
1169        }
1170
1171        Ok(())
1172    }
1173
1174    #[test]
1175    fn decode_map_big_value() -> Result<()> {
1176        let mut map_value = CellBuilder::new();
1177        map_value.store_u128(0)?;
1178        map_value.store_u128(1)?;
1179        map_value.store_u128(0)?;
1180        map_value.store_u128(2)?;
1181        map_value.store_u128(0)?;
1182        map_value.store_u128(3)?;
1183        map_value.store_reference(CellBuilder::build_from((0u128, 4u128))?)?;
1184        let map_value = map_value.build()?;
1185
1186        let mut key = CellBuilder::new();
1187        key.store_u128(0)?;
1188        key.store_u128(123)?;
1189
1190        let mut map = RawDict::<256>::new();
1191        map.set(key.as_data_slice(), &map_value)?;
1192
1193        //
1194        let mut key = CellBuilder::new();
1195        key.store_u32(0)?;
1196
1197        let mut array = RawDict::<32>::new();
1198        array.set(key.as_data_slice(), &map_value)?;
1199
1200        //
1201        let tuple_value = AbiValue::unnamed_tuple([
1202            AbiValue::uint(256, 1_u32),
1203            AbiValue::uint(256, 2_u32),
1204            AbiValue::uint(256, 3_u32),
1205            AbiValue::uint(256, 4_u32),
1206        ]);
1207
1208        let value = AbiValue::unnamed_tuple([
1209            AbiValue::uint(32, 0u32),
1210            AbiValue::Cell(Cell::empty_cell()),
1211            AbiValue::Map(
1212                PlainAbiType::Uint(256),
1213                Arc::new(tuple_value.get_type()),
1214                BTreeMap::from([(
1215                    PlainAbiValue::Uint(256, BigUint::from(123u32)),
1216                    tuple_value.clone(),
1217                )]),
1218            ),
1219            AbiValue::Array(Arc::new(tuple_value.get_type()), vec![tuple_value]),
1220        ]);
1221
1222        //
1223        let cell = {
1224            let context = &mut Cell::empty_context();
1225            let mut builder = CellBuilder::new();
1226            builder.store_u32(0)?;
1227            builder.store_reference(Cell::empty_cell())?;
1228
1229            map.store_into(&mut builder, context)?;
1230
1231            builder.store_u32(1)?;
1232            array.store_into(&mut builder, context)?;
1233
1234            builder.build()?
1235        };
1236
1237        for v in V2_X {
1238            println!("ABIv{v}");
1239            load_simple(v, cell.clone(), value.clone())?;
1240        }
1241
1242        Ok(())
1243    }
1244
1245    #[test]
1246    fn decode_optional() -> Result<()> {
1247        const STR: &str = "Some string";
1248
1249        let string_cell = {
1250            let mut builder = CellBuilder::new();
1251            builder.store_raw(STR.as_bytes(), (STR.len() * 8) as u16)?;
1252            builder.build()?
1253        };
1254        let string_value = AbiValue::String(STR.to_owned());
1255
1256        let tuple_value = AbiValue::unnamed_tuple([
1257            string_value.clone(),
1258            string_value.clone(),
1259            string_value.clone(),
1260            string_value.clone(),
1261        ]);
1262
1263        let value = AbiValue::unnamed_tuple([
1264            AbiValue::uint(32, 0u32),
1265            AbiValue::Cell(Cell::empty_cell()),
1266            AbiValue::varint(16, -123),
1267            AbiValue::varuint(32, 456u32),
1268            AbiValue::optional(None::<bool>),
1269            AbiValue::Optional(
1270                Arc::new(AbiType::Uint(1022)),
1271                Some(Box::new(AbiValue::uint(1022, 1u32))),
1272            ),
1273            AbiValue::Optional(
1274                Arc::new(AbiType::varuint(128)),
1275                Some(Box::new(AbiValue::varuint(128, 123u32))),
1276            ),
1277            AbiValue::Optional(
1278                Arc::new(tuple_value.get_type()),
1279                Some(Box::new(tuple_value)),
1280            ),
1281        ]);
1282
1283        let cell = {
1284            let mut builder = CellBuilder::new();
1285            builder.store_u32(0)?;
1286            builder.store_reference(Cell::empty_cell())?;
1287
1288            builder.store_small_uint(1, 4)?;
1289            builder.store_u8(-123i8 as _)?;
1290
1291            builder.store_small_uint(2, 5)?;
1292            builder.store_u16(456)?;
1293
1294            builder.store_bit_zero()?;
1295
1296            builder.store_reference({
1297                let mut builder = CellBuilder::new();
1298                builder.store_bit_one()?;
1299                builder.store_zeros(127 * 8)?;
1300                builder.store_small_uint(1, 6)?;
1301
1302                builder.store_reference({
1303                    let mut builder = CellBuilder::new();
1304                    builder.store_bit_one()?;
1305                    builder.store_reference({
1306                        let mut builder = CellBuilder::new();
1307                        builder.store_small_uint(1, 7)?;
1308                        builder.store_u8(123)?;
1309                        builder.build()?
1310                    })?;
1311
1312                    builder.store_bit_one()?;
1313                    builder.store_reference(CellBuilder::build_from((
1314                        string_cell.clone(),
1315                        string_cell.clone(),
1316                        string_cell.clone(),
1317                        string_cell.clone(),
1318                    ))?)?;
1319
1320                    builder.build()?
1321                })?;
1322
1323                builder.build()?
1324            })?;
1325
1326            builder.build()?
1327        };
1328
1329        for v in V2_X {
1330            println!("ABIv{v}");
1331            load_simple(v, cell.clone(), value.clone())?;
1332        }
1333
1334        Ok(())
1335    }
1336
1337    #[test]
1338    fn decode_ref() -> Result<()> {
1339        let cell = {
1340            let mut builder = CellBuilder::new();
1341            builder.store_u32(0)?;
1342            builder.store_reference(Cell::empty_cell())?;
1343
1344            builder.store_reference(CellBuilder::build_from(123u64)?)?;
1345            builder.store_reference(CellBuilder::build_from((true, Cell::empty_cell()))?)?;
1346
1347            builder.build()?
1348        };
1349
1350        let value = AbiValue::unnamed_tuple([
1351            AbiValue::uint(32, 0u32),
1352            AbiValue::Cell(Cell::empty_cell()),
1353            AbiValue::reference(123u64),
1354            AbiValue::reference((true, Cell::empty_cell())),
1355        ]);
1356
1357        for v in V2_X {
1358            println!("ABIv{v}");
1359            load_simple(v, cell.clone(), value.clone())?;
1360        }
1361
1362        Ok(())
1363    }
1364}