Skip to main content

tycho_types/abi/value/
ser.rs

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