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 + 7) / 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 + 7) / 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!(
455 bytes.len() == len,
456 AbiError::BytesSizeMismatch {
457 expected: len,
458 len: bytes.len()
459 }
460 );
461 Ok(bytes)
462}
463
464fn load_string(version: AbiVersion, last: bool, slice: &mut CellSlice) -> Result<String> {
465 let bytes = ok!(load_bytes_raw(version, last, slice));
466 match String::from_utf8(bytes) {
467 Ok(str) => Ok(str),
468 Err(e) => Err(AbiError::InvalidString(e.utf8_error()).into()),
469 }
470}
471
472fn load_array_raw(
473 ty: &AbiType,
474 len: usize,
475 version: AbiVersion,
476 allow_partial: bool,
477 slice: &mut CellSlice,
478) -> Result<Vec<AbiValue>> {
479 ok!(preload_bits(1, slice));
480 let dict = RawDict::<32>::load_from(slice)?;
481
482 let mut result = Vec::with_capacity(len);
483 for value in dict.values().take(len) {
484 let slice = &mut value?;
485 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
486 ok!(AbiValue::check_remaining(slice, allow_partial));
487 result.push(value);
488 }
489
490 Ok(result)
491}
492
493fn load_array(
494 ty: &AbiType,
495 version: AbiVersion,
496 allow_partial: bool,
497 slice: &mut CellSlice,
498) -> Result<Vec<AbiValue>> {
499 ok!(preload_bits(32, slice));
500 let len = slice.load_u32()?;
501 load_array_raw(ty, len as usize, version, allow_partial, slice)
502}
503
504fn load_fixed_array(
505 ty: &AbiType,
506 len: usize,
507 version: AbiVersion,
508 allow_partial: bool,
509 slice: &mut CellSlice,
510) -> Result<Vec<AbiValue>> {
511 let values = ok!(load_array_raw(ty, len, version, allow_partial, slice));
512 anyhow::ensure!(
513 values.len() == len,
514 AbiError::ArraySizeMismatch {
515 expected: len,
516 len: values.len()
517 }
518 );
519 Ok(values)
520}
521
522fn load_map(
523 key_ty: PlainAbiType,
524 value_ty: &AbiType,
525 version: AbiVersion,
526 allow_partial: bool,
527 slice: &mut CellSlice,
528) -> Result<BTreeMap<PlainAbiValue, AbiValue>> {
529 ok!(preload_bits(1, slice));
530
531 let key_bits = key_ty.key_bits();
532 let dict = Option::<Cell>::load_from(slice)?;
533
534 let mut result = BTreeMap::new();
535 for entry in dict::RawIter::new(&dict, key_bits) {
536 let (key, mut slice) = entry?;
537 let key = PlainAbiValue::load(key_ty, &mut key.as_data_slice())?;
538 let value = ok!(AbiValue::load_ext(
539 value_ty,
540 version,
541 true,
542 allow_partial,
543 &mut slice
544 ));
545 result.insert(key, value);
546 }
547
548 Ok(result)
549}
550
551fn load_optional(
552 ty: &AbiType,
553 version: AbiVersion,
554 last: bool,
555 allow_partial: bool,
556 slice: &mut CellSlice,
557) -> Result<Option<Box<AbiValue>>> {
558 ok!(preload_bits(1, slice));
559
560 if !slice.load_bit()? {
561 return Ok(None);
562 }
563
564 let ty_size = ty.max_size();
565 if ty_size.bit_count < MAX_BIT_LEN as u64 && ty_size.cell_count < MAX_REF_COUNT as u64 {
566 let value = ok!(AbiValue::load_ext(ty, version, last, allow_partial, slice));
567 Ok(Some(Box::new(value)))
568 } else {
569 let cell = ok!(load_cell(version, last, slice));
570 let slice = &mut cell.as_slice()?;
571 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
572 ok!(AbiValue::check_remaining(slice, allow_partial));
573 Ok(Some(Box::new(value)))
574 }
575}
576
577fn load_ref(
578 ty: &AbiType,
579 version: AbiVersion,
580 last: bool,
581 allow_partial: bool,
582 slice: &mut CellSlice,
583) -> Result<Box<AbiValue>> {
584 let cell = ok!(load_cell(version, last, slice));
585 let slice = &mut cell.as_slice()?;
586 let value = ok!(AbiValue::load_ext(ty, version, true, allow_partial, slice));
587 ok!(AbiValue::check_remaining(slice, allow_partial));
588 Ok(Box::new(value))
589}
590
591#[cfg(test)]
592mod tests {
593 use std::sync::Arc;
594
595 use crate::boc::Boc;
596 use crate::dict::Dict;
597 use crate::models::{StdAddr, VarAddr};
598 use crate::num::{Uint9, VarUint24, VarUint56};
599 use crate::prelude::{CellBuilder, CellFamily, HashBytes, Store};
600
601 use super::*;
602
603 trait BuildCell {
604 fn build_cell(&self) -> Result<Cell>;
605 }
606
607 impl<T: Store> BuildCell for T {
608 fn build_cell(&self) -> Result<Cell> {
609 CellBuilder::build_from(self).map_err(From::from)
610 }
611 }
612
613 impl BuildCell for &str {
614 fn build_cell(&self) -> Result<Cell> {
615 Boc::decode_base64(self).map_err(From::from)
616 }
617 }
618
619 fn load_simple<T>(version: AbiVersion, boc: T, expected: AbiValue) -> Result<()>
620 where
621 T: BuildCell,
622 {
623 let cell = boc.build_cell()?;
624 let ty = expected.get_type();
625 assert_eq!(
626 AbiValue::load(&ty, version, &mut cell.as_slice()?)?,
627 expected
628 );
629 Ok(())
630 }
631
632 fn load_tuple<T>(version: AbiVersion, boc: T, expected: &[AbiValue]) -> Result<()>
633 where
634 T: BuildCell,
635 {
636 let cell = boc.build_cell()?;
637 let ty = expected.iter().map(AbiValue::get_type).collect::<Vec<_>>();
638 assert_eq!(
639 AbiValue::load_tuple(&ty, version, &mut cell.as_slice()?)?,
640 expected
641 );
642 Ok(())
643 }
644
645 macro_rules! assert_basic_err {
646 ($expr:expr, $err:expr) => {{
647 match $expr {
648 Ok(_) => panic!("Expected basic error: {:?}, got success", $err),
649 Err(e) => {
650 if let Some(e) = e.downcast_ref::<Error>() {
651 assert_eq!(e, &($err));
652 } else {
653 panic!("Unexpected error: {e:?}");
654 }
655 }
656 }
657 }};
658 }
659
660 macro_rules! assert_abi_err {
661 ($expr:expr, $err:expr) => {{
662 match $expr {
663 Ok(_) => panic!("Expected ABI error: {:?}, got success", $err),
664 Err(e) => {
665 if let Some(e) = e.downcast_ref::<AbiError>() {
666 assert_eq!(e, &($err));
667 } else {
668 panic!("Unexpected error: {e:?}");
669 }
670 }
671 }
672 }};
673 }
674
675 const VX_X: [AbiVersion; 5] = [
676 AbiVersion::V1_0,
677 AbiVersion::V2_0,
678 AbiVersion::V2_1,
679 AbiVersion::V2_2,
680 AbiVersion::V2_3,
681 ];
682 const V2_X: [AbiVersion; 4] = [
683 AbiVersion::V2_0,
684 AbiVersion::V2_1,
685 AbiVersion::V2_2,
686 AbiVersion::V2_3,
687 ];
688
689 #[test]
690 fn failed_decode() -> Result<()> {
691 for v in VX_X {
692 assert_basic_err!(
693 load_simple(v, false, AbiValue::uint(32, 0u32)),
694 Error::CellUnderflow
695 );
696
697 assert_abi_err!(
698 load_simple(v, u64::MAX, AbiValue::uint(32, 0u32)),
699 AbiError::IncompleteDeserialization
700 );
701
702 assert_abi_err!(
703 load_tuple(v, u64::MAX, &[AbiValue::uint(32, u32::MAX)]),
704 AbiError::IncompleteDeserialization
705 );
706 }
707
708 Ok(())
709 }
710
711 #[test]
712 fn decode_int() -> Result<()> {
713 macro_rules! define_tests {
714 ($v:ident, { $($abi:ident($bits:literal) => [$($expr:expr),*$(,)?]),*$(,)? }) => {$(
715 $(load_simple($v, $expr, AbiValue::$abi($bits, $expr))?;)*
716 )*};
717 }
718
719 for v in VX_X {
720 define_tests!(v, {
721 uint(8) => [0u8, 123u8, u8::MAX],
722 uint(16) => [0u16, 1234u16, u16::MAX],
723 uint(32) => [0u32, 123456u32, u32::MAX],
724 uint(64) => [0u64, 123456789u64, u64::MAX],
725 uint(128) => [0u128, 123456789123123123123u128, u128::MAX],
726
727 int(8) => [0i8, 123i8, i8::MIN, i8::MAX],
728 int(16) => [0i16, 1234i16, i16::MIN, i16::MAX],
729 int(32) => [0i32, 123456i32, i32::MIN, i32::MAX],
730 int(64) => [0i64, 123456789i64, i64::MIN, i64::MAX],
731 int(128) => [0i128, 123456789123123123123i128, i128::MIN, i128::MAX],
732 });
733 }
734
735 Ok(())
736 }
737
738 #[test]
739 fn decode_varint() -> Result<()> {
740 for v in VX_X {
741 println!("ABIv{v}");
742 load_simple(v, VarUint24::ZERO, AbiValue::varuint(4, 0u32))?;
743 load_simple(v, VarUint24::MAX, AbiValue::varuint(4, u32::MAX >> 8))?;
744 load_simple(v, VarUint24::new(123321), AbiValue::varuint(4, 123321u32))?;
745
746 load_simple(v, VarUint56::ZERO, AbiValue::varuint(8, 0u32))?;
747 load_simple(v, VarUint56::MAX, AbiValue::varuint(8, u64::MAX >> 8))?;
748 load_simple(
749 v,
750 VarUint56::new(1233213213123123),
751 AbiValue::varuint(8, 1233213213123123u64),
752 )?;
753
754 load_simple(
755 v,
756 "te6ccgEBAQEABgAABzAeG5g=",
757 AbiValue::varuint(16, 123321u32),
758 )?;
759 load_simple(v, "te6ccgEBAQEABgAABzAeG5g=", AbiValue::varint(16, 123321))?;
760
761 load_simple(v, Tokens::ZERO, AbiValue::varuint(16, 0u32))?;
762 load_simple(v, Tokens::ZERO, AbiValue::Token(Tokens::ZERO))?;
763
764 let mut prev_value = 0;
765 for byte in 0..15 {
766 let value = (0xffu128 << (byte * 8)) | prev_value;
767 prev_value = value;
768 load_simple(v, Tokens::new(value), AbiValue::varuint(16, value))?;
769 load_simple(v, Tokens::new(value), AbiValue::Token(Tokens::new(value)))?;
770 }
771 }
772
773 Ok(())
774 }
775
776 #[test]
777 fn decode_bool() -> Result<()> {
778 for v in VX_X {
779 println!("ABIv{v}");
780 load_simple(v, false, AbiValue::Bool(false))?;
781 load_simple(v, true, AbiValue::Bool(true))?;
782 }
783 Ok(())
784 }
785
786 #[test]
787 fn decode_cell() -> Result<()> {
788 {
790 load_simple(
791 AbiVersion::V1_0,
792 "te6ccgEBAgEABQABAAEAAA==", AbiValue::Cell(Cell::empty_cell()),
794 )?;
795
796 let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
798 let slice = &mut cell.as_slice()?;
799 slice.skip_first(0, 3)?;
800
801 assert_basic_err!(
802 AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice),
803 Error::CellUnderflow
804 );
805
806 let cell = Boc::decode_base64("te6ccgEBAwEACwAEAAICAgEBAAIAAA==")?;
808 let slice = &mut cell.as_slice()?;
809 slice.skip_first(0, 3)?;
810
811 assert_eq!(
812 AbiValue::load(&AbiType::Cell, AbiVersion::V1_0, slice)?,
813 AbiValue::Cell(Cell::empty_cell())
814 );
815 }
816
817 for v in V2_X {
818 println!("ABIv{v}");
819 load_simple(
820 v,
821 "te6ccgEBAgEABQABAAEAAA==", AbiValue::Cell(Cell::empty_cell()),
823 )?;
824
825 let cell = Boc::decode_base64("te6ccgEBAgEACAAEAAEBAQEAAA==")?;
827 let slice = &mut cell.as_slice()?;
828 slice.skip_first(0, 3)?;
829
830 assert_eq!(
831 AbiValue::load(&AbiType::Cell, v, slice)?,
832 AbiValue::Cell(Cell::empty_cell())
833 );
834 }
835
836 Ok(())
837 }
838
839 #[test]
840 fn decode_address() -> Result<()> {
841 for v in VX_X {
842 println!("ABIv{v}");
843 let addr: StdAddr = StdAddr::from((0i8, [0xffu8; 32]));
844 load_simple(
845 v,
846 addr.clone(),
847 AbiValue::Address(Box::new(IntAddr::Std(addr))),
848 )?;
849
850 let addr: VarAddr = VarAddr {
851 address_len: Uint9::new(10 * 8),
852 anycast: None,
853 workchain: 123456,
854 address: vec![0xffu8; 10],
855 };
856 load_simple(
857 v,
858 addr.clone(),
859 AbiValue::Address(Box::new(IntAddr::Var(addr))),
860 )?;
861 }
862
863 Ok(())
864 }
865
866 #[test]
867 fn decode_bytes() -> Result<()> {
868 for v in VX_X {
869 println!("ABIv{v}");
870 for len in 0..20 {
871 let mut bytes = vec![0xffu8; 1usize << len];
872 bytes[0] = 0x55; let bytes = Bytes::from(bytes);
874 let serialized = AbiValue::Bytes(bytes.clone()).make_cell(v)?;
875
876 load_simple(v, serialized.clone(), AbiValue::Bytes(bytes.clone()))?;
877 load_simple(v, serialized.clone(), AbiValue::FixedBytes(bytes.clone()))?;
878
879 let original = bytes.len();
880 assert_abi_err!(
881 load_simple(
882 v,
883 serialized.clone(),
884 AbiValue::FixedBytes(bytes.slice(..original / 2))
885 ),
886 AbiError::BytesSizeMismatch {
887 expected: original / 2,
888 len: original
889 }
890 )
891 }
892 }
893
894 Ok(())
895 }
896
897 #[test]
898 fn decode_string() -> Result<()> {
899 for v in VX_X {
900 println!("ABIv{v}");
901 for len in 0..20 {
902 let mut bytes = vec![b'a'; 1usize << len];
903 bytes[0] = b'f'; let string = String::from_utf8(bytes)?;
905
906 let serialized = AbiValue::String(string.clone()).make_cell(v)?;
907 load_simple(v, serialized.clone(), AbiValue::String(string))?;
908 }
909 }
910
911 Ok(())
912 }
913
914 #[test]
915 fn decode_nested_simple_tuple() -> Result<()> {
916 let cell = {
917 let mut builder = CellBuilder::new();
918 builder.store_u32(0)?;
919 builder.store_reference(Cell::empty_cell())?;
920 builder.store_bit_zero()?;
921 builder.store_u8(-15_i8 as _)?;
922 builder.store_u16(-9845_i16 as _)?;
923 builder.store_u32(-1_i32 as _)?;
924 builder.store_u64(12345678_i64 as _)?;
925 builder.store_u128(-12345678_i128 as _)?;
926 builder.store_u8(255)?;
927 builder.store_u16(0)?;
928 builder.store_u32(256)?;
929 builder.store_u64(123)?;
930 builder.store_u128(1234567890)?;
931 builder.build()?
932 };
933
934 let value = AbiValue::unnamed_tuple([
935 AbiValue::uint(32, 0u32),
936 AbiValue::Cell(Cell::empty_cell()),
937 AbiValue::Bool(false),
938 AbiValue::unnamed_tuple([
939 AbiValue::int(8, -15),
940 AbiValue::int(16, -9845),
941 AbiValue::unnamed_tuple([
942 AbiValue::int(32, -1),
943 AbiValue::int(64, 12345678),
944 AbiValue::int(128, -12345678),
945 ]),
946 ]),
947 AbiValue::unnamed_tuple([
948 AbiValue::uint(8, 255_u8),
949 AbiValue::uint(16, 0_u16),
950 AbiValue::unnamed_tuple([
951 AbiValue::uint(32, 256_u32),
952 AbiValue::uint(64, 123_u64),
953 AbiValue::uint(128, 1234567890_u128),
954 ]),
955 ]),
956 ]);
957
958 for v in VX_X {
959 println!("ABIv{v}");
960 load_simple(v, cell.clone(), value.clone())?;
961 }
962
963 Ok(())
964 }
965
966 #[test]
967 fn decode_tuple_four_refs_and_four_uint256() -> Result<()> {
968 let bytes = HashBytes([0xff; 32]);
969 let bytes_cell = CellBuilder::build_from(bytes)?;
970
971 let cell = {
972 let mut builder = CellBuilder::new();
973 builder.store_u32(0)?;
974 builder.store_reference(Cell::empty_cell())?;
975
976 builder.store_reference(bytes_cell.clone())?;
977 builder.store_reference(bytes_cell.clone())?;
978
979 let mut second_builder = CellBuilder::new();
980 second_builder.store_reference(bytes_cell.clone())?;
981 second_builder.store_u256(&bytes)?;
982 second_builder.store_u256(&bytes)?;
983 second_builder.store_u256(&bytes)?;
984
985 let mut third_builder = CellBuilder::new();
986 third_builder.store_u256(&bytes)?;
987
988 second_builder.store_reference(third_builder.build()?)?;
989 builder.store_reference(second_builder.build()?)?;
990
991 builder.build()?
992 };
993
994 let value = AbiValue::unnamed_tuple([
995 AbiValue::uint(32, 0_u32),
996 AbiValue::Cell(Cell::empty_cell()),
997 AbiValue::Cell(bytes_cell.clone()),
998 AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
999 AbiValue::Cell(bytes_cell),
1000 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1001 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1002 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1003 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1004 ]);
1005
1006 for v in VX_X {
1007 println!("ABIv{v}");
1008 load_simple(v, cell.clone(), value.clone())?;
1009 }
1010
1011 Ok(())
1012 }
1013
1014 #[test]
1015 fn decode_tuple_four_refs_and_one_uint256() -> Result<()> {
1016 let bytes = HashBytes([0x55; 32]);
1017 let bytes_cell = CellBuilder::build_from(bytes)?;
1018
1019 let mut builder = CellBuilder::new();
1020 builder.store_u32(0)?;
1021 builder.store_reference(Cell::empty_cell())?;
1022
1023 builder.store_reference(bytes_cell.clone())?;
1024 builder.store_reference(bytes_cell.clone())?;
1025
1026 let cell_v2 = {
1027 let mut builder = builder.clone();
1028 builder.store_reference(bytes_cell.clone())?;
1029 builder.store_u256(&bytes)?;
1030 builder.build()?
1031 };
1032
1033 let cell_v1 = {
1034 let mut child_builder = CellBuilder::new();
1035 child_builder.store_reference(bytes_cell.clone())?;
1036 child_builder.store_u256(&bytes)?;
1037
1038 builder.store_reference(child_builder.build()?)?;
1039 builder.build()?
1040 };
1041
1042 let value = AbiValue::unnamed_tuple([
1043 AbiValue::uint(32, 0_u32),
1044 AbiValue::Cell(Cell::empty_cell()),
1045 AbiValue::Cell(bytes_cell.clone()),
1046 AbiValue::Bytes(Bytes::copy_from_slice(bytes.as_slice())),
1047 AbiValue::Cell(bytes_cell.clone()),
1048 AbiValue::uint(256, BigUint::from_bytes_be(bytes.as_slice())),
1049 ]);
1050
1051 load_simple(AbiVersion::V1_0, cell_v1, value.clone())?;
1052 for v in V2_X {
1053 println!("ABIv{v}");
1054 load_simple(v, cell_v2.clone(), value.clone())?;
1055 }
1056
1057 Ok(())
1058 }
1059
1060 #[test]
1061 fn decode_map_simple() -> Result<()> {
1062 let bytes = HashBytes([0x55; 32]);
1063 let bytes_cell = CellBuilder::build_from(bytes)?;
1064
1065 let mut bytes_map = Dict::<u8, Cell>::new();
1066 for i in 1..=3 {
1067 bytes_map.set(i, bytes_cell.clone())?;
1068 }
1069 let bytes_map_value = AbiValue::map([
1070 (1u8, Bytes::copy_from_slice(bytes.as_slice())),
1071 (2, Bytes::copy_from_slice(bytes.as_slice())),
1072 (3, Bytes::copy_from_slice(bytes.as_slice())),
1073 ]);
1074
1075 let mut int_map = Dict::<i16, i128>::new();
1076 for i in -1..=1 {
1077 int_map.set(i, i as i128)?;
1078 }
1079 let int_map_value = AbiValue::map([(-1i16, -1i128), (0, 0), (1, 1)]);
1080
1081 let mut tuples_map = Dict::<u128, (u32, bool)>::new();
1082 for i in 1..=5 {
1083 tuples_map.set(i as u128, (i, i % 2 != 0))?;
1084 }
1085 let tuples_map_value = AbiValue::map([
1086 (1u128, (1u32, true)),
1087 (2, (2, false)),
1088 (3, (3, true)),
1089 (4, (4, false)),
1090 (5, (5, true)),
1091 ]);
1092
1093 let context = &mut Cell::empty_context();
1095 let mut builder = CellBuilder::new();
1096 builder.store_u32(0)?;
1097 builder.store_reference(Cell::empty_cell())?;
1098
1099 bytes_map.store_into(&mut builder, context)?;
1100 int_map.store_into(&mut builder, context)?;
1101
1102 let cell_v2 = {
1103 let mut builder = builder.clone();
1104 tuples_map.store_into(&mut builder, context)?;
1105 builder.store_bit_zero()?;
1106 builder.build()?
1107 };
1108
1109 let cell_v1 = {
1110 let mut child_builder = CellBuilder::new();
1111 tuples_map.store_into(&mut child_builder, context)?;
1112 child_builder.store_bit_zero()?;
1113
1114 builder.store_reference(child_builder.build()?)?;
1115 builder.build()?
1116 };
1117
1118 let value = AbiValue::unnamed_tuple([
1119 AbiValue::uint(32, 0u32),
1120 AbiValue::Cell(Cell::empty_cell()),
1121 bytes_map_value,
1122 int_map_value,
1123 tuples_map_value,
1124 AbiValue::map([] as [(HashBytes, bool); 0]),
1125 ]);
1126
1127 for v in VX_X {
1128 println!("ABIv{v}");
1129 load_simple(v, cell_v1.clone(), value.clone())?;
1130 }
1131
1132 for v in V2_X {
1133 println!("ABIv{v}");
1134 load_simple(v, cell_v2.clone(), value.clone())?;
1135 }
1136
1137 Ok(())
1138 }
1139
1140 #[test]
1141 fn decode_map_address() -> Result<()> {
1142 let addr1 = StdAddr::new(0, HashBytes([0x11; 32]));
1143 let addr2 = StdAddr::new(0, HashBytes([0x22; 32]));
1144
1145 let mut addr_map = Dict::<StdAddr, u32>::new();
1146 addr_map.set(&addr1, 123)?;
1147 addr_map.set(&addr2, 456)?;
1148
1149 let addr_map_value = AbiValue::map([(addr1, 123u32), (addr2, 456)]);
1150
1151 let cell = {
1153 let mut builder = CellBuilder::new();
1154 builder.store_u32(0)?;
1155 builder.store_reference(Cell::empty_cell())?;
1156 addr_map.store_into(&mut builder, &mut Cell::empty_context())?;
1157 builder.build()?
1158 };
1159
1160 let value = AbiValue::unnamed_tuple([
1161 AbiValue::uint(32, 0u32),
1162 AbiValue::Cell(Cell::empty_cell()),
1163 addr_map_value,
1164 ]);
1165
1166 for v in VX_X {
1167 println!("ABIv{v}");
1168 load_simple(v, cell.clone(), value.clone())?;
1169 }
1170
1171 Ok(())
1172 }
1173
1174 #[test]
1175 fn decode_map_big_value() -> Result<()> {
1176 let mut map_value = CellBuilder::new();
1177 map_value.store_u128(0)?;
1178 map_value.store_u128(1)?;
1179 map_value.store_u128(0)?;
1180 map_value.store_u128(2)?;
1181 map_value.store_u128(0)?;
1182 map_value.store_u128(3)?;
1183 map_value.store_reference(CellBuilder::build_from((0u128, 4u128))?)?;
1184 let map_value = map_value.build()?;
1185
1186 let mut key = CellBuilder::new();
1187 key.store_u128(0)?;
1188 key.store_u128(123)?;
1189
1190 let mut map = RawDict::<256>::new();
1191 map.set(key.as_data_slice(), &map_value)?;
1192
1193 let mut key = CellBuilder::new();
1195 key.store_u32(0)?;
1196
1197 let mut array = RawDict::<32>::new();
1198 array.set(key.as_data_slice(), &map_value)?;
1199
1200 let tuple_value = AbiValue::unnamed_tuple([
1202 AbiValue::uint(256, 1_u32),
1203 AbiValue::uint(256, 2_u32),
1204 AbiValue::uint(256, 3_u32),
1205 AbiValue::uint(256, 4_u32),
1206 ]);
1207
1208 let value = AbiValue::unnamed_tuple([
1209 AbiValue::uint(32, 0u32),
1210 AbiValue::Cell(Cell::empty_cell()),
1211 AbiValue::Map(
1212 PlainAbiType::Uint(256),
1213 Arc::new(tuple_value.get_type()),
1214 BTreeMap::from([(
1215 PlainAbiValue::Uint(256, BigUint::from(123u32)),
1216 tuple_value.clone(),
1217 )]),
1218 ),
1219 AbiValue::Array(Arc::new(tuple_value.get_type()), vec![tuple_value]),
1220 ]);
1221
1222 let cell = {
1224 let context = &mut Cell::empty_context();
1225 let mut builder = CellBuilder::new();
1226 builder.store_u32(0)?;
1227 builder.store_reference(Cell::empty_cell())?;
1228
1229 map.store_into(&mut builder, context)?;
1230
1231 builder.store_u32(1)?;
1232 array.store_into(&mut builder, context)?;
1233
1234 builder.build()?
1235 };
1236
1237 for v in V2_X {
1238 println!("ABIv{v}");
1239 load_simple(v, cell.clone(), value.clone())?;
1240 }
1241
1242 Ok(())
1243 }
1244
1245 #[test]
1246 fn decode_optional() -> Result<()> {
1247 const STR: &str = "Some string";
1248
1249 let string_cell = {
1250 let mut builder = CellBuilder::new();
1251 builder.store_raw(STR.as_bytes(), (STR.len() * 8) as u16)?;
1252 builder.build()?
1253 };
1254 let string_value = AbiValue::String(STR.to_owned());
1255
1256 let tuple_value = AbiValue::unnamed_tuple([
1257 string_value.clone(),
1258 string_value.clone(),
1259 string_value.clone(),
1260 string_value.clone(),
1261 ]);
1262
1263 let value = AbiValue::unnamed_tuple([
1264 AbiValue::uint(32, 0u32),
1265 AbiValue::Cell(Cell::empty_cell()),
1266 AbiValue::varint(16, -123),
1267 AbiValue::varuint(32, 456u32),
1268 AbiValue::optional(None::<bool>),
1269 AbiValue::Optional(
1270 Arc::new(AbiType::Uint(1022)),
1271 Some(Box::new(AbiValue::uint(1022, 1u32))),
1272 ),
1273 AbiValue::Optional(
1274 Arc::new(AbiType::varuint(128)),
1275 Some(Box::new(AbiValue::varuint(128, 123u32))),
1276 ),
1277 AbiValue::Optional(
1278 Arc::new(tuple_value.get_type()),
1279 Some(Box::new(tuple_value)),
1280 ),
1281 ]);
1282
1283 let cell = {
1284 let mut builder = CellBuilder::new();
1285 builder.store_u32(0)?;
1286 builder.store_reference(Cell::empty_cell())?;
1287
1288 builder.store_small_uint(1, 4)?;
1289 builder.store_u8(-123i8 as _)?;
1290
1291 builder.store_small_uint(2, 5)?;
1292 builder.store_u16(456)?;
1293
1294 builder.store_bit_zero()?;
1295
1296 builder.store_reference({
1297 let mut builder = CellBuilder::new();
1298 builder.store_bit_one()?;
1299 builder.store_zeros(127 * 8)?;
1300 builder.store_small_uint(1, 6)?;
1301
1302 builder.store_reference({
1303 let mut builder = CellBuilder::new();
1304 builder.store_bit_one()?;
1305 builder.store_reference({
1306 let mut builder = CellBuilder::new();
1307 builder.store_small_uint(1, 7)?;
1308 builder.store_u8(123)?;
1309 builder.build()?
1310 })?;
1311
1312 builder.store_bit_one()?;
1313 builder.store_reference(CellBuilder::build_from((
1314 string_cell.clone(),
1315 string_cell.clone(),
1316 string_cell.clone(),
1317 string_cell.clone(),
1318 ))?)?;
1319
1320 builder.build()?
1321 })?;
1322
1323 builder.build()?
1324 })?;
1325
1326 builder.build()?
1327 };
1328
1329 for v in V2_X {
1330 println!("ABIv{v}");
1331 load_simple(v, cell.clone(), value.clone())?;
1332 }
1333
1334 Ok(())
1335 }
1336
1337 #[test]
1338 fn decode_ref() -> Result<()> {
1339 let cell = {
1340 let mut builder = CellBuilder::new();
1341 builder.store_u32(0)?;
1342 builder.store_reference(Cell::empty_cell())?;
1343
1344 builder.store_reference(CellBuilder::build_from(123u64)?)?;
1345 builder.store_reference(CellBuilder::build_from((true, Cell::empty_cell()))?)?;
1346
1347 builder.build()?
1348 };
1349
1350 let value = AbiValue::unnamed_tuple([
1351 AbiValue::uint(32, 0u32),
1352 AbiValue::Cell(Cell::empty_cell()),
1353 AbiValue::reference(123u64),
1354 AbiValue::reference((true, Cell::empty_cell())),
1355 ]);
1356
1357 for v in V2_X {
1358 println!("ABIv{v}");
1359 load_simple(v, cell.clone(), value.clone())?;
1360 }
1361
1362 Ok(())
1363 }
1364}