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