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        }
795    }
796}
797
798impl AbiVersion {
799    fn use_max_size(&self) -> bool {
800        self >= &Self::V2_2
801    }
802}
803
804#[cfg(test)]
805mod tests {
806    use std::sync::Arc;
807
808    use bytes::Bytes;
809
810    use super::*;
811    use crate::dict::Dict;
812    use crate::models::{StdAddr, VarAddr};
813    use crate::num::Uint9;
814    use crate::prelude::{CellFamily, HashBytes};
815
816    const VX_X: [AbiVersion; 5] = [
817        AbiVersion::V1_0,
818        AbiVersion::V2_0,
819        AbiVersion::V2_1,
820        AbiVersion::V2_2,
821        AbiVersion::V2_3,
822    ];
823    const V2_X: [AbiVersion; 4] = [
824        AbiVersion::V2_0,
825        AbiVersion::V2_1,
826        AbiVersion::V2_2,
827        AbiVersion::V2_3,
828    ];
829
830    fn check_encoding(version: AbiVersion, value: AbiValue) {
831        let cell = value.make_cell(version).unwrap();
832        let parsed =
833            AbiValue::load(&value.get_type(), version, &mut cell.as_slice().unwrap()).unwrap();
834        assert_eq!(value, parsed);
835    }
836
837    #[test]
838    fn int_overflow() {
839        assert_eq!(
840            AbiValue::Uint(16, BigUint::from(u32::MAX)).make_cell(AbiVersion::V2_2),
841            Err(Error::IntOverflow)
842        );
843
844        assert_eq!(
845            AbiValue::Uint(16, BigUint::from(u16::MAX as u32 + 1)).make_cell(AbiVersion::V2_2),
846            Err(Error::IntOverflow)
847        );
848    }
849
850    #[test]
851    fn encode_int() {
852        macro_rules! define_tests {
853            ($v:ident, { $($abi:ident($bits:literal) => [$($expr:expr),*$(,)?]),*$(,)? }) => {$(
854                $(check_encoding($v, AbiValue::$abi($bits, $expr));)*
855            )*};
856        }
857
858        for v in VX_X {
859            println!("ABIv{v}");
860            define_tests!(v, {
861                uint(8) => [0u8, 123u8, u8::MAX],
862                uint(16) => [0u16, 1234u16, u16::MAX],
863                uint(32) => [0u32, 123456u32, u32::MAX],
864                uint(64) => [0u64, 123456789u64, u64::MAX],
865                uint(128) => [0u128, 123456789123123123123u128, u128::MAX],
866
867                int(8) => [0i8, 123i8, i8::MIN, i8::MAX],
868                int(16) => [0i16, 1234i16, i16::MIN, i16::MAX],
869                int(32) => [0i32, 123456i32, i32::MIN, i32::MAX],
870                int(64) => [0i64, 123456789i64, i64::MIN, i64::MAX],
871                int(128) => [0i128, 123456789123123123123i128, i128::MIN, i128::MAX],
872            });
873        }
874    }
875
876    #[test]
877    fn encode_varint() {
878        for v in V2_X {
879            println!("ABIv{v}");
880            check_encoding(v, AbiValue::varuint(4, 0u32));
881            check_encoding(v, AbiValue::varuint(4, u32::MAX >> 8));
882            check_encoding(v, AbiValue::varuint(4, 123321u32));
883
884            check_encoding(v, AbiValue::varuint(8, 0u32));
885            check_encoding(v, AbiValue::varuint(8, u64::MAX >> 8));
886            check_encoding(v, AbiValue::varuint(8, 1233213213123123u64));
887
888            check_encoding(v, AbiValue::varuint(16, 0u8));
889            check_encoding(v, AbiValue::Token(Tokens::ZERO));
890
891            let mut prev_value = 0;
892            for byte in 0..15 {
893                let value = (0xffu128 << (byte * 8)) | prev_value;
894                prev_value = value;
895                check_encoding(v, AbiValue::varuint(16, value));
896                check_encoding(v, AbiValue::Token(Tokens::new(value)));
897            }
898
899            check_encoding(v, AbiValue::varuint(128, 0u8));
900            check_encoding(v, AbiValue::varuint(128, BigUint::from(1u8) << (126 * 8)));
901        }
902    }
903
904    #[test]
905    fn encode_bool() {
906        for v in VX_X {
907            println!("ABIv{v}");
908            check_encoding(v, AbiValue::Bool(false));
909            check_encoding(v, AbiValue::Bool(true));
910        }
911    }
912
913    #[test]
914    fn encode_cell() {
915        // Simple cases
916        for v in VX_X {
917            check_encoding(v, AbiValue::Cell(Cell::empty_cell()));
918        }
919
920        // Complex case
921        let value = AbiValue::unnamed_tuple([
922            AbiValue::Cell(Cell::empty_cell()),
923            AbiValue::Cell(Cell::empty_cell()),
924            AbiValue::Cell(Cell::empty_cell()),
925            AbiValue::Cell(Cell::empty_cell()),
926        ]);
927
928        // ABI v1
929        let cell_v1 = {
930            let mut builder = CellBuilder::new();
931            builder.store_reference(Cell::empty_cell()).unwrap();
932            builder.store_reference(Cell::empty_cell()).unwrap();
933            builder.store_reference(Cell::empty_cell()).unwrap();
934            builder
935                .store_reference(CellBuilder::build_from(Cell::empty_cell()).unwrap())
936                .unwrap();
937            builder.build().unwrap()
938        };
939
940        assert_eq!(value.make_cell(AbiVersion::V1_0).unwrap(), cell_v1);
941
942        // ABI v2.x
943        let cell_v2 = CellBuilder::build_from((
944            Cell::empty_cell(),
945            Cell::empty_cell(),
946            Cell::empty_cell(),
947            Cell::empty_cell(),
948        ))
949        .unwrap();
950
951        for v in V2_X {
952            println!("ABIv{v}");
953            assert_eq!(value.make_cell(v).unwrap(), cell_v2);
954        }
955    }
956
957    #[test]
958    fn encode_address() {
959        for v in VX_X {
960            check_encoding(v, AbiValue::address(StdAddr::new(0, HashBytes([0xff; 32]))));
961            check_encoding(
962                v,
963                AbiValue::address(VarAddr {
964                    address_len: Uint9::new(10 * 8),
965                    anycast: None,
966                    workchain: 123456,
967                    address: vec![0xffu8; 10],
968                }),
969            );
970        }
971    }
972
973    #[test]
974    fn encode_bytes() {
975        let mut bytes = vec![0xffu8; 256];
976        bytes[0] = 0xff; // mark start
977        let bytes = Bytes::from(bytes);
978
979        let empty_bytes_cell = {
980            let mut builder = CellBuilder::new();
981            builder.store_reference(Cell::empty_cell()).unwrap();
982            builder.build().unwrap()
983        };
984
985        // Check simple encoding
986        for v in VX_X {
987            println!("ABIv{v}");
988
989            check_encoding(v, AbiValue::Bytes(bytes.clone()));
990
991            // Bytes must have the same encoding as fixedbytes
992            assert_eq!(
993                AbiValue::Bytes(bytes.clone()).make_cell(v),
994                AbiValue::FixedBytes(bytes.clone()).make_cell(v)
995            );
996
997            assert_eq!(
998                AbiValue::Bytes(Bytes::new()).make_cell(v).unwrap(),
999                empty_bytes_cell
1000            );
1001        }
1002
1003        // ABI v1
1004        let cell_v1 = CellBuilder::build_from({
1005            let mut builder = CellBuilder::new();
1006            builder.store_raw(&[0xff; 2], 2 * 8).unwrap();
1007
1008            builder
1009                .store_reference({
1010                    let mut builder = CellBuilder::new();
1011                    builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
1012
1013                    builder
1014                        .store_reference({
1015                            let mut builder = CellBuilder::new();
1016                            builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
1017                            builder.build().unwrap()
1018                        })
1019                        .unwrap();
1020
1021                    builder.build().unwrap()
1022                })
1023                .unwrap();
1024
1025            builder.build().unwrap()
1026        })
1027        .unwrap();
1028
1029        // ABI v2
1030        let cell_v2 = CellBuilder::build_from({
1031            let mut builder = CellBuilder::new();
1032            builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
1033
1034            builder
1035                .store_reference({
1036                    let mut builder = CellBuilder::new();
1037                    builder.store_raw(&[0xff; 127], 127 * 8).unwrap();
1038
1039                    builder
1040                        .store_reference({
1041                            let mut builder = CellBuilder::new();
1042                            builder.store_raw(&[0xff; 2], 2 * 8).unwrap();
1043                            builder.build().unwrap()
1044                        })
1045                        .unwrap();
1046
1047                    builder.build().unwrap()
1048                })
1049                .unwrap();
1050
1051            builder.build().unwrap()
1052        })
1053        .unwrap();
1054
1055        //
1056
1057        assert_eq!(
1058            AbiValue::Bytes(bytes.clone())
1059                .make_cell(AbiVersion::V1_0)
1060                .unwrap(),
1061            cell_v1
1062        );
1063
1064        for v in V2_X {
1065            println!("ABIv{v}");
1066
1067            assert_eq!(
1068                AbiValue::Bytes(bytes.clone()).make_cell(v).unwrap(),
1069                cell_v2
1070            );
1071        }
1072    }
1073
1074    #[test]
1075    fn encode_string() {
1076        for v in VX_X {
1077            println!("ABIv{v}");
1078            check_encoding(v, AbiValue::String(String::new()));
1079            check_encoding(v, AbiValue::String("Hello".to_owned()));
1080            check_encoding(
1081                v,
1082                AbiValue::String(
1083                    std::iter::repeat_with(|| "HELLO".to_owned())
1084                        .take(200)
1085                        .collect::<Vec<String>>()
1086                        .join(" "),
1087                ),
1088            );
1089        }
1090    }
1091
1092    #[test]
1093    fn encode_nested_simple_tuple() {
1094        let value = AbiValue::unnamed_tuple([
1095            AbiValue::uint(32, 0u32),
1096            AbiValue::Cell(Cell::empty_cell()),
1097            AbiValue::Bool(false),
1098            AbiValue::unnamed_tuple([
1099                AbiValue::int(8, -15),
1100                AbiValue::int(16, -9845),
1101                AbiValue::unnamed_tuple([
1102                    AbiValue::int(32, -1),
1103                    AbiValue::int(64, 12345678),
1104                    AbiValue::int(128, -12345678),
1105                ]),
1106            ]),
1107            AbiValue::unnamed_tuple([
1108                AbiValue::uint(8, 255_u8),
1109                AbiValue::uint(16, 0_u16),
1110                AbiValue::unnamed_tuple([
1111                    AbiValue::uint(32, 256_u32),
1112                    AbiValue::uint(64, 123_u64),
1113                    AbiValue::uint(128, 1234567890_u128),
1114                ]),
1115            ]),
1116        ]);
1117
1118        for v in VX_X {
1119            println!("ABIv{v}");
1120
1121            let cell = value.make_cell(v).unwrap();
1122            assert_eq!(
1123                cell.bit_len(),
1124                32 + 1 + 8 + 16 + 32 + 64 + 128 + 8 + 16 + 32 + 64 + 128
1125            );
1126            assert_eq!(cell.reference_count(), 1);
1127
1128            check_encoding(v, value.clone());
1129        }
1130    }
1131
1132    #[test]
1133    fn encode_tuple_four_refs_and_four_uint256() {
1134        let bytes = HashBytes([0xff; 32]);
1135        let bytes_cell = CellBuilder::build_from(bytes).unwrap();
1136
1137        let cell = {
1138            let mut builder = CellBuilder::new();
1139            builder.store_u32(0).unwrap();
1140            builder.store_reference(Cell::empty_cell()).unwrap();
1141
1142            builder.store_reference(bytes_cell.clone()).unwrap();
1143            builder.store_reference(bytes_cell.clone()).unwrap();
1144
1145            let mut second_builder = CellBuilder::new();
1146            second_builder.store_reference(bytes_cell.clone()).unwrap();
1147            second_builder.store_u256(&bytes).unwrap();
1148            second_builder.store_u256(&bytes).unwrap();
1149            second_builder.store_u256(&bytes).unwrap();
1150
1151            let mut third_builder = CellBuilder::new();
1152            third_builder.store_u256(&bytes).unwrap();
1153
1154            second_builder
1155                .store_reference(third_builder.build().unwrap())
1156                .unwrap();
1157            builder
1158                .store_reference(second_builder.build().unwrap())
1159                .unwrap();
1160
1161            builder.build().unwrap()
1162        };
1163
1164        let value = AbiValue::unnamed_tuple([
1165            AbiValue::uint(32, 0_u32),
1166            AbiValue::Cell(Cell::empty_cell()),
1167            AbiValue::Cell(bytes_cell.clone()),
1168            AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1169            AbiValue::Cell(bytes_cell),
1170            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1171            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1172            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1173            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1174        ]);
1175
1176        for v in VX_X {
1177            println!("ABIv{v}");
1178
1179            assert_eq!(value.make_cell(v).unwrap(), cell);
1180            check_encoding(v, value.clone());
1181        }
1182    }
1183
1184    #[test]
1185    fn encode_tuple_four_refs_and_one_uint256() {
1186        let bytes = HashBytes([0x55; 32]);
1187        let bytes_cell = CellBuilder::build_from(bytes).unwrap();
1188
1189        let mut builder = CellBuilder::new();
1190        builder.store_u32(0).unwrap();
1191        builder.store_reference(Cell::empty_cell()).unwrap();
1192
1193        builder.store_reference(bytes_cell.clone()).unwrap();
1194        builder.store_reference(bytes_cell.clone()).unwrap();
1195
1196        let cell_v2 = {
1197            let mut builder = builder.clone();
1198            builder.store_reference(bytes_cell.clone()).unwrap();
1199            builder.store_u256(&bytes).unwrap();
1200            builder.build().unwrap()
1201        };
1202
1203        let cell_v1 = {
1204            let mut child_builder = CellBuilder::new();
1205            child_builder.store_reference(bytes_cell.clone()).unwrap();
1206            child_builder.store_u256(&bytes).unwrap();
1207
1208            builder
1209                .store_reference(child_builder.build().unwrap())
1210                .unwrap();
1211            builder.build().unwrap()
1212        };
1213
1214        let value = AbiValue::unnamed_tuple([
1215            AbiValue::uint(32, 0_u32),
1216            AbiValue::Cell(Cell::empty_cell()),
1217            AbiValue::Cell(bytes_cell.clone()),
1218            AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1219            AbiValue::Cell(bytes_cell.clone()),
1220            AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1221        ]);
1222
1223        for v in VX_X {
1224            println!("ABIv{v}");
1225            check_encoding(v, value.clone());
1226        }
1227
1228        assert_eq!(value.make_cell(AbiVersion::V1_0).unwrap(), cell_v1);
1229
1230        for v in V2_X {
1231            println!("ABIv{v}");
1232            assert_eq!(value.make_cell(v).unwrap(), cell_v2);
1233        }
1234    }
1235
1236    #[test]
1237    fn encode_map_simple() {
1238        let bytes = HashBytes([0x55; 32]);
1239        let bytes_cell = CellBuilder::build_from(bytes).unwrap();
1240
1241        let mut bytes_map = Dict::<u8, Cell>::new();
1242        for i in 1..=3 {
1243            bytes_map.set(i, bytes_cell.clone()).unwrap();
1244        }
1245        let bytes_map_cell = CellBuilder::build_from(bytes_map).unwrap();
1246        let bytes_map_value = AbiValue::map([
1247            (1u8, Bytes::copy_from_slice(bytes.as_slice())),
1248            (2, Bytes::copy_from_slice(bytes.as_slice())),
1249            (3, Bytes::copy_from_slice(bytes.as_slice())),
1250        ]);
1251
1252        for v in VX_X {
1253            println!("ABIv{v}");
1254
1255            assert_eq!(bytes_map_value.make_cell(v).unwrap(), bytes_map_cell);
1256            check_encoding(v, bytes_map_value.clone());
1257        }
1258
1259        //
1260        let mut int_map = Dict::<i16, i128>::new();
1261        for i in -1..=1 {
1262            int_map.set(i, i as i128).unwrap();
1263        }
1264        let int_map_cell = CellBuilder::build_from(int_map).unwrap();
1265        let int_map_value = AbiValue::map([(-1i16, -1i128), (0, 0), (1, 1)]);
1266
1267        for v in VX_X {
1268            println!("ABIv{v}");
1269
1270            assert_eq!(int_map_value.make_cell(v).unwrap(), int_map_cell);
1271            check_encoding(v, int_map_value.clone());
1272        }
1273
1274        //
1275        let mut tuples_map = Dict::<u128, (u32, bool)>::new();
1276        for i in 1..=5 {
1277            tuples_map.set(i as u128, (i, i % 2 != 0)).unwrap();
1278        }
1279        let tuples_map_cell = CellBuilder::build_from(tuples_map).unwrap();
1280        let tuples_map_value = AbiValue::map([
1281            (1u128, (1u32, true)),
1282            (2, (2, false)),
1283            (3, (3, true)),
1284            (4, (4, false)),
1285            (5, (5, true)),
1286        ]);
1287
1288        for v in VX_X {
1289            println!("ABIv{v}");
1290
1291            assert_eq!(tuples_map_value.make_cell(v).unwrap(), tuples_map_cell);
1292            check_encoding(v, tuples_map_value.clone());
1293        }
1294
1295        //
1296        let addr1 = StdAddr::new(0, HashBytes([0x11; 32]));
1297        let addr2 = StdAddr::new(0, HashBytes([0x22; 32]));
1298
1299        let mut addr_map = Dict::<StdAddr, u32>::new();
1300        addr_map.set(&addr1, 123).unwrap();
1301        addr_map.set(&addr2, 456).unwrap();
1302        let addr_map_cell = CellBuilder::build_from(addr_map).unwrap();
1303        let addr_map_value = AbiValue::map([(addr1, 123u32), (addr2, 456)]);
1304
1305        for v in VX_X {
1306            println!("ABIv{v}");
1307
1308            assert_eq!(addr_map_value.make_cell(v).unwrap(), addr_map_cell);
1309            check_encoding(v, addr_map_value.clone());
1310        }
1311    }
1312
1313    #[test]
1314    fn encode_map_big_value() {
1315        //
1316        let tuple_value = AbiValue::unnamed_tuple([
1317            AbiValue::uint(256, 1_u32),
1318            AbiValue::uint(256, 2_u32),
1319            AbiValue::uint(256, 3_u32),
1320            AbiValue::uint(256, 4_u32),
1321        ]);
1322
1323        //
1324        let mut map_value = CellBuilder::new();
1325        map_value.store_u128(0).unwrap();
1326        map_value.store_u128(1).unwrap();
1327        map_value.store_u128(0).unwrap();
1328        map_value.store_u128(2).unwrap();
1329        map_value.store_u128(0).unwrap();
1330        map_value.store_u128(3).unwrap();
1331        map_value
1332            .store_reference(CellBuilder::build_from((0u128, 4u128)).unwrap())
1333            .unwrap();
1334        let map_value = map_value.build().unwrap();
1335
1336        let mut key = CellBuilder::new();
1337        key.store_u128(0).unwrap();
1338        key.store_u128(123).unwrap();
1339
1340        let mut map = RawDict::<256>::new();
1341        map.set(key.as_data_slice(), &map_value).unwrap();
1342        let map_cell = CellBuilder::build_from(map).unwrap();
1343        let map = AbiValue::Map(
1344            PlainAbiType::Uint(256),
1345            Arc::new(tuple_value.get_type()),
1346            BTreeMap::from([(
1347                PlainAbiValue::Uint(256, BigUint::from(123u32)),
1348                tuple_value.clone(),
1349            )]),
1350        );
1351
1352        for v in VX_X {
1353            println!("ABIv{v}");
1354            assert_eq!(map.make_cell(v).unwrap(), map_cell);
1355            check_encoding(v, map.clone());
1356        }
1357
1358        //
1359        let mut key = CellBuilder::new();
1360        key.store_u32(0).unwrap();
1361
1362        let mut array = RawDict::<32>::new();
1363        array.set(key.as_data_slice(), &map_value).unwrap();
1364        let array_cell = CellBuilder::build_from((1u32, array)).unwrap();
1365        let array = AbiValue::Array(Arc::new(tuple_value.get_type()), vec![tuple_value]);
1366
1367        for v in V2_X {
1368            println!("ABIv{v}");
1369            assert_eq!(array.make_cell(v).unwrap(), array_cell);
1370            check_encoding(v, array.clone());
1371        }
1372    }
1373
1374    #[test]
1375    fn encode_optional() {
1376        const STR: &str = "Some string";
1377
1378        let string_cell = {
1379            let mut builder = CellBuilder::new();
1380            builder
1381                .store_raw(STR.as_bytes(), (STR.len() * 8) as u16)
1382                .unwrap();
1383            builder.build().unwrap()
1384        };
1385        let string_value = AbiValue::String(STR.to_owned());
1386
1387        let tuple_value = AbiValue::unnamed_tuple([
1388            string_value.clone(),
1389            string_value.clone(),
1390            string_value.clone(),
1391            string_value.clone(),
1392        ]);
1393
1394        let value = AbiValue::unnamed_tuple([
1395            AbiValue::uint(32, 0u32),
1396            AbiValue::Cell(Cell::empty_cell()),
1397            AbiValue::varint(16, -123),
1398            AbiValue::varuint(32, 456u32),
1399            AbiValue::optional(None::<bool>),
1400            AbiValue::Optional(
1401                Arc::new(AbiType::Uint(1022)),
1402                Some(Box::new(AbiValue::uint(1022, 1u32))),
1403            ),
1404            AbiValue::Optional(
1405                Arc::new(AbiType::varuint(128)),
1406                Some(Box::new(AbiValue::varuint(128, 123u32))),
1407            ),
1408            AbiValue::Optional(
1409                Arc::new(tuple_value.get_type()),
1410                Some(Box::new(tuple_value)),
1411            ),
1412        ]);
1413
1414        let cell = {
1415            let mut builder = CellBuilder::new();
1416            builder.store_u32(0).unwrap();
1417            builder.store_reference(Cell::empty_cell()).unwrap();
1418
1419            builder.store_small_uint(1, 4).unwrap();
1420            builder.store_u8(-123i8 as _).unwrap();
1421
1422            builder.store_small_uint(2, 5).unwrap();
1423            builder.store_u16(456).unwrap();
1424
1425            builder.store_bit_zero().unwrap();
1426
1427            builder
1428                .store_reference({
1429                    let mut builder = CellBuilder::new();
1430                    builder.store_bit_one().unwrap();
1431                    builder.store_zeros(127 * 8).unwrap();
1432                    builder.store_small_uint(1, 6).unwrap();
1433
1434                    builder
1435                        .store_reference({
1436                            let mut builder = CellBuilder::new();
1437                            builder.store_bit_one().unwrap();
1438                            builder
1439                                .store_reference({
1440                                    let mut builder = CellBuilder::new();
1441                                    builder.store_small_uint(1, 7).unwrap();
1442                                    builder.store_u8(123).unwrap();
1443                                    builder.build().unwrap()
1444                                })
1445                                .unwrap();
1446
1447                            builder.store_bit_one().unwrap();
1448                            builder
1449                                .store_reference(
1450                                    CellBuilder::build_from((
1451                                        string_cell.clone(),
1452                                        string_cell.clone(),
1453                                        string_cell.clone(),
1454                                        string_cell.clone(),
1455                                    ))
1456                                    .unwrap(),
1457                                )
1458                                .unwrap();
1459
1460                            builder.build().unwrap()
1461                        })
1462                        .unwrap();
1463
1464                    builder.build().unwrap()
1465                })
1466                .unwrap();
1467
1468            builder.build().unwrap()
1469        };
1470
1471        for v in V2_X {
1472            println!("ABIv{v}");
1473
1474            assert_eq!(value.make_cell(v).unwrap(), cell);
1475            check_encoding(v, value.clone());
1476        }
1477    }
1478
1479    #[test]
1480    fn encode_ref() {
1481        let cell = CellBuilder::build_from((
1482            CellBuilder::build_from(123u64).unwrap(),
1483            CellBuilder::build_from((true, Cell::empty_cell())).unwrap(),
1484        ))
1485        .unwrap();
1486
1487        let value = AbiValue::unnamed_tuple([
1488            AbiValue::reference(123u64),
1489            AbiValue::reference((true, Cell::empty_cell())),
1490        ]);
1491
1492        for v in V2_X {
1493            println!("ABIv{v}");
1494            assert_eq!(value.make_cell(v).unwrap(), cell);
1495            check_encoding(v, value.clone());
1496        }
1497    }
1498}