1use std::collections::BTreeMap;
2use std::num::NonZeroU8;
3
4use anyhow::Result;
5use bytes::Bytes;
6use num_bigint::{BigInt, BigUint};
7
8use crate::abi::error::AbiError;
9use crate::abi::{
10 AbiHeader, AbiHeaderType, AbiType, AbiValue, AbiVersion, NamedAbiType, NamedAbiValue,
11 PlainAbiType, PlainAbiValue,
12};
13use crate::cell::{Cell, CellSlice, Load, MAX_BIT_LEN, MAX_REF_COUNT};
14use crate::dict::{self, RawDict};
15use crate::error::Error;
16use crate::models::IntAddr;
17use crate::num::Tokens;
18
19impl NamedAbiValue {
20 pub fn load_tuple(
24 items: &[NamedAbiType],
25 version: AbiVersion,
26 slice: &mut CellSlice,
27 ) -> Result<Vec<Self>> {
28 let result = ok!(Self::load_tuple_ext(items, version, true, false, slice));
29 ok!(AbiValue::check_remaining(slice, false));
30 Ok(result)
31 }
32
33 pub fn load_tuple_partial(
35 items: &[NamedAbiType],
36 version: AbiVersion,
37 slice: &mut CellSlice,
38 ) -> Result<Vec<Self>> {
39 Self::load_tuple_ext(items, version, true, true, slice)
40 }
41
42 pub fn load_tuple_ext(
46 items: &[NamedAbiType],
47 version: AbiVersion,
48 last: bool,
49 allow_partial: bool,
50 slice: &mut CellSlice,
51 ) -> Result<Vec<Self>> {
52 let mut result = Vec::with_capacity(items.len());
53 let items_len = items.len();
54 for (i, item) in items.iter().enumerate() {
55 let last = last && i + 1 == items_len;
56 result.push(ok!(Self::load_ext(
57 item,
58 version,
59 last,
60 allow_partial,
61 slice
62 )));
63 }
64 Ok(result)
65 }
66
67 pub fn load(ty: &NamedAbiType, version: AbiVersion, slice: &mut CellSlice) -> Result<Self> {
71 let res = ok!(Self::load_ext(ty, version, true, false, slice));
72 ok!(AbiValue::check_remaining(slice, false));
73 Ok(res)
74 }
75
76 pub fn load_partial(
78 ty: &NamedAbiType,
79 version: AbiVersion,
80 slice: &mut CellSlice,
81 ) -> Result<Self> {
82 Self::load_ext(ty, version, true, true, slice)
83 }
84
85 pub fn load_ext(
89 ty: &NamedAbiType,
90 version: AbiVersion,
91 last: bool,
92 allow_partial: bool,
93 slice: &mut CellSlice,
94 ) -> Result<Self> {
95 Ok(Self {
96 value: ok!(AbiValue::load_ext(
97 &ty.ty,
98 version,
99 last,
100 allow_partial,
101 slice
102 )),
103 name: ty.name.clone(),
104 })
105 }
106}
107
108impl AbiValue {
109 pub fn check_remaining(slice: &mut CellSlice, allow_partial: bool) -> Result<()> {
111 anyhow::ensure!(
112 allow_partial || slice.is_data_empty() && slice.is_refs_empty(),
113 AbiError::IncompleteDeserialization
114 );
115 Ok(())
116 }
117
118 pub fn load_tuple(
122 types: &[AbiType],
123 version: AbiVersion,
124 slice: &mut CellSlice,
125 ) -> Result<Vec<Self>> {
126 let res = ok!(Self::load_tuple_ext(types, version, true, false, slice));
127 ok!(Self::check_remaining(slice, false));
128 Ok(res)
129 }
130
131 pub fn load_tuple_partial(
133 types: &[AbiType],
134 version: AbiVersion,
135 slice: &mut CellSlice,
136 ) -> Result<Vec<Self>> {
137 Self::load_tuple_ext(types, version, true, true, slice)
138 }
139
140 pub fn load_tuple_ext(
144 types: &[AbiType],
145 version: AbiVersion,
146 last: bool,
147 allow_partial: bool,
148 slice: &mut CellSlice,
149 ) -> Result<Vec<Self>> {
150 let mut result = Vec::with_capacity(types.len());
151 let types_len = types.len();
152 for (i, ty) in types.iter().enumerate() {
153 let last = last && i + 1 == types_len;
154 result.push(ok!(Self::load_ext(ty, version, last, allow_partial, slice)));
155 }
156 Ok(result)
157 }
158
159 pub fn load(ty: &AbiType, version: AbiVersion, slice: &mut CellSlice) -> Result<Self> {
163 let res = ok!(Self::load_ext(ty, version, true, false, slice));
164 ok!(Self::check_remaining(slice, false));
165 Ok(res)
166 }
167
168 pub fn load_partial(ty: &AbiType, version: AbiVersion, slice: &mut CellSlice) -> Result<Self> {
170 Self::load_ext(ty, version, true, true, slice)
171 }
172
173 pub fn load_ext(
177 ty: &AbiType,
178 version: AbiVersion,
179 last: bool,
180 allow_partial: bool,
181 slice: &mut CellSlice,
182 ) -> Result<Self> {
183 match ty {
184 AbiType::Uint(bits) => load_uint(*bits, slice).map(|value| Self::Uint(*bits, value)),
185 AbiType::Int(bits) => load_int(*bits, slice).map(|value| Self::Int(*bits, value)),
186 AbiType::VarUint(size) => {
187 load_varuint(*size, slice).map(|value| Self::VarUint(*size, value))
188 }
189 AbiType::VarInt(size) => {
190 load_varint(*size, slice).map(|value| Self::VarInt(*size, value))
191 }
192 AbiType::Bool => {
193 ok!(preload_bits(1, slice));
194 Ok(Self::Bool(slice.load_bit()?))
195 }
196 AbiType::Cell => load_cell(version, last, slice).map(Self::Cell),
197 AbiType::Address => {
198 ok!(preload_bits(1, slice));
199 Ok(Self::Address(IntAddr::load_from(slice).map(Box::new)?))
200 }
201 AbiType::Bytes => load_bytes(version, last, slice).map(Self::Bytes),
202 AbiType::FixedBytes(len) => {
203 load_fixed_bytes(*len, version, last, slice).map(Self::FixedBytes)
204 }
205 AbiType::String => load_string(version, last, slice).map(Self::String),
206 AbiType::Token => {
207 ok!(preload_bits(1, slice));
208 Ok(Self::Token(Tokens::load_from(slice)?))
209 }
210 AbiType::Tuple(items) => {
211 let values = ok!(NamedAbiValue::load_tuple_ext(
212 items,
213 version,
214 last,
215 allow_partial,
216 slice
217 ));
218 Ok(Self::Tuple(values))
219 }
220 AbiType::Array(ty) => load_array(ty, version, allow_partial, slice)
221 .map(|values| Self::Array(ty.clone(), values)),
222 AbiType::FixedArray(ty, len) => {
223 load_fixed_array(ty, *len, version, allow_partial, slice)
224 .map(|values| Self::FixedArray(ty.clone(), values))
225 }
226 AbiType::Map(key_ty, value_ty) => {
227 load_map(*key_ty, value_ty, version, allow_partial, slice)
228 .map(|value| Self::Map(*key_ty, value_ty.clone(), value))
229 }
230 AbiType::Optional(ty) => load_optional(ty, version, last, allow_partial, slice)
231 .map(|value| Self::Optional(ty.clone(), value)),
232 AbiType::Ref(ty) => load_ref(ty, version, last, allow_partial, slice).map(Self::Ref),
233 }
234 }
235}
236
237impl PlainAbiValue {
238 pub fn load(ty: PlainAbiType, slice: &mut CellSlice) -> Result<Self, Error> {
240 match ty {
241 PlainAbiType::Uint(bits) => {
242 load_uint_plain(bits, slice).map(|value| Self::Uint(bits, value))
243 }
244 PlainAbiType::Int(bits) => {
245 load_int_plain(bits, slice).map(|value| Self::Int(bits, value))
246 }
247 PlainAbiType::Bool => slice.load_bit().map(Self::Bool),
248 PlainAbiType::Address => IntAddr::load_from(slice).map(Box::new).map(Self::Address),
249 }
250 }
251}
252
253impl AbiHeader {
254 pub fn skip_all(headers: &[AbiHeaderType], slice: &mut CellSlice) -> Result<()> {
256 for header in headers {
257 ok!(Self::skip(*header, slice))
258 }
259 Ok(())
260 }
261
262 pub fn skip(ty: AbiHeaderType, slice: &mut CellSlice) -> Result<()> {
264 match ty {
265 AbiHeaderType::Time => {
266 ok!(preload_bits(64, slice));
267 slice.skip_first(64, 0)?;
268 }
269 AbiHeaderType::Expire => {
270 ok!(preload_bits(32, slice));
271 slice.skip_first(32, 0)?;
272 }
273 AbiHeaderType::PublicKey => {
274 ok!(preload_bits(1, slice));
275 if slice.load_bit()? {
276 ok!(preload_bits(256, slice));
277 slice.skip_first(256, 0)?;
278 }
279 }
280 }
281 Ok(())
282 }
283
284 pub fn load(ty: AbiHeaderType, slice: &mut CellSlice) -> Result<Self> {
286 Ok(match ty {
287 AbiHeaderType::Time => {
288 ok!(preload_bits(64, slice));
289 Self::Time(slice.load_u64()?)
290 }
291 AbiHeaderType::Expire => {
292 ok!(preload_bits(32, slice));
293 Self::Expire(slice.load_u32()?)
294 }
295 AbiHeaderType::PublicKey => {
296 ok!(preload_bits(1, slice));
297 Self::PublicKey(if slice.load_bit()? {
298 ok!(preload_bits(256, slice));
299 let Ok(pubkey) =
300 ed25519_dalek::VerifyingKey::from_bytes(slice.load_u256()?.as_array())
301 else {
302 anyhow::bail!(Error::InvalidPublicKey);
303 };
304 Some(Box::new(pubkey))
305 } else {
306 None
307 })
308 }
309 })
310 }
311}
312
313fn preload_bits(bits: u16, slice: &mut CellSlice) -> Result<()> {
314 if bits == 0 {
315 return Ok(());
316 }
317
318 let remaining_bits = slice.size_bits();
319 if remaining_bits == 0 {
320 let first_ref = slice.load_reference_as_slice()?;
321
322 anyhow::ensure!(slice.is_refs_empty(), AbiError::IncompleteDeserialization);
324
325 *slice = first_ref;
326 } else if remaining_bits < bits {
327 anyhow::bail!(Error::CellUnderflow);
328 }
329
330 Ok(())
331}
332
333fn load_uint(bits: u16, slice: &mut CellSlice) -> Result<BigUint> {
334 ok!(preload_bits(bits, slice));
335 load_uint_plain(bits, slice).map_err(From::from)
336}
337
338fn load_int(bits: u16, slice: &mut CellSlice) -> Result<BigInt> {
339 ok!(preload_bits(bits, slice));
340 load_int_plain(bits, slice).map_err(From::from)
341}
342
343fn load_uint_plain(bits: u16, slice: &mut CellSlice) -> Result<BigUint, Error> {
344 match bits {
345 0 => Ok(BigUint::default()),
346 1..=64 => slice.load_uint(bits).map(BigUint::from),
347 _ => {
348 let rem = bits % 8;
349 let mut buffer = vec![0u8; bits.div_ceil(8) as usize];
350 slice.load_raw(&mut buffer, bits)?;
351
352 buffer.reverse();
353 let mut int = BigUint::from_bytes_le(&buffer);
354 if rem != 0 {
355 int >>= 8 - rem;
356 }
357 Ok(int)
358 }
359 }
360}
361
362fn load_int_plain(bits: u16, slice: &mut CellSlice) -> Result<BigInt, Error> {
363 match bits {
364 0 => Ok(BigInt::default()),
365 1..=64 => slice.load_uint(bits).map(|mut int| {
366 if bits < 64 {
367 int |= ((int >> (bits - 1)) * u64::MAX) << (bits - 1);
369 }
370 BigInt::from(int as i64)
371 }),
372 _ => {
373 let rem = bits % 8;
374 let mut buffer = vec![0u8; bits.div_ceil(8) as usize];
375 slice.load_raw(&mut buffer, bits)?;
376
377 buffer.reverse();
378 let mut int = BigInt::from_signed_bytes_le(&buffer);
379 if rem != 0 {
380 int >>= 8 - rem;
381 }
382 Ok(int)
383 }
384 }
385}
386
387fn load_varuint(size: NonZeroU8, slice: &mut CellSlice) -> Result<BigUint> {
388 let bytes = ok!(load_varuint_raw(size, slice));
389 Ok(BigUint::from_bytes_le(&bytes))
390}
391
392fn load_varint(size: NonZeroU8, slice: &mut CellSlice) -> Result<BigInt> {
393 let bytes = ok!(load_varuint_raw(size, slice));
395 Ok(BigInt::from_signed_bytes_le(&bytes))
396}
397
398fn load_varuint_raw(size: NonZeroU8, slice: &mut CellSlice) -> Result<Vec<u8>> {
400 let value_size = size.get() - 1;
401
402 let len_bits = (8 - value_size.leading_zeros()) as u16;
403 ok!(preload_bits(len_bits, slice));
404
405 let value_bytes = slice.load_small_uint(len_bits)? as usize;
406 let value_bits = (value_bytes * 8) as u16;
407 ok!(preload_bits(value_bits, slice));
408
409 let mut bytes = vec![0u8; value_bytes];
410 slice.load_raw(&mut bytes, value_bits)?;
411
412 bytes.reverse();
414 Ok(bytes)
415}
416
417fn load_cell(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<Cell> {
418 if slice.size_refs() == 1
419 && (version.major == 1 && slice.cell().reference_count() as usize == MAX_REF_COUNT
420 || version.major > 1 && !last && slice.size_bits() == 0)
421 {
422 *slice = slice.load_reference_as_slice()?;
423 }
424 slice.load_reference_cloned().map_err(From::from)
425}
426
427fn load_bytes_raw(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<Vec<u8>> {
428 let cell = ok!(load_cell(version, last, slice));
429 let mut cell = cell.as_ref();
430
431 let mut bytes = Vec::new();
432 loop {
433 anyhow::ensure!(cell.bit_len() % 8 == 0, AbiError::ExpectedCellWithBytes);
434 bytes.extend_from_slice(cell.data());
435
436 match cell.reference(0) {
437 Some(child) => cell = child,
438 None => break Ok(bytes),
439 };
440 }
441}
442
443fn load_bytes(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<Bytes> {
444 load_bytes_raw(version, last, slice).map(Bytes::from)
445}
446
447fn load_fixed_bytes(
448 len: usize,
449 version: AbiVersion,
450 last: bool,
451 slice: &mut CellSlice,
452) -> Result<Bytes> {
453 let bytes = ok!(load_bytes(version, last, slice));
454 anyhow::ensure!(bytes.len() == len, AbiError::BytesSizeMismatch {
455 expected: len,
456 len: bytes.len()
457 });
458 Ok(bytes)
459}
460
461fn load_string(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<String> {
462 let bytes = ok!(load_bytes_raw(version, last, slice));
463 match String::from_utf8(bytes) {
464 Ok(str) => Ok(str),
465 Err(e) => Err(AbiError::InvalidString(e.utf8_error()).into()),
466 }
467}
468
469fn load_array_raw(
470 ty: &AbiType,
471 len: usize,
472 version: AbiVersion,
473 allow_partial: bool,
474 slice: &mut CellSlice,
475) -> Result<Vec<AbiValue>> {
476 ok!(preload_bits(1, slice));
477 let dict = RawDict::<32>::load_from(slice)?;
478
479 let mut result = Vec::with_capacity(len);
480 for value in dict.values().take(len) {
481 let slice = &mut value?;
482 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
483 ok!(AbiValue::check_remaining(slice, allow_partial));
484 result.push(value);
485 }
486
487 Ok(result)
488}
489
490fn load_array(
491 ty: &AbiType,
492 version: AbiVersion,
493 allow_partial: bool,
494 slice: &mut CellSlice,
495) -> Result<Vec<AbiValue>> {
496 ok!(preload_bits(32, slice));
497 let len = slice.load_u32()?;
498 load_array_raw(ty, len as usize, version, allow_partial, slice)
499}
500
501fn load_fixed_array(
502 ty: &AbiType,
503 len: usize,
504 version: AbiVersion,
505 allow_partial: bool,
506 slice: &mut CellSlice,
507) -> Result<Vec<AbiValue>> {
508 let values = ok!(load_array_raw(ty, len, version, allow_partial, slice));
509 anyhow::ensure!(values.len() == len, AbiError::ArraySizeMismatch {
510 expected: len,
511 len: values.len()
512 });
513 Ok(values)
514}
515
516fn load_map(
517 key_ty: PlainAbiType,
518 value_ty: &AbiType,
519 version: AbiVersion,
520 allow_partial: bool,
521 slice: &mut CellSlice,
522) -> Result<BTreeMap<PlainAbiValue, AbiValue>> {
523 ok!(preload_bits(1, slice));
524
525 let key_bits = key_ty.key_bits();
526 let dict = Option::<Cell>::load_from(slice)?;
527
528 let mut result = BTreeMap::new();
529 for entry in dict::RawIter::new(&dict, key_bits) {
530 let (key, mut slice) = entry?;
531 let key = PlainAbiValue::load(key_ty, &mut key.as_data_slice())?;
532 let value = ok!(AbiValue::load_ext(
533 value_ty,
534 version,
535 true,
536 allow_partial,
537 &mut slice
538 ));
539 result.insert(key, value);
540 }
541
542 Ok(result)
543}
544
545fn load_optional(
546 ty: &AbiType,
547 version: AbiVersion,
548 last: bool,
549 allow_partial: bool,
550 slice: &mut CellSlice,
551) -> Result<Option<Box<AbiValue>>> {
552 ok!(preload_bits(1, slice));
553
554 if !slice.load_bit()? {
555 return Ok(None);
556 }
557
558 let ty_size = ty.max_size();
559 if ty_size.bit_count < MAX_BIT_LEN as u64 && ty_size.cell_count < MAX_REF_COUNT as u64 {
560 let value = ok!(AbiValue::load_ext(ty, version, last, allow_partial, slice));
561 Ok(Some(Box::new(value)))
562 } else {
563 let cell = ok!(load_cell(version, last, slice));
564 let slice = &mut cell.as_slice()?;
565 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
566 ok!(AbiValue::check_remaining(slice, allow_partial));
567 Ok(Some(Box::new(value)))
568 }
569}
570
571fn load_ref(
572 ty: &AbiType,
573 version: AbiVersion,
574 last: bool,
575 allow_partial: bool,
576 slice: &mut CellSlice,
577) -> Result<Box<AbiValue>> {
578 let cell = ok!(load_cell(version, last, slice));
579 let slice = &mut cell.as_slice()?;
580 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
581 ok!(AbiValue::check_remaining(slice, allow_partial));
582 Ok(Box::new(value))
583}
584
585#[cfg(test)]
586mod tests {
587 use std::sync::Arc;
588
589 use super::*;
590 use crate::boc::Boc;
591 use crate::dict::Dict;
592 use crate::models::{StdAddr, VarAddr};
593 use crate::num::{Uint9, VarUint24, VarUint56};
594 use crate::prelude::{CellBuilder, CellFamily, HashBytes, Store};
595
596 trait BuildCell {
597 fn build_cell(&self) -> Result<Cell>;
598 }
599
600 impl<T: Store> BuildCell for T {
601 fn build_cell(&self) -> Result<Cell> {
602 CellBuilder::build_from(self).map_err(From::from)
603 }
604 }
605
606 impl BuildCell for &str {
607 fn build_cell(&self) -> Result<Cell> {
608 Boc::decode_base64(self).map_err(From::from)
609 }
610 }
611
612 fn load_simple<T>(version: AbiVersion, boc: T, expected: AbiValue) -> Result<()>
613 where
614 T: BuildCell,
615 {
616 let cell = boc.build_cell()?;
617 let ty = expected.get_type();
618 assert_eq!(
619 AbiValue::load(&ty, version, &mut cell.as_slice()?)?,
620 expected
621 );
622 Ok(())
623 }
624
625 fn load_tuple<T>(version: AbiVersion, boc: T, expected: &[AbiValue]) -> Result<()>
626 where
627 T: BuildCell,
628 {
629 let cell = boc.build_cell()?;
630 let ty = expected.iter().map(AbiValue::get_type).collect::<Vec<_>>();
631 assert_eq!(
632 AbiValue::load_tuple(&ty, version, &mut cell.as_slice()?)?,
633 expected
634 );
635 Ok(())
636 }
637
638 macro_rules! assert_basic_err {
639 ($expr:expr, $err:expr) => {{
640 match $expr {
641 Ok(_) => panic!("Expected basic error: {:?}, got success", $err),
642 Err(e) => {
643 if let Some(e) = e.downcast_ref::<Error>() {
644 assert_eq!(e, &($err));
645 } else {
646 panic!("Unexpected error: {e:?}");
647 }
648 }
649 }
650 }};
651 }
652
653 macro_rules! assert_abi_err {
654 ($expr:expr, $err:expr) => {{
655 match $expr {
656 Ok(_) => panic!("Expected ABI error: {:?}, got success", $err),
657 Err(e) => {
658 if let Some(e) = e.downcast_ref::<AbiError>() {
659 assert_eq!(e, &($err));
660 } else {
661 panic!("Unexpected error: {e:?}");
662 }
663 }
664 }
665 }};
666 }
667
668 const VX_X: [AbiVersion; 5] = [
669 AbiVersion::V1_0,
670 AbiVersion::V2_0,
671 AbiVersion::V2_1,
672 AbiVersion::V2_2,
673 AbiVersion::V2_3,
674 ];
675 const V2_X: [AbiVersion; 4] = [
676 AbiVersion::V2_0,
677 AbiVersion::V2_1,
678 AbiVersion::V2_2,
679 AbiVersion::V2_3,
680 ];
681
682 #[test]
683 fn failed_decode() -> Result<()> {
684 for v in VX_X {
685 assert_basic_err!(
686 load_simple(v, false, AbiValue::uint(32, 0u32)),
687 Error::CellUnderflow
688 );
689
690 assert_abi_err!(
691 load_simple(v, u64::MAX, AbiValue::uint(32, 0u32)),
692 AbiError::IncompleteDeserialization
693 );
694
695 assert_abi_err!(
696 load_tuple(v, u64::MAX, &[AbiValue::uint(32, u32::MAX)]),
697 AbiError::IncompleteDeserialization
698 );
699 }
700
701 Ok(())
702 }
703
704 #[test]
705 fn decode_int() -> Result<()> {
706 macro_rules! define_tests {
707 ($v:ident, { $($abi:ident($bits:literal) => [$($expr:expr),*$(,)?]),*$(,)? }) => {$(
708 $(load_simple($v, $expr, AbiValue::$abi($bits, $expr))?;)*
709 )*};
710 }
711
712 for v in VX_X {
713 define_tests!(v, {
714 uint(8) => [0u8, 123u8, u8::MAX],
715 uint(16) => [0u16, 1234u16, u16::MAX],
716 uint(32) => [0u32, 123456u32, u32::MAX],
717 uint(64) => [0u64, 123456789u64, u64::MAX],
718 uint(128) => [0u128, 123456789123123123123u128, u128::MAX],
719
720 int(8) => [0i8, 123i8, i8::MIN, i8::MAX],
721 int(16) => [0i16, 1234i16, i16::MIN, i16::MAX],
722 int(32) => [0i32, 123456i32, i32::MIN, i32::MAX],
723 int(64) => [0i64, 123456789i64, i64::MIN, i64::MAX],
724 int(128) => [0i128, 123456789123123123123i128, i128::MIN, i128::MAX],
725 });
726 }
727
728 Ok(())
729 }
730
731 #[test]
732 fn decode_varint() -> Result<()> {
733 for v in VX_X {
734 println!("ABIv{v}");
735 load_simple(v, VarUint24::ZERO, AbiValue::varuint(4, 0u32))?;
736 load_simple(v, VarUint24::MAX, AbiValue::varuint(4, u32::MAX >> 8))?;
737 load_simple(v, VarUint24::new(123321), AbiValue::varuint(4, 123321u32))?;
738
739 load_simple(v, VarUint56::ZERO, AbiValue::varuint(8, 0u32))?;
740 load_simple(v, VarUint56::MAX, AbiValue::varuint(8, u64::MAX >> 8))?;
741 load_simple(
742 v,
743 VarUint56::new(1233213213123123),
744 AbiValue::varuint(8, 1233213213123123u64),
745 )?;
746
747 load_simple(
748 v,
749 "te6ccgEBAQEABgAABzAeG5g=",
750 AbiValue::varuint(16, 123321u32),
751 )?;
752 load_simple(v, "te6ccgEBAQEABgAABzAeG5g=", AbiValue::varint(16, 123321))?;
753
754 load_simple(v, Tokens::ZERO, AbiValue::varuint(16, 0u32))?;
755 load_simple(v, Tokens::ZERO, AbiValue::Token(Tokens::ZERO))?;
756
757 let mut prev_value = 0;
758 for byte in 0..15 {
759 let value = (0xffu128 << (byte * 8)) | prev_value;
760 prev_value = value;
761 load_simple(v, Tokens::new(value), AbiValue::varuint(16, value))?;
762 load_simple(v, Tokens::new(value), AbiValue::Token(Tokens::new(value)))?;
763 }
764 }
765
766 Ok(())
767 }
768
769 #[test]
770 fn decode_bool() -> Result<()> {
771 for v in VX_X {
772 println!("ABIv{v}");
773 load_simple(v, false, AbiValue::Bool(false))?;
774 load_simple(v, true, AbiValue::Bool(true))?;
775 }
776 Ok(())
777 }
778
779 #[test]
780 fn decode_cell() -> Result<()> {
781 {
783 load_simple(
784 AbiVersion::V1_0,
785 "te6ccgEBAgEABQABAAEAAA==", AbiValue::Cell(Cell::empty_cell()),
787 )?;
788
789 let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
791 let slice = &mut cell.as_slice()?;
792 slice.skip_first(0, 3)?;
793
794 assert_basic_err!(
795 AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice),
796 Error::CellUnderflow
797 );
798
799 let cell = Boc::decode_base64("te6ccgEBAwEACwAEAAICAgEBAAIAAA==")?;
801 let slice = &mut cell.as_slice()?;
802 slice.skip_first(0, 3)?;
803
804 assert_eq!(
805 AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice)?,
806 AbiValue::Cell(Cell::empty_cell())
807 );
808 }
809
810 for v in V2_X {
811 println!("ABIv{v}");
812 load_simple(
813 v,
814 "te6ccgEBAgEABQABAAEAAA==", AbiValue::Cell(Cell::empty_cell()),
816 )?;
817
818 let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
820 let slice = &mut cell.as_slice()?;
821 slice.skip_first(0, 3)?;
822
823 assert_eq!(
824 AbiValue::load(&AbiType::Cell, v, slice)?,
825 AbiValue::Cell(Cell::empty_cell())
826 );
827 }
828
829 Ok(())
830 }
831
832 #[test]
833 fn decode_address() -> Result<()> {
834 for v in VX_X {
835 println!("ABIv{v}");
836 let addr: StdAddr = StdAddr::from((0i8, [0xffu8; 32]));
837 load_simple(
838 v,
839 addr.clone(),
840 AbiValue::Address(Box::new(IntAddr::Std(addr))),
841 )?;
842
843 let addr: VarAddr = VarAddr {
844 address_len: Uint9::new(10 * 8),
845 anycast: None,
846 workchain: 123456,
847 address: vec![0xffu8; 10],
848 };
849 load_simple(
850 v,
851 addr.clone(),
852 AbiValue::Address(Box::new(IntAddr::Var(addr))),
853 )?;
854 }
855
856 Ok(())
857 }
858
859 #[test]
860 fn decode_bytes() -> Result<()> {
861 for v in VX_X {
862 println!("ABIv{v}");
863 for len in 0..20 {
864 let mut bytes = vec![0xffu8; 1usize << len];
865 bytes[0] = 0x55; let bytes = Bytes::from(bytes);
867 let serialized = AbiValue::Bytes(bytes.clone()).make_cell(v)?;
868
869 load_simple(v, serialized.clone(), AbiValue::Bytes(bytes.clone()))?;
870 load_simple(v, serialized.clone(), AbiValue::FixedBytes(bytes.clone()))?;
871
872 let original = bytes.len();
873 assert_abi_err!(
874 load_simple(
875 v,
876 serialized.clone(),
877 AbiValue::FixedBytes(bytes.slice(..original / 2))
878 ),
879 AbiError::BytesSizeMismatch {
880 expected: original / 2,
881 len: original
882 }
883 )
884 }
885 }
886
887 Ok(())
888 }
889
890 #[test]
891 fn decode_string() -> Result<()> {
892 for v in VX_X {
893 println!("ABIv{v}");
894 for len in 0..20 {
895 let mut bytes = vec![b'a'; 1usize << len];
896 bytes[0] = b'f'; let string = String::from_utf8(bytes)?;
898
899 let serialized = AbiValue::String(string.clone()).make_cell(v)?;
900 load_simple(v, serialized.clone(), AbiValue::String(string))?;
901 }
902 }
903
904 Ok(())
905 }
906
907 #[test]
908 fn decode_nested_simple_tuple() -> Result<()> {
909 let cell = {
910 let mut builder = CellBuilder::new();
911 builder.store_u32(0)?;
912 builder.store_reference(Cell::empty_cell())?;
913 builder.store_bit_zero()?;
914 builder.store_u8(-15_i8 as _)?;
915 builder.store_u16(-9845_i16 as _)?;
916 builder.store_u32(-1_i32 as _)?;
917 builder.store_u64(12345678_i64 as _)?;
918 builder.store_u128(-12345678_i128 as _)?;
919 builder.store_u8(255)?;
920 builder.store_u16(0)?;
921 builder.store_u32(256)?;
922 builder.store_u64(123)?;
923 builder.store_u128(1234567890)?;
924 builder.build()?
925 };
926
927 let value = AbiValue::unnamed_tuple([
928 AbiValue::uint(32, 0u32),
929 AbiValue::Cell(Cell::empty_cell()),
930 AbiValue::Bool(false),
931 AbiValue::unnamed_tuple([
932 AbiValue::int(8, -15),
933 AbiValue::int(16, -9845),
934 AbiValue::unnamed_tuple([
935 AbiValue::int(32, -1),
936 AbiValue::int(64, 12345678),
937 AbiValue::int(128, -12345678),
938 ]),
939 ]),
940 AbiValue::unnamed_tuple([
941 AbiValue::uint(8, 255_u8),
942 AbiValue::uint(16, 0_u16),
943 AbiValue::unnamed_tuple([
944 AbiValue::uint(32, 256_u32),
945 AbiValue::uint(64, 123_u64),
946 AbiValue::uint(128, 1234567890_u128),
947 ]),
948 ]),
949 ]);
950
951 for v in VX_X {
952 println!("ABIv{v}");
953 load_simple(v, cell.clone(), value.clone())?;
954 }
955
956 Ok(())
957 }
958
959 #[test]
960 fn decode_tuple_four_refs_and_four_uint256() -> Result<()> {
961 let bytes = HashBytes([0xff; 32]);
962 let bytes_cell = CellBuilder::build_from(bytes)?;
963
964 let cell = {
965 let mut builder = CellBuilder::new();
966 builder.store_u32(0)?;
967 builder.store_reference(Cell::empty_cell())?;
968
969 builder.store_reference(bytes_cell.clone())?;
970 builder.store_reference(bytes_cell.clone())?;
971
972 let mut second_builder = CellBuilder::new();
973 second_builder.store_reference(bytes_cell.clone())?;
974 second_builder.store_u256(&bytes)?;
975 second_builder.store_u256(&bytes)?;
976 second_builder.store_u256(&bytes)?;
977
978 let mut third_builder = CellBuilder::new();
979 third_builder.store_u256(&bytes)?;
980
981 second_builder.store_reference(third_builder.build()?)?;
982 builder.store_reference(second_builder.build()?)?;
983
984 builder.build()?
985 };
986
987 let value = AbiValue::unnamed_tuple([
988 AbiValue::uint(32, 0_u32),
989 AbiValue::Cell(Cell::empty_cell()),
990 AbiValue::Cell(bytes_cell.clone()),
991 AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
992 AbiValue::Cell(bytes_cell),
993 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
994 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
995 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
996 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
997 ]);
998
999 for v in VX_X {
1000 println!("ABIv{v}");
1001 load_simple(v, cell.clone(), value.clone())?;
1002 }
1003
1004 Ok(())
1005 }
1006
1007 #[test]
1008 fn decode_tuple_four_refs_and_one_uint256() -> Result<()> {
1009 let bytes = HashBytes([0x55; 32]);
1010 let bytes_cell = CellBuilder::build_from(bytes)?;
1011
1012 let mut builder = CellBuilder::new();
1013 builder.store_u32(0)?;
1014 builder.store_reference(Cell::empty_cell())?;
1015
1016 builder.store_reference(bytes_cell.clone())?;
1017 builder.store_reference(bytes_cell.clone())?;
1018
1019 let cell_v2 = {
1020 let mut builder = builder.clone();
1021 builder.store_reference(bytes_cell.clone())?;
1022 builder.store_u256(&bytes)?;
1023 builder.build()?
1024 };
1025
1026 let cell_v1 = {
1027 let mut child_builder = CellBuilder::new();
1028 child_builder.store_reference(bytes_cell.clone())?;
1029 child_builder.store_u256(&bytes)?;
1030
1031 builder.store_reference(child_builder.build()?)?;
1032 builder.build()?
1033 };
1034
1035 let value = AbiValue::unnamed_tuple([
1036 AbiValue::uint(32, 0_u32),
1037 AbiValue::Cell(Cell::empty_cell()),
1038 AbiValue::Cell(bytes_cell.clone()),
1039 AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1040 AbiValue::Cell(bytes_cell.clone()),
1041 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1042 ]);
1043
1044 load_simple(AbiVersion::V1_0, cell_v1, value.clone())?;
1045 for v in V2_X {
1046 println!("ABIv{v}");
1047 load_simple(v, cell_v2.clone(), value.clone())?;
1048 }
1049
1050 Ok(())
1051 }
1052
1053 #[test]
1054 fn decode_map_simple() -> Result<()> {
1055 let bytes = HashBytes([0x55; 32]);
1056 let bytes_cell = CellBuilder::build_from(bytes)?;
1057
1058 let mut bytes_map = Dict::<u8, Cell>::new();
1059 for i in 1..=3 {
1060 bytes_map.set(i, bytes_cell.clone())?;
1061 }
1062 let bytes_map_value = AbiValue::map([
1063 (1u8, Bytes::copy_from_slice(bytes.as_slice())),
1064 (2, Bytes::copy_from_slice(bytes.as_slice())),
1065 (3, Bytes::copy_from_slice(bytes.as_slice())),
1066 ]);
1067
1068 let mut int_map = Dict::<i16, i128>::new();
1069 for i in -1..=1 {
1070 int_map.set(i, i as i128)?;
1071 }
1072 let int_map_value = AbiValue::map([(-1i16, -1i128), (0, 0), (1, 1)]);
1073
1074 let mut tuples_map = Dict::<u128, (u32, bool)>::new();
1075 for i in 1..=5 {
1076 tuples_map.set(i as u128, (i, i % 2 != 0))?;
1077 }
1078 let tuples_map_value = AbiValue::map([
1079 (1u128, (1u32, true)),
1080 (2, (2, false)),
1081 (3, (3, true)),
1082 (4, (4, false)),
1083 (5, (5, true)),
1084 ]);
1085
1086 let context = Cell::empty_context();
1088 let mut builder = CellBuilder::new();
1089 builder.store_u32(0)?;
1090 builder.store_reference(Cell::empty_cell())?;
1091
1092 bytes_map.store_into(&mut builder, context)?;
1093 int_map.store_into(&mut builder, context)?;
1094
1095 let cell_v2 = {
1096 let mut builder = builder.clone();
1097 tuples_map.store_into(&mut builder, context)?;
1098 builder.store_bit_zero()?;
1099 builder.build()?
1100 };
1101
1102 let cell_v1 = {
1103 let mut child_builder = CellBuilder::new();
1104 tuples_map.store_into(&mut child_builder, context)?;
1105 child_builder.store_bit_zero()?;
1106
1107 builder.store_reference(child_builder.build()?)?;
1108 builder.build()?
1109 };
1110
1111 let value = AbiValue::unnamed_tuple([
1112 AbiValue::uint(32, 0u32),
1113 AbiValue::Cell(Cell::empty_cell()),
1114 bytes_map_value,
1115 int_map_value,
1116 tuples_map_value,
1117 AbiValue::map([] as [(HashBytes, bool); 0]),
1118 ]);
1119
1120 for v in VX_X {
1121 println!("ABIv{v}");
1122 load_simple(v, cell_v1.clone(), value.clone())?;
1123 }
1124
1125 for v in V2_X {
1126 println!("ABIv{v}");
1127 load_simple(v, cell_v2.clone(), value.clone())?;
1128 }
1129
1130 Ok(())
1131 }
1132
1133 #[test]
1134 fn decode_map_address() -> Result<()> {
1135 let addr1 = StdAddr::new(0, HashBytes([0x11; 32]));
1136 let addr2 = StdAddr::new(0, HashBytes([0x22; 32]));
1137
1138 let mut addr_map = Dict::<StdAddr, u32>::new();
1139 addr_map.set(&addr1, 123)?;
1140 addr_map.set(&addr2, 456)?;
1141
1142 let addr_map_value = AbiValue::map([(addr1, 123u32), (addr2, 456)]);
1143
1144 let cell = {
1146 let mut builder = CellBuilder::new();
1147 builder.store_u32(0)?;
1148 builder.store_reference(Cell::empty_cell())?;
1149 addr_map.store_into(&mut builder, Cell::empty_context())?;
1150 builder.build()?
1151 };
1152
1153 let value = AbiValue::unnamed_tuple([
1154 AbiValue::uint(32, 0u32),
1155 AbiValue::Cell(Cell::empty_cell()),
1156 addr_map_value,
1157 ]);
1158
1159 for v in VX_X {
1160 println!("ABIv{v}");
1161 load_simple(v, cell.clone(), value.clone())?;
1162 }
1163
1164 Ok(())
1165 }
1166
1167 #[test]
1168 fn decode_map_big_value() -> Result<()> {
1169 let mut map_value = CellBuilder::new();
1170 map_value.store_u128(0)?;
1171 map_value.store_u128(1)?;
1172 map_value.store_u128(0)?;
1173 map_value.store_u128(2)?;
1174 map_value.store_u128(0)?;
1175 map_value.store_u128(3)?;
1176 map_value.store_reference(CellBuilder::build_from((0u128, 4u128))?)?;
1177 let map_value = map_value.build()?;
1178
1179 let mut key = CellBuilder::new();
1180 key.store_u128(0)?;
1181 key.store_u128(123)?;
1182
1183 let mut map = RawDict::<256>::new();
1184 map.set(key.as_data_slice(), &map_value)?;
1185
1186 let mut key = CellBuilder::new();
1188 key.store_u32(0)?;
1189
1190 let mut array = RawDict::<32>::new();
1191 array.set(key.as_data_slice(), &map_value)?;
1192
1193 let tuple_value = AbiValue::unnamed_tuple([
1195 AbiValue::uint(256, 1_u32),
1196 AbiValue::uint(256, 2_u32),
1197 AbiValue::uint(256, 3_u32),
1198 AbiValue::uint(256, 4_u32),
1199 ]);
1200
1201 let value = AbiValue::unnamed_tuple([
1202 AbiValue::uint(32, 0u32),
1203 AbiValue::Cell(Cell::empty_cell()),
1204 AbiValue::Map(
1205 PlainAbiType::Uint(256),
1206 Arc::new(tuple_value.get_type()),
1207 BTreeMap::from([(
1208 PlainAbiValue::Uint(256, BigUint::from(123u32)),
1209 tuple_value.clone(),
1210 )]),
1211 ),
1212 AbiValue::Array(Arc::new(tuple_value.get_type()), vec![tuple_value]),
1213 ]);
1214
1215 let cell = {
1217 let context = Cell::empty_context();
1218 let mut builder = CellBuilder::new();
1219 builder.store_u32(0)?;
1220 builder.store_reference(Cell::empty_cell())?;
1221
1222 map.store_into(&mut builder, context)?;
1223
1224 builder.store_u32(1)?;
1225 array.store_into(&mut builder, context)?;
1226
1227 builder.build()?
1228 };
1229
1230 for v in V2_X {
1231 println!("ABIv{v}");
1232 load_simple(v, cell.clone(), value.clone())?;
1233 }
1234
1235 Ok(())
1236 }
1237
1238 #[test]
1239 fn decode_optional() -> Result<()> {
1240 const STR: &str = "Some string";
1241
1242 let string_cell = {
1243 let mut builder = CellBuilder::new();
1244 builder.store_raw(STR.as_bytes(), (STR.len() * 8) as u16)?;
1245 builder.build()?
1246 };
1247 let string_value = AbiValue::String(STR.to_owned());
1248
1249 let tuple_value = AbiValue::unnamed_tuple([
1250 string_value.clone(),
1251 string_value.clone(),
1252 string_value.clone(),
1253 string_value.clone(),
1254 ]);
1255
1256 let value = AbiValue::unnamed_tuple([
1257 AbiValue::uint(32, 0u32),
1258 AbiValue::Cell(Cell::empty_cell()),
1259 AbiValue::varint(16, -123),
1260 AbiValue::varuint(32, 456u32),
1261 AbiValue::optional(None::<bool>),
1262 AbiValue::Optional(
1263 Arc::new(AbiType::Uint(1022)),
1264 Some(Box::new(AbiValue::uint(1022, 1u32))),
1265 ),
1266 AbiValue::Optional(
1267 Arc::new(AbiType::varuint(128)),
1268 Some(Box::new(AbiValue::varuint(128, 123u32))),
1269 ),
1270 AbiValue::Optional(
1271 Arc::new(tuple_value.get_type()),
1272 Some(Box::new(tuple_value)),
1273 ),
1274 ]);
1275
1276 let cell = {
1277 let mut builder = CellBuilder::new();
1278 builder.store_u32(0)?;
1279 builder.store_reference(Cell::empty_cell())?;
1280
1281 builder.store_small_uint(1, 4)?;
1282 builder.store_u8(-123i8 as _)?;
1283
1284 builder.store_small_uint(2, 5)?;
1285 builder.store_u16(456)?;
1286
1287 builder.store_bit_zero()?;
1288
1289 builder.store_reference({
1290 let mut builder = CellBuilder::new();
1291 builder.store_bit_one()?;
1292 builder.store_zeros(127 * 8)?;
1293 builder.store_small_uint(1, 6)?;
1294
1295 builder.store_reference({
1296 let mut builder = CellBuilder::new();
1297 builder.store_bit_one()?;
1298 builder.store_reference({
1299 let mut builder = CellBuilder::new();
1300 builder.store_small_uint(1, 7)?;
1301 builder.store_u8(123)?;
1302 builder.build()?
1303 })?;
1304
1305 builder.store_bit_one()?;
1306 builder.store_reference(CellBuilder::build_from((
1307 string_cell.clone(),
1308 string_cell.clone(),
1309 string_cell.clone(),
1310 string_cell.clone(),
1311 ))?)?;
1312
1313 builder.build()?
1314 })?;
1315
1316 builder.build()?
1317 })?;
1318
1319 builder.build()?
1320 };
1321
1322 for v in V2_X {
1323 println!("ABIv{v}");
1324 load_simple(v, cell.clone(), value.clone())?;
1325 }
1326
1327 Ok(())
1328 }
1329
1330 #[test]
1331 fn decode_ref() -> Result<()> {
1332 let cell = {
1333 let mut builder = CellBuilder::new();
1334 builder.store_u32(0)?;
1335 builder.store_reference(Cell::empty_cell())?;
1336
1337 builder.store_reference(CellBuilder::build_from(123u64)?)?;
1338 builder.store_reference(CellBuilder::build_from((true, Cell::empty_cell()))?)?;
1339
1340 builder.build()?
1341 };
1342
1343 let value = AbiValue::unnamed_tuple([
1344 AbiValue::uint(32, 0u32),
1345 AbiValue::Cell(Cell::empty_cell()),
1346 AbiValue::reference(123u64),
1347 AbiValue::reference((true, Cell::empty_cell())),
1348 ]);
1349
1350 for v in V2_X {
1351 println!("ABIv{v}");
1352 load_simple(v, cell.clone(), value.clone())?;
1353 }
1354
1355 Ok(())
1356 }
1357}