everscale_types/abi/value/
ser.rs

1use std::collections::BTreeMap;
2use std::num::NonZeroU8;
3
4use num_bigint::{BigUint, Sign};
5
6use crate::abi::{
7    AbiHeader, AbiHeaderType, AbiType, AbiValue, AbiVersion, NamedAbiValue, PlainAbiType,
8    PlainAbiValue,
9};
10use crate::cell::{
11    Cell, CellBuilder, CellContext, CellSlice, CellTreeStats, Size, Store, MAX_BIT_LEN,
12    MAX_REF_COUNT,
13};
14use crate::dict::{self, RawDict};
15use crate::error::Error;
16use crate::models::IntAddr;
17use crate::num::Tokens;
18use crate::prelude::CellFamily;
19
20impl NamedAbiValue {
21    /// Tries to store multiple values into a new builder according to the specified ABI version.
22    pub fn tuple_to_builder(items: &[Self], version: AbiVersion) -> Result<CellBuilder, Error> {
23        let context = &mut Cell::empty_context();
24        let mut serializer = AbiSerializer::new(version);
25        for item in items {
26            serializer.reserve_value(&item.value);
27        }
28        for item in items {
29            ok!(serializer.write_value(&item.value, context));
30        }
31        serializer.finalize(context)
32    }
33
34    /// Builds a new cell from multiple values according to the specified ABI version.
35    pub fn tuple_to_cell(items: &[Self], version: AbiVersion) -> Result<Cell, Error> {
36        Self::tuple_to_builder(items, version).and_then(CellBuilder::build)
37    }
38
39    /// Tries to store this value into a new builder according to the specified ABI version.
40    pub fn make_builder(&self, version: AbiVersion) -> Result<CellBuilder, Error> {
41        self.value.make_builder(version)
42    }
43
44    /// Builds a new cell from this value according to the specified ABI version.
45    pub fn make_cell(&self, version: AbiVersion) -> Result<Cell, Error> {
46        self.value.make_cell(version)
47    }
48}
49
50impl AbiValue {
51    /// Tries to store multiple values into a new builder according to the specified ABI version.
52    pub fn tuple_to_builder(values: &[Self], version: AbiVersion) -> Result<CellBuilder, Error> {
53        let context = &mut Cell::empty_context();
54        let mut serializer = AbiSerializer::new(version);
55        for value in values {
56            serializer.reserve_value(value);
57        }
58        for value in values {
59            ok!(serializer.write_value(value, context));
60        }
61        serializer.finalize(context)
62    }
63
64    /// Builds a new cell from multiple values according to the specified ABI version.
65    pub fn tuple_to_cell(values: &[Self], version: AbiVersion) -> Result<Cell, Error> {
66        Self::tuple_to_builder(values, version).and_then(CellBuilder::build)
67    }
68
69    /// Tries to store this value into a new builder according to the specified ABI version.
70    pub fn make_builder(&self, version: AbiVersion) -> Result<CellBuilder, Error> {
71        let context = &mut Cell::empty_context();
72        let mut serializer = AbiSerializer::new(version);
73        serializer.reserve_value(self);
74        ok!(serializer.write_value(self, context));
75        serializer.finalize(context)
76    }
77
78    /// Builds a new cell from this value according to the specified ABI version.
79    pub fn make_cell(&self, version: AbiVersion) -> Result<Cell, Error> {
80        self.make_builder(version).and_then(CellBuilder::build)
81    }
82
83    fn compute_size_full(&self, version: AbiVersion) -> CellTreeStats {
84        if version.use_max_size() {
85            self.compute_max_size_full()
86        } else {
87            self.compute_exact_size_full()
88        }
89    }
90
91    fn compute_max_size_full(&self) -> CellTreeStats {
92        if let Self::Tuple(items) = self {
93            items
94                .iter()
95                .map(|item| item.value.compute_max_size_full())
96                .sum()
97        } else {
98            self.compute_max_size_short().into()
99        }
100    }
101
102    fn compute_exact_size_full(&self) -> CellTreeStats {
103        if let Self::Tuple(items) = self {
104            items
105                .iter()
106                .map(|item| item.value.compute_exact_size_full())
107                .sum()
108        } else {
109            self.compute_exact_size_short().into()
110        }
111    }
112
113    fn compute_exact_size_short(&self) -> Size {
114        fn compute_varuint_size(n: &NonZeroU8, value: &BigUint) -> Size {
115            let value_bytes: u8 = n.get() - 1;
116            let len_bits = (8 - value_bytes.leading_zeros()) as u16;
117            let value_bits = std::cmp::max(8, 8 * ((value.bits() + 7) / 8) as u16);
118            Size {
119                bits: len_bits + value_bits,
120                refs: 0,
121            }
122        }
123
124        match self {
125            Self::Uint(n, _) | Self::Int(n, _) => Size { bits: *n, refs: 0 },
126            Self::VarUint(n, value) => compute_varuint_size(n, value),
127            Self::VarInt(n, value) => compute_varuint_size(n, value.magnitude()),
128            Self::Bool(_) => Size { bits: 1, refs: 0 },
129            Self::Cell(_)
130            | Self::Bytes(_)
131            | Self::FixedBytes(_)
132            | Self::String(_)
133            | Self::Ref(_) => Size { bits: 0, refs: 1 },
134            Self::Address(value) => Size {
135                bits: value.bit_len(),
136                refs: 0,
137            },
138            Self::Token(tokens) => Size {
139                bits: tokens.bit_len().unwrap_or(Tokens::MAX_BITS),
140                refs: 0,
141            },
142            Self::Array(_, values) => Size {
143                bits: 33,
144                refs: !values.is_empty() as u8,
145            },
146            Self::FixedArray(_, values) => Size {
147                bits: 1,
148                refs: !values.is_empty() as u8,
149            },
150            Self::Map(_, _, values) => Size {
151                bits: 1,
152                refs: !values.is_empty() as u8,
153            },
154            Self::Optional(ty, value) => {
155                if let Some(value) = value {
156                    let ty_size = ty.max_size();
157                    if ty_size.bit_count < MAX_BIT_LEN as u64
158                        && ty_size.cell_count < MAX_REF_COUNT as u64
159                    {
160                        Size { bits: 1, refs: 0 } + value.compute_exact_size_short()
161                    } else {
162                        Size { bits: 1, refs: 1 }
163                    }
164                } else {
165                    Size { bits: 1, refs: 0 }
166                }
167            }
168            Self::Tuple(items) => {
169                let mut size = Size::ZERO;
170                for item in items {
171                    size = size.saturating_add(item.value.compute_exact_size_short());
172                }
173                size
174            }
175        }
176    }
177
178    fn compute_max_size_short(&self) -> Size {
179        match self {
180            Self::Uint(n, _) | Self::Int(n, _) => Size { bits: *n, refs: 0 },
181            Self::VarUint(n, _) | Self::VarInt(n, _) => {
182                let value_bytes: u8 = n.get() - 1;
183                let bits = (8 - value_bytes.leading_zeros()) as u16 + (value_bytes as u16 * 8);
184                Size { bits, refs: 0 }
185            }
186            Self::Bool(_) => Size { bits: 1, refs: 0 },
187            Self::Cell(_)
188            | Self::Bytes(_)
189            | Self::FixedBytes(_)
190            | Self::String(_)
191            | Self::Ref(_) => Size { bits: 0, refs: 1 },
192            Self::Address(_) => Size {
193                bits: IntAddr::BITS_MAX,
194                refs: 0,
195            },
196            Self::Token(_) => Size {
197                bits: Tokens::MAX_BITS,
198                refs: 0,
199            },
200            Self::Array(..) => Size { bits: 33, refs: 1 },
201            Self::FixedArray(..) | Self::Map(..) => Size { bits: 1, refs: 1 },
202            Self::Optional(ty, _) => {
203                let ty_size = ty.max_size();
204                if ty_size.bit_count < MAX_BIT_LEN as u64
205                    && ty_size.cell_count < MAX_REF_COUNT as u64
206                {
207                    Size {
208                        bits: 1 + ty_size.bit_count as u16,
209                        refs: ty_size.cell_count as u8,
210                    }
211                } else {
212                    Size { bits: 1, refs: 1 }
213                }
214            }
215            Self::Tuple(items) => {
216                let mut size = Size::ZERO;
217                for item in items {
218                    size = size.saturating_add(item.value.compute_max_size_short());
219                }
220                size
221            }
222        }
223    }
224}
225
226pub(crate) struct AbiSerializer {
227    version: AbiVersion,
228    current: Size,
229    remaining_total: CellTreeStats,
230    stack: Vec<CellBuilder>,
231}
232
233impl AbiSerializer {
234    pub fn new(version: AbiVersion) -> Self {
235        Self {
236            version,
237            current: Size::ZERO,
238            remaining_total: CellTreeStats::ZERO,
239            stack: Vec::new(),
240        }
241    }
242
243    pub fn add_offset(&mut self, offset: Size) {
244        self.current += offset;
245    }
246
247    pub fn reserve_value(&mut self, value: &AbiValue) {
248        self.remaining_total += value.compute_size_full(self.version);
249    }
250
251    pub fn reserve_headers(&mut self, headers: &[AbiHeaderType], has_public_key: bool) {
252        for header in headers {
253            self.remaining_total.bit_count += match header {
254                AbiHeaderType::Time => 64,
255                AbiHeaderType::Expire => 32,
256                AbiHeaderType::PublicKey => {
257                    1 + if self.version.use_max_size() || has_public_key {
258                        256
259                    } else {
260                        0
261                    }
262                }
263            };
264        }
265    }
266
267    pub fn finalize(mut self, context: &mut dyn CellContext) -> Result<CellBuilder, Error> {
268        debug_assert_eq!(self.remaining_total, CellTreeStats::ZERO);
269
270        let mut result = self.stack.pop().unwrap_or_default();
271        while let Some(builder) = self.stack.pop() {
272            let child = ok!(std::mem::replace(&mut result, builder).build_ext(context));
273            ok!(result.store_reference(child));
274        }
275        Ok(result)
276    }
277
278    pub fn take_finalize(&mut self, context: &mut dyn CellContext) -> Result<CellBuilder, Error> {
279        debug_assert_eq!(self.remaining_total, CellTreeStats::ZERO);
280
281        self.current = Size::ZERO;
282        self.remaining_total = CellTreeStats::ZERO;
283
284        let mut result = self.stack.pop().unwrap_or_default();
285        while let Some(builder) = self.stack.pop() {
286            let child = ok!(std::mem::replace(&mut result, builder).build_ext(context));
287            ok!(result.store_reference(child));
288        }
289        Ok(result)
290    }
291
292    fn begin_child(&self) -> Self {
293        Self::new(self.version)
294    }
295
296    fn require_builder(&mut self, value_size: Size) -> &mut CellBuilder {
297        if self.stack.is_empty() {
298            self.stack.push(CellBuilder::new());
299        }
300
301        self.remaining_total -= value_size;
302
303        let remaining = Size::MAX - self.current;
304
305        let store_inline = if value_size.bits > remaining.bits || value_size.refs > remaining.refs {
306            false
307        } else if value_size.refs > 0 && value_size.refs == remaining.refs {
308            self.version.major != 1
309                && self.remaining_total.cell_count == 0
310                && self.remaining_total.bit_count + value_size.bits as u64 <= remaining.bits as u64
311        } else {
312            true
313        };
314
315        if !store_inline {
316            self.current = Size::ZERO;
317            self.stack.push(CellBuilder::new());
318        }
319
320        self.current += value_size;
321
322        // SAFETY: we guarantee that there will be at least one element.
323        unsafe { self.stack.last_mut().unwrap_unchecked() }
324    }
325
326    pub(crate) fn write_header_value(&mut self, value: &AbiHeader) -> Result<(), Error> {
327        match value {
328            AbiHeader::Time(value) => self
329                .require_builder(Size { bits: 64, refs: 0 })
330                .store_u64(*value),
331            AbiHeader::Expire(value) => self
332                .require_builder(Size { bits: 32, refs: 0 })
333                .store_u32(*value),
334            AbiHeader::PublicKey(value) => {
335                let target = self.require_builder(Size {
336                    bits: 1 + if self.version.use_max_size() || value.is_some() {
337                        256
338                    } else {
339                        0
340                    },
341                    refs: 0,
342                });
343                match value {
344                    None => target.store_bit_zero(),
345                    Some(value) => {
346                        ok!(target.store_bit_one());
347                        target.store_raw(value.as_bytes(), 256)
348                    }
349                }
350            }
351        }
352    }
353
354    pub(crate) fn write_value(
355        &mut self,
356        value: &AbiValue,
357        c: &mut dyn CellContext,
358    ) -> Result<(), Error> {
359        match value {
360            AbiValue::Uint(n, value) => self.write_int(*n, Sign::Plus, value),
361            AbiValue::Int(n, value) => self.write_int(*n, value.sign(), value.magnitude()),
362            AbiValue::VarUint(n, value) => self.write_varint(*n, Sign::Plus, value),
363            AbiValue::VarInt(n, value) => self.write_varint(*n, value.sign(), value.magnitude()),
364            AbiValue::Bool(value) => self.write_bool(*value),
365            AbiValue::Cell(value) => self.write_cell(value),
366            AbiValue::Address(value) => self.write_address(value),
367            AbiValue::Bytes(value) | AbiValue::FixedBytes(value) => self.write_bytes(value, c),
368            AbiValue::String(value) => self.write_bytes(value.as_bytes(), c),
369            AbiValue::Token(value) => self.write_tokens(value),
370            AbiValue::Tuple(items) => self.write_tuple(items, c),
371            AbiValue::Array(ty, values) => self.write_array(ty, values, false, c),
372            AbiValue::FixedArray(ty, values) => self.write_array(ty, values, true, c),
373            AbiValue::Map(k, v, values) => self.write_map(k, v, values, c),
374            AbiValue::Optional(ty, value) => self.write_optional(ty, value.as_deref(), c),
375            AbiValue::Ref(value) => self.write_ref(value, c),
376        }
377    }
378
379    pub(crate) fn write_tuple(
380        &mut self,
381        items: &[NamedAbiValue],
382        context: &mut dyn CellContext,
383    ) -> Result<(), Error> {
384        for item in items {
385            ok!(self.write_value(&item.value, context));
386        }
387        Ok(())
388    }
389
390    fn write_int(&mut self, bits: u16, sign: Sign, value: &BigUint) -> Result<(), Error> {
391        let target = self.require_builder(Size { bits, refs: 0 });
392        write_int(bits, sign, value, target)
393    }
394
395    fn write_varint(&mut self, size: NonZeroU8, sign: Sign, value: &BigUint) -> Result<(), Error> {
396        let is_negative = sign == Sign::Minus;
397        let bytes = to_signed_bytes_be(is_negative, value);
398
399        let max_value_size = size.get() - 1;
400        if bytes.len() > max_value_size as usize {
401            return Err(Error::IntOverflow);
402        }
403
404        let len_bits = (8 - max_value_size.leading_zeros()) as u16;
405        let value_bits = (bytes.len() * 8) as u16;
406
407        let target = self.require_builder(Size {
408            bits: if self.version.use_max_size() {
409                len_bits + (max_value_size as u16) * 8
410            } else {
411                len_bits + value_bits
412            },
413            refs: 0,
414        });
415
416        ok!(target.store_small_uint(bytes.len() as u8, len_bits));
417        target.store_raw(&bytes, value_bits)
418    }
419
420    fn write_bool(&mut self, value: bool) -> Result<(), Error> {
421        let target = self.require_builder(Size { bits: 1, refs: 0 });
422        target.store_bit(value)
423    }
424
425    fn write_cell(&mut self, cell: &Cell) -> Result<(), Error> {
426        let target = self.require_builder(Size { bits: 0, refs: 1 });
427        target.store_reference(cell.clone())
428    }
429
430    fn write_address(&mut self, address: &IntAddr) -> Result<(), Error> {
431        let target = self.require_builder(Size {
432            bits: if self.version.use_max_size() {
433                IntAddr::BITS_MAX
434            } else {
435                address.bit_len()
436            },
437            refs: 0,
438        });
439        address.store_into(target, &mut Cell::empty_context())
440    }
441
442    fn write_tokens(&mut self, tokens: &Tokens) -> Result<(), Error> {
443        let target = self.require_builder(Size {
444            bits: if self.version.use_max_size() {
445                Tokens::MAX_BITS
446            } else {
447                tokens.bit_len().unwrap_or(Tokens::MAX_BITS)
448            },
449            refs: 0,
450        });
451        tokens.store_into(target, &mut Cell::empty_context())
452    }
453
454    fn write_bytes(&mut self, mut data: &[u8], context: &mut dyn CellContext) -> Result<(), Error> {
455        const MAX_BYTES_PER_BUILDER: usize = (MAX_BIT_LEN / 8) as usize;
456        let mut len = data.len();
457
458        let mut bytes_per_builder = if self.version.major > 1 {
459            match len % MAX_BYTES_PER_BUILDER {
460                0 => MAX_BYTES_PER_BUILDER,
461                x => x,
462            }
463        } else {
464            std::cmp::min(MAX_BYTES_PER_BUILDER, len)
465        };
466
467        let mut result = CellBuilder::new();
468        while len > 0 {
469            len -= bytes_per_builder;
470            let (head, tail) = data.split_at(len);
471            data = head;
472
473            if result.size_bits() > 0 {
474                let child = ok!(std::mem::take(&mut result).build_ext(context));
475                ok!(result.store_reference(child));
476            }
477
478            ok!(result.store_raw(tail, (bytes_per_builder * 8) as u16));
479
480            bytes_per_builder = std::cmp::min(MAX_BYTES_PER_BUILDER, len);
481        }
482
483        let target = self.require_builder(Size { bits: 0, refs: 1 });
484        target.store_reference(ok!(result.build()))
485    }
486
487    fn write_array(
488        &mut self,
489        value_ty: &AbiType,
490        values: &[AbiValue],
491        fixed_len: bool,
492        context: &mut dyn CellContext,
493    ) -> Result<(), Error> {
494        let inline_value = fits_into_dict_leaf(32, value_ty.max_bits());
495
496        let mut dict = RawDict::<32>::new();
497        let mut key_builder = CellBuilder::new();
498        let mut serializer = self.begin_child();
499        for (i, value) in values.iter().enumerate() {
500            ok!(key_builder.store_u32(i as u32));
501
502            let value = {
503                serializer.reserve_value(value);
504                ok!(serializer.write_value(value, context));
505                ok!(serializer.take_finalize(context))
506            };
507            let value = if inline_value {
508                InlineOrRef::Inline(value.as_full_slice())
509            } else {
510                InlineOrRef::Ref(ok!(value.build_ext(context)))
511            };
512
513            ok!(dict.set(key_builder.as_data_slice(), value));
514
515            ok!(key_builder.rewind(32));
516        }
517
518        let bits = 1 + if fixed_len { 1 } else { 32 };
519        let refs = if self.version.use_max_size() {
520            1
521        } else {
522            !values.is_empty() as u8
523        };
524
525        let target = self.require_builder(Size { bits, refs });
526
527        if !fixed_len {
528            ok!(target.store_u32(values.len() as u32));
529        }
530        dict.store_into(target, context)
531    }
532
533    fn write_map(
534        &mut self,
535        key_ty: &PlainAbiType,
536        value_ty: &AbiType,
537        value: &BTreeMap<PlainAbiValue, AbiValue>,
538        context: &mut dyn CellContext,
539    ) -> Result<(), Error> {
540        let key_bits = key_ty.key_bits();
541        let inline_value = fits_into_dict_leaf(key_bits, value_ty.max_bits());
542
543        let mut dict = None::<Cell>;
544        let mut key_builder = CellBuilder::new();
545        let mut serializer = self.begin_child();
546        for (key, value) in value {
547            ok!(key.store_into(&mut key_builder, context));
548
549            let value = {
550                serializer.reserve_value(value);
551                ok!(serializer.write_value(value, context));
552                ok!(serializer.take_finalize(context))
553            };
554            let value = if inline_value {
555                InlineOrRef::Inline(value.as_full_slice())
556            } else {
557                InlineOrRef::Ref(ok!(value.build_ext(context)))
558            };
559
560            ok!(dict::dict_insert(
561                &mut dict,
562                &mut key_builder.as_data_slice(),
563                key_bits,
564                &value,
565                dict::SetMode::Set,
566                context,
567            ));
568
569            ok!(key_builder.rewind(key_builder.size_bits()));
570        }
571
572        let target = self.require_builder(Size { bits: 1, refs: 1 });
573        dict.store_into(target, context)
574    }
575
576    fn write_optional(
577        &mut self,
578        ty: &AbiType,
579        value: Option<&AbiValue>,
580        context: &mut dyn CellContext,
581    ) -> Result<(), Error> {
582        let (max_size, inline) = {
583            let ty_size = ty.max_size();
584            if ty_size.bit_count < MAX_BIT_LEN as _ && ty_size.cell_count < MAX_REF_COUNT as _ {
585                let size = Size {
586                    bits: 1 + ty_size.bit_count as u16,
587                    refs: ty_size.cell_count as u8,
588                };
589                (size, true)
590            } else {
591                (Size { bits: 1, refs: 1 }, false)
592            }
593        };
594
595        match value {
596            Some(value) => {
597                let value = {
598                    let mut serializer = self.begin_child();
599                    serializer.reserve_value(value);
600                    ok!(serializer.write_value(value, context));
601                    ok!(serializer.finalize(context))
602                };
603
604                let target = self.require_builder(if self.version.use_max_size() {
605                    max_size
606                } else if inline {
607                    Size {
608                        bits: 1 + value.size_bits(),
609                        refs: value.size_refs(),
610                    }
611                } else {
612                    Size { bits: 1, refs: 1 }
613                });
614
615                ok!(target.store_bit(true));
616                if inline {
617                    target.store_builder(&value)
618                } else {
619                    target.store_reference(ok!(value.build_ext(context)))
620                }
621            }
622            None => {
623                let target = self.require_builder(if self.version.use_max_size() {
624                    max_size
625                } else {
626                    Size { bits: 1, refs: 0 }
627                });
628                target.store_bit(false)
629            }
630        }
631    }
632
633    fn write_ref(&mut self, value: &AbiValue, context: &mut dyn CellContext) -> Result<(), Error> {
634        let cell = {
635            let mut serializer = self.begin_child();
636            serializer.reserve_value(value);
637            ok!(serializer.write_value(value, context));
638            let builder = ok!(serializer.finalize(context));
639            ok!(builder.build_ext(context))
640        };
641        let target = self.require_builder(Size { bits: 0, refs: 1 });
642        target.store_reference(cell)
643    }
644}
645
646fn to_signed_bytes_be(is_negative: bool, value: &BigUint) -> Vec<u8> {
647    #[inline]
648    fn is_zero(value: &u8) -> bool {
649        *value == 0
650    }
651
652    #[inline]
653    pub fn twos_complement_le(digits: &mut [u8]) {
654        let mut carry = true;
655        for digit in digits {
656            *digit = !*digit;
657            if carry {
658                let (d, c) = digit.overflowing_add(1);
659                *digit = d;
660                carry = c;
661            }
662        }
663    }
664
665    fn negative_to_signed_bytes_be(value: &BigUint) -> Vec<u8> {
666        let mut bytes = value.to_bytes_le();
667        let last_byte = bytes.last().cloned().unwrap_or(0);
668        if last_byte > 0x7f && !(last_byte == 0x80 && bytes.iter().rev().skip(1).all(is_zero)) {
669            // msb used by magnitude, extend by 1 byte
670            bytes.push(0);
671        }
672        twos_complement_le(&mut bytes);
673        bytes.reverse();
674        bytes
675    }
676
677    if is_negative {
678        negative_to_signed_bytes_be(value)
679    } else {
680        value.to_bytes_be()
681    }
682}
683
684const fn fits_into_dict_leaf(key_bits: u16, value_bits: usize) -> bool {
685    // NOTE: Label offset is calculated as 2 bits for tag + max ceil(log2(key_bits)).
686    // However this might be incorrect as we have other parts of the label to store.
687    const LABEL_OFFSET: usize = 12;
688
689    LABEL_OFFSET + key_bits as usize + value_bits <= MAX_BIT_LEN as usize
690}
691
692enum InlineOrRef<'a> {
693    Inline(CellSlice<'a>),
694    Ref(Cell),
695}
696
697impl Store for InlineOrRef<'_> {
698    fn store_into(&self, builder: &mut CellBuilder, _: &mut dyn CellContext) -> Result<(), Error> {
699        match self {
700            Self::Inline(slice) => builder.store_slice(slice),
701            Self::Ref(cell) => builder.store_reference(cell.clone()),
702        }
703    }
704}
705
706impl Store for PlainAbiValue {
707    fn store_into(&self, builder: &mut CellBuilder, f: &mut dyn CellContext) -> Result<(), Error> {
708        match self {
709            Self::Uint(bits, value) => write_int(*bits, Sign::Plus, value, builder),
710            Self::Int(bits, value) => write_int(*bits, value.sign(), value.magnitude(), builder),
711            Self::Bool(bit) => builder.store_bit(*bit),
712            Self::Address(address) => address.store_into(builder, f),
713        }
714    }
715}
716
717impl AbiVersion {
718    fn use_max_size(&self) -> bool {
719        self >= &Self::V2_2
720    }
721}
722
723fn write_int(
724    bits: u16,
725    sign: Sign,
726    value: &BigUint,
727    target: &mut CellBuilder,
728) -> Result<(), Error> {
729    if value.bits() > bits as u64 {
730        return Err(Error::IntOverflow);
731    }
732
733    let is_negative = sign == Sign::Minus;
734    let bytes = to_signed_bytes_be(is_negative, value);
735    let value_bits = (bytes.len() * 8) as u16;
736
737    if bytes.is_empty() {
738        target.store_zeros(bits)
739    } else if bits > value_bits {
740        let diff = bits - value_bits;
741        ok!(if is_negative {
742            target.store_ones(diff)
743        } else {
744            target.store_zeros(diff)
745        });
746        target.store_raw(&bytes, value_bits)
747    } else {
748        let bits_offset = value_bits - bits;
749        let bytes_offset = (bits_offset / 8) as usize;
750        let rem = bits_offset % 8;
751
752        let (left, right) = bytes.split_at(bytes_offset + 1);
753        if let Some(left) = left.last() {
754            ok!(target.store_small_uint(*left << rem, 8 - rem));
755        }
756        if !right.is_empty() {
757            ok!(target.store_raw(right, (right.len() * 8) as u16));
758        }
759        Ok(())
760    }
761}
762
763#[cfg(test)]
764mod tests {
765    use std::sync::Arc;
766
767    use bytes::Bytes;
768
769    use crate::dict::Dict;
770    use crate::models::{StdAddr, VarAddr};
771    use crate::num::Uint9;
772    use crate::prelude::{CellFamily, HashBytes};
773
774    use super::*;
775
776    const VX_X: [AbiVersion; 5] = [
777        AbiVersion::V1_0,
778        AbiVersion::V2_0,
779        AbiVersion::V2_1,
780        AbiVersion::V2_2,
781        AbiVersion::V2_3,
782    ];
783    const V2_X: [AbiVersion; 4] = [
784        AbiVersion::V2_0,
785        AbiVersion::V2_1,
786        AbiVersion::V2_2,
787        AbiVersion::V2_3,
788    ];
789
790    fn check_encoding(version: AbiVersion, value: AbiValue) {
791        let cell = value.make_cell(version).unwrap();
792        let parsed =
793            AbiValue::load(&value.get_type(), version, &mut cell.as_slice().unwrap()).unwrap();
794        assert_eq!(value, parsed);
795    }
796
797    #[test]
798    fn int_overflow() {
799        assert_eq!(
800            AbiValue::Uint(16, BigUint::from(u32::MAX)).make_cell(AbiVersion::V2_2),
801            Err(Error::IntOverflow)
802        );
803
804        assert_eq!(
805            AbiValue::Uint(16, BigUint::from(u16::MAX as u32 + 1)).make_cell(AbiVersion::V2_2),
806            Err(Error::IntOverflow)
807        );
808    }
809
810    #[test]
811    fn encode_int() {
812        macro_rules! define_tests {
813            ($v:ident, { $($abi:ident($bits:literal) => [$($expr:expr),*$(,)?]),*$(,)? }) => {$(
814                $(check_encoding($v, AbiValue::$abi($bits, $expr));)*
815            )*};
816        }
817
818        for v in VX_X {
819            println!("ABIv{v}");
820            define_tests!(v, {
821                uint(8) => [0u8, 123u8, u8::MAX],
822                uint(16) => [0u16, 1234u16, u16::MAX],
823                uint(32) => [0u32, 123456u32, u32::MAX],
824                uint(64) => [0u64, 123456789u64, u64::MAX],
825                uint(128) => [0u128, 123456789123123123123u128, u128::MAX],
826
827                int(8) => [0i8, 123i8, i8::MIN, i8::MAX],
828                int(16) => [0i16, 1234i16, i16::MIN, i16::MAX],
829                int(32) => [0i32, 123456i32, i32::MIN, i32::MAX],
830                int(64) => [0i64, 123456789i64, i64::MIN, i64::MAX],
831                int(128) => [0i128, 123456789123123123123i128, i128::MIN, i128::MAX],
832            });
833        }
834    }
835
836    #[test]
837    fn encode_varint() {
838        for v in V2_X {
839            println!("ABIv{v}");
840            check_encoding(v, AbiValue::varuint(4, 0u32));
841            check_encoding(v, AbiValue::varuint(4, u32::MAX >> 8));
842            check_encoding(v, AbiValue::varuint(4, 123321u32));
843
844            check_encoding(v, AbiValue::varuint(8, 0u32));
845            check_encoding(v, AbiValue::varuint(8, u64::MAX >> 8));
846            check_encoding(v, AbiValue::varuint(8, 1233213213123123u64));
847
848            check_encoding(v, AbiValue::varuint(16, 0u8));
849            check_encoding(v, AbiValue::Token(Tokens::ZERO));
850
851            let mut prev_value = 0;
852            for byte in 0..15 {
853                let value = (0xffu128 << (byte * 8)) | prev_value;
854                prev_value = value;
855                check_encoding(v, AbiValue::varuint(16, value));
856                check_encoding(v, AbiValue::Token(Tokens::new(value)));
857            }
858
859            check_encoding(v, AbiValue::varuint(128, 0u8));
860            check_encoding(v, AbiValue::varuint(128, BigUint::from(1u8) << (126 * 8)));
861        }
862    }
863
864    #[test]
865    fn encode_bool() {
866        for v in VX_X {
867            println!("ABIv{v}");
868            check_encoding(v, AbiValue::Bool(false));
869            check_encoding(v, AbiValue::Bool(true));
870        }
871    }
872
873    #[test]
874    fn encode_cell() {
875        // Simple cases
876        for v in VX_X {
877            check_encoding(v, AbiValue::Cell(Cell::empty_cell()));
878        }
879
880        // Complex case
881        let value = AbiValue::unnamed_tuple([
882            AbiValue::Cell(Cell::empty_cell()),
883            AbiValue::Cell(Cell::empty_cell()),
884            AbiValue::Cell(Cell::empty_cell()),
885            AbiValue::Cell(Cell::empty_cell()),
886        ]);
887
888        // ABI v1
889        let cell_v1 = {
890            let mut builder = CellBuilder::new();
891            builder.store_reference(Cell::empty_cell()).unwrap();
892            builder.store_reference(Cell::empty_cell()).unwrap();
893            builder.store_reference(Cell::empty_cell()).unwrap();
894            builder
895                .store_reference(CellBuilder::build_from(Cell::empty_cell()).unwrap())
896                .unwrap();
897            builder.build().unwrap()
898        };
899
900        assert_eq!(value.make_cell(AbiVersion::V1_0).unwrap(), cell_v1);
901
902        // ABI v2.x
903        let cell_v2 = CellBuilder::build_from((
904            Cell::empty_cell(),
905            Cell::empty_cell(),
906            Cell::empty_cell(),
907            Cell::empty_cell(),
908        ))
909        .unwrap();
910
911        for v in V2_X {
912            println!("ABIv{v}");
913            assert_eq!(value.make_cell(v).unwrap(), cell_v2);
914        }
915    }
916
917    #[test]
918    fn encode_address() {
919        for v in VX_X {
920            check_encoding(v, AbiValue::address(StdAddr::new(0, HashBytes([0xff; 32]))));
921            check_encoding(
922                v,
923                AbiValue::address(VarAddr {
924                    address_len: Uint9::new(10 * 8),
925                    anycast: None,
926                    workchain: 123456,
927                    address: vec![0xffu8; 10],
928                }),
929            );
930        }
931    }
932
933    #[test]
934    fn encode_bytes() {
935        let mut bytes = vec![0xffu8; 256];
936        bytes[0] = 0xff; // mark start
937        let bytes = Bytes::from(bytes);
938
939        let empty_bytes_cell = {
940            let mut builder = CellBuilder::new();
941            builder.store_reference(Cell::empty_cell()).unwrap();
942            builder.build().unwrap()
943        };
944
945        // Check simple encoding
946        for v in VX_X {
947            println!("ABIv{v}");
948
949            check_encoding(v, AbiValue::Bytes(bytes.clone()));
950
951            // Bytes must have the same encoding as fixedbytes
952            assert_eq!(
953                AbiValue::Bytes(bytes.clone()).make_cell(v),
954                AbiValue::FixedBytes(bytes.clone()).make_cell(v)
955            );
956
957            assert_eq!(
958                AbiValue::Bytes(Bytes::new()).make_cell(v).unwrap(),
959                empty_bytes_cell
960            );
961        }
962
963        // ABI v1
964        let cell_v1 = CellBuilder::build_from({
965            let mut builder = CellBuilder::new();
966            builder.store_raw(&[0xff; 2], 2 * 8).unwrap();
967
968            builder
969                .store_reference({
970                    let mut builder = CellBuilder::new();
971                    builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
972
973                    builder
974                        .store_reference({
975                            let mut builder = CellBuilder::new();
976                            builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
977                            builder.build().unwrap()
978                        })
979                        .unwrap();
980
981                    builder.build().unwrap()
982                })
983                .unwrap();
984
985            builder.build().unwrap()
986        })
987        .unwrap();
988
989        // ABI v2
990        let cell_v2 = CellBuilder::build_from({
991            let mut builder = CellBuilder::new();
992            builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
993
994            builder
995                .store_reference({
996                    let mut builder = CellBuilder::new();
997                    builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
998
999                    builder
1000                        .store_reference({
1001                            let mut builder = CellBuilder::new();
1002                            builder.store_raw(&[0xff; 2], 2 * 8).unwrap();
1003                            builder.build().unwrap()
1004                        })
1005                        .unwrap();
1006
1007                    builder.build().unwrap()
1008                })
1009                .unwrap();
1010
1011            builder.build().unwrap()
1012        })
1013        .unwrap();
1014
1015        //
1016
1017        assert_eq!(
1018            AbiValue::Bytes(bytes.clone())
1019                .make_cell(AbiVersion::V1_0)
1020                .unwrap(),
1021            cell_v1
1022        );
1023
1024        for v in V2_X {
1025            println!("ABIv{v}");
1026
1027            assert_eq!(
1028                AbiValue::Bytes(bytes.clone()).make_cell(v).unwrap(),
1029                cell_v2
1030            );
1031        }
1032    }
1033
1034    #[test]
1035    fn encode_string() {
1036        for v in VX_X {
1037            println!("ABIv{v}");
1038            check_encoding(v, AbiValue::String(String::new()));
1039            check_encoding(v, AbiValue::String("Hello".to_owned()));
1040            check_encoding(
1041                v,
1042                AbiValue::String(
1043                    std::iter::repeat_with(|| "HELLO".to_owned())
1044                        .take(200)
1045                        .collect::<Vec<String>>()
1046                        .join(" "),
1047                ),
1048            );
1049        }
1050    }
1051
1052    #[test]
1053    fn encode_nested_simple_tuple() {
1054        let value = AbiValue::unnamed_tuple([
1055            AbiValue::uint(32, 0u32),
1056            AbiValue::Cell(Cell::empty_cell()),
1057            AbiValue::Bool(false),
1058            AbiValue::unnamed_tuple([
1059                AbiValue::int(8, -15),
1060                AbiValue::int(16, -9845),
1061                AbiValue::unnamed_tuple([
1062                    AbiValue::int(32, -1),
1063                    AbiValue::int(64, 12345678),
1064                    AbiValue::int(128, -12345678),
1065                ]),
1066            ]),
1067            AbiValue::unnamed_tuple([
1068                AbiValue::uint(8, 255_u8),
1069                AbiValue::uint(16, 0_u16),
1070                AbiValue::unnamed_tuple([
1071                    AbiValue::uint(32, 256_u32),
1072                    AbiValue::uint(64, 123_u64),
1073                    AbiValue::uint(128, 1234567890_u128),
1074                ]),
1075            ]),
1076        ]);
1077
1078        for v in VX_X {
1079            println!("ABIv{v}");
1080
1081            let cell = value.make_cell(v).unwrap();
1082            assert_eq!(
1083                cell.bit_len(),
1084                32 + 1 + 8 + 16 + 32 + 64 + 128 + 8 + 16 + 32 + 64 + 128
1085            );
1086            assert_eq!(cell.reference_count(), 1);
1087
1088            check_encoding(v, value.clone());
1089        }
1090    }
1091
1092    #[test]
1093    fn encode_tuple_four_refs_and_four_uint256() {
1094        let bytes = HashBytes([0xff; 32]);
1095        let bytes_cell = CellBuilder::build_from(bytes).unwrap();
1096
1097        let cell = {
1098            let mut builder = CellBuilder::new();
1099            builder.store_u32(0).unwrap();
1100            builder.store_reference(Cell::empty_cell()).unwrap();
1101
1102            builder.store_reference(bytes_cell.clone()).unwrap();
1103            builder.store_reference(bytes_cell.clone()).unwrap();
1104
1105            let mut second_builder = CellBuilder::new();
1106            second_builder.store_reference(bytes_cell.clone()).unwrap();
1107            second_builder.store_u256(&bytes).unwrap();
1108            second_builder.store_u256(&bytes).unwrap();
1109            second_builder.store_u256(&bytes).unwrap();
1110
1111            let mut third_builder = CellBuilder::new();
1112            third_builder.store_u256(&bytes).unwrap();
1113
1114            second_builder
1115                .store_reference(third_builder.build().unwrap())
1116                .unwrap();
1117            builder
1118                .store_reference(second_builder.build().unwrap())
1119                .unwrap();
1120
1121            builder.build().unwrap()
1122        };
1123
1124        let value = AbiValue::unnamed_tuple([
1125            AbiValue::uint(32, 0_u32),
1126            AbiValue::Cell(Cell::empty_cell()),
1127            AbiValue::Cell(bytes_cell.clone()),
1128            AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1129            AbiValue::Cell(bytes_cell),
1130            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1131            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1132            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1133            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1134        ]);
1135
1136        for v in VX_X {
1137            println!("ABIv{v}");
1138
1139            assert_eq!(value.make_cell(v).unwrap(), cell);
1140            check_encoding(v, value.clone());
1141        }
1142    }
1143
1144    #[test]
1145    fn encode_tuple_four_refs_and_one_uint256() {
1146        let bytes = HashBytes([0x55; 32]);
1147        let bytes_cell = CellBuilder::build_from(bytes).unwrap();
1148
1149        let mut builder = CellBuilder::new();
1150        builder.store_u32(0).unwrap();
1151        builder.store_reference(Cell::empty_cell()).unwrap();
1152
1153        builder.store_reference(bytes_cell.clone()).unwrap();
1154        builder.store_reference(bytes_cell.clone()).unwrap();
1155
1156        let cell_v2 = {
1157            let mut builder = builder.clone();
1158            builder.store_reference(bytes_cell.clone()).unwrap();
1159            builder.store_u256(&bytes).unwrap();
1160            builder.build().unwrap()
1161        };
1162
1163        let cell_v1 = {
1164            let mut child_builder = CellBuilder::new();
1165            child_builder.store_reference(bytes_cell.clone()).unwrap();
1166            child_builder.store_u256(&bytes).unwrap();
1167
1168            builder
1169                .store_reference(child_builder.build().unwrap())
1170                .unwrap();
1171            builder.build().unwrap()
1172        };
1173
1174        let value = AbiValue::unnamed_tuple([
1175            AbiValue::uint(32, 0_u32),
1176            AbiValue::Cell(Cell::empty_cell()),
1177            AbiValue::Cell(bytes_cell.clone()),
1178            AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1179            AbiValue::Cell(bytes_cell.clone()),
1180            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1181        ]);
1182
1183        for v in VX_X {
1184            println!("ABIv{v}");
1185            check_encoding(v, value.clone());
1186        }
1187
1188        assert_eq!(value.make_cell(AbiVersion::V1_0).unwrap(), cell_v1);
1189
1190        for v in V2_X {
1191            println!("ABIv{v}");
1192            assert_eq!(value.make_cell(v).unwrap(), cell_v2);
1193        }
1194    }
1195
1196    #[test]
1197    fn encode_map_simple() {
1198        let bytes = HashBytes([0x55; 32]);
1199        let bytes_cell = CellBuilder::build_from(bytes).unwrap();
1200
1201        let mut bytes_map = Dict::<u8, Cell>::new();
1202        for i in 1..=3 {
1203            bytes_map.set(i, bytes_cell.clone()).unwrap();
1204        }
1205        let bytes_map_cell = CellBuilder::build_from(bytes_map).unwrap();
1206        let bytes_map_value = AbiValue::map([
1207            (1u8, Bytes::copy_from_slice(bytes.as_slice())),
1208            (2, Bytes::copy_from_slice(bytes.as_slice())),
1209            (3, Bytes::copy_from_slice(bytes.as_slice())),
1210        ]);
1211
1212        for v in VX_X {
1213            println!("ABIv{v}");
1214
1215            assert_eq!(bytes_map_value.make_cell(v).unwrap(), bytes_map_cell);
1216            check_encoding(v, bytes_map_value.clone());
1217        }
1218
1219        //
1220        let mut int_map = Dict::<i16, i128>::new();
1221        for i in -1..=1 {
1222            int_map.set(i, i as i128).unwrap();
1223        }
1224        let int_map_cell = CellBuilder::build_from(int_map).unwrap();
1225        let int_map_value = AbiValue::map([(-1i16, -1i128), (0, 0), (1, 1)]);
1226
1227        for v in VX_X {
1228            println!("ABIv{v}");
1229
1230            assert_eq!(int_map_value.make_cell(v).unwrap(), int_map_cell);
1231            check_encoding(v, int_map_value.clone());
1232        }
1233
1234        //
1235        let mut tuples_map = Dict::<u128, (u32, bool)>::new();
1236        for i in 1..=5 {
1237            tuples_map.set(i as u128, (i, i % 2 != 0)).unwrap();
1238        }
1239        let tuples_map_cell = CellBuilder::build_from(tuples_map).unwrap();
1240        let tuples_map_value = AbiValue::map([
1241            (1u128, (1u32, true)),
1242            (2, (2, false)),
1243            (3, (3, true)),
1244            (4, (4, false)),
1245            (5, (5, true)),
1246        ]);
1247
1248        for v in VX_X {
1249            println!("ABIv{v}");
1250
1251            assert_eq!(tuples_map_value.make_cell(v).unwrap(), tuples_map_cell);
1252            check_encoding(v, tuples_map_value.clone());
1253        }
1254
1255        //
1256        let addr1 = StdAddr::new(0, HashBytes([0x11; 32]));
1257        let addr2 = StdAddr::new(0, HashBytes([0x22; 32]));
1258
1259        let mut addr_map = Dict::<StdAddr, u32>::new();
1260        addr_map.set(&addr1, 123).unwrap();
1261        addr_map.set(&addr2, 456).unwrap();
1262        let addr_map_cell = CellBuilder::build_from(addr_map).unwrap();
1263        let addr_map_value = AbiValue::map([(addr1, 123u32), (addr2, 456)]);
1264
1265        for v in VX_X {
1266            println!("ABIv{v}");
1267
1268            assert_eq!(addr_map_value.make_cell(v).unwrap(), addr_map_cell);
1269            check_encoding(v, addr_map_value.clone());
1270        }
1271    }
1272
1273    #[test]
1274    fn encode_map_big_value() {
1275        //
1276        let tuple_value = AbiValue::unnamed_tuple([
1277            AbiValue::uint(256, 1_u32),
1278            AbiValue::uint(256, 2_u32),
1279            AbiValue::uint(256, 3_u32),
1280            AbiValue::uint(256, 4_u32),
1281        ]);
1282
1283        //
1284        let mut map_value = CellBuilder::new();
1285        map_value.store_u128(0).unwrap();
1286        map_value.store_u128(1).unwrap();
1287        map_value.store_u128(0).unwrap();
1288        map_value.store_u128(2).unwrap();
1289        map_value.store_u128(0).unwrap();
1290        map_value.store_u128(3).unwrap();
1291        map_value
1292            .store_reference(CellBuilder::build_from((0u128, 4u128)).unwrap())
1293            .unwrap();
1294        let map_value = map_value.build().unwrap();
1295
1296        let mut key = CellBuilder::new();
1297        key.store_u128(0).unwrap();
1298        key.store_u128(123).unwrap();
1299
1300        let mut map = RawDict::<256>::new();
1301        map.set(key.as_data_slice(), &map_value).unwrap();
1302        let map_cell = CellBuilder::build_from(map).unwrap();
1303        let map = AbiValue::Map(
1304            PlainAbiType::Uint(256),
1305            Arc::new(tuple_value.get_type()),
1306            BTreeMap::from([(
1307                PlainAbiValue::Uint(256, BigUint::from(123u32)),
1308                tuple_value.clone(),
1309            )]),
1310        );
1311
1312        for v in VX_X {
1313            println!("ABIv{v}");
1314            assert_eq!(map.make_cell(v).unwrap(), map_cell);
1315            check_encoding(v, map.clone());
1316        }
1317
1318        //
1319        let mut key = CellBuilder::new();
1320        key.store_u32(0).unwrap();
1321
1322        let mut array = RawDict::<32>::new();
1323        array.set(key.as_data_slice(), &map_value).unwrap();
1324        let array_cell = CellBuilder::build_from((1u32, array)).unwrap();
1325        let array = AbiValue::Array(Arc::new(tuple_value.get_type()), vec![tuple_value]);
1326
1327        for v in V2_X {
1328            println!("ABIv{v}");
1329            assert_eq!(array.make_cell(v).unwrap(), array_cell);
1330            check_encoding(v, array.clone());
1331        }
1332    }
1333
1334    #[test]
1335    fn encode_optional() {
1336        const STR: &str = "Some string";
1337
1338        let string_cell = {
1339            let mut builder = CellBuilder::new();
1340            builder
1341                .store_raw(STR.as_bytes(), (STR.len() * 8) as u16)
1342                .unwrap();
1343            builder.build().unwrap()
1344        };
1345        let string_value = AbiValue::String(STR.to_owned());
1346
1347        let tuple_value = AbiValue::unnamed_tuple([
1348            string_value.clone(),
1349            string_value.clone(),
1350            string_value.clone(),
1351            string_value.clone(),
1352        ]);
1353
1354        let value = AbiValue::unnamed_tuple([
1355            AbiValue::uint(32, 0u32),
1356            AbiValue::Cell(Cell::empty_cell()),
1357            AbiValue::varint(16, -123),
1358            AbiValue::varuint(32, 456u32),
1359            AbiValue::optional(None::<bool>),
1360            AbiValue::Optional(
1361                Arc::new(AbiType::Uint(1022)),
1362                Some(Box::new(AbiValue::uint(1022, 1u32))),
1363            ),
1364            AbiValue::Optional(
1365                Arc::new(AbiType::varuint(128)),
1366                Some(Box::new(AbiValue::varuint(128, 123u32))),
1367            ),
1368            AbiValue::Optional(
1369                Arc::new(tuple_value.get_type()),
1370                Some(Box::new(tuple_value)),
1371            ),
1372        ]);
1373
1374        let cell = {
1375            let mut builder = CellBuilder::new();
1376            builder.store_u32(0).unwrap();
1377            builder.store_reference(Cell::empty_cell()).unwrap();
1378
1379            builder.store_small_uint(1, 4).unwrap();
1380            builder.store_u8(-123i8 as _).unwrap();
1381
1382            builder.store_small_uint(2, 5).unwrap();
1383            builder.store_u16(456).unwrap();
1384
1385            builder.store_bit_zero().unwrap();
1386
1387            builder
1388                .store_reference({
1389                    let mut builder = CellBuilder::new();
1390                    builder.store_bit_one().unwrap();
1391                    builder.store_zeros(127 * 8).unwrap();
1392                    builder.store_small_uint(1, 6).unwrap();
1393
1394                    builder
1395                        .store_reference({
1396                            let mut builder = CellBuilder::new();
1397                            builder.store_bit_one().unwrap();
1398                            builder
1399                                .store_reference({
1400                                    let mut builder = CellBuilder::new();
1401                                    builder.store_small_uint(1, 7).unwrap();
1402                                    builder.store_u8(123).unwrap();
1403                                    builder.build().unwrap()
1404                                })
1405                                .unwrap();
1406
1407                            builder.store_bit_one().unwrap();
1408                            builder
1409                                .store_reference(
1410                                    CellBuilder::build_from((
1411                                        string_cell.clone(),
1412                                        string_cell.clone(),
1413                                        string_cell.clone(),
1414                                        string_cell.clone(),
1415                                    ))
1416                                    .unwrap(),
1417                                )
1418                                .unwrap();
1419
1420                            builder.build().unwrap()
1421                        })
1422                        .unwrap();
1423
1424                    builder.build().unwrap()
1425                })
1426                .unwrap();
1427
1428            builder.build().unwrap()
1429        };
1430
1431        for v in V2_X {
1432            println!("ABIv{v}");
1433
1434            assert_eq!(value.make_cell(v).unwrap(), cell);
1435            check_encoding(v, value.clone());
1436        }
1437    }
1438
1439    #[test]
1440    fn encode_ref() {
1441        let cell = CellBuilder::build_from((
1442            CellBuilder::build_from(123u64).unwrap(),
1443            CellBuilder::build_from((true, Cell::empty_cell())).unwrap(),
1444        ))
1445        .unwrap();
1446
1447        let value = AbiValue::unnamed_tuple([
1448            AbiValue::reference(123u64),
1449            AbiValue::reference((true, Cell::empty_cell())),
1450        ]);
1451
1452        for v in V2_X {
1453            println!("ABIv{v}");
1454            assert_eq!(value.make_cell(v).unwrap(), cell);
1455            check_encoding(v, value.clone());
1456        }
1457    }
1458}