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