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 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 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 pub fn make_builder(&self, version: AbiVersion) -> Result<CellBuilder, Error> {
41 self.value.make_builder(version)
42 }
43
44 pub fn make_cell(&self, version: AbiVersion) -> Result<Cell, Error> {
46 self.value.make_cell(version)
47 }
48}
49
50impl AbiValue {
51 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 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 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 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 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 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 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 for v in VX_X {
917 check_encoding(v, AbiValue::Cell(Cell::empty_cell()));
918 }
919
920 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 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 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; 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 for v in VX_X {
987 println!("ABIv{v}");
988
989 check_encoding(v, AbiValue::Bytes(bytes.clone()));
990
991 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 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 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 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 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 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 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 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 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 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}