everscale_types/
lib.rs

1#![warn(missing_docs)]
2
3//! Everscale types.
4//!
5//! This crate is a collection of basic structures and models for the
6//! Everscale blockchain. The [`Cell`] represents the core
7//! data structure which is used as an atom for building other structures.
8//!
9//! *Compiler support: [requires `rustc` 1.65+][msrv]*
10//!
11//! [msrv]: #supported-rust-versions
12//!
13//! ## `Cell` vs `CellSlice` vs `CellBuilder`
14//!
15//! - [`Cell`] is an immutable tree and provides only basic methods for accessing
16//!   nodes and some meta info.
17//!
18//! - [`CellSlice`] is a read-only view for a part of some cell. It can only
19//!   be obtained from an existing cell. A cell contains **up to 1023 bits** and
20//!   **up to 4 references**. Minimal data unit is bit, so a cell slice is similar
21//!   to a couple of ranges (bit range and refs range).
22//!
23//! - [`CellBuilder`] is used to create a new cell. It is used as an append-only
24//!   data structure and is the only way to create a new cell with the provided data.
25//!   Cell creation depends on a context (e.g. message creation in a wallet or a
26//!   TVM execution with gas tracking), so [`CellBuilder::build_ext`] accepts
27//!   a [`CellContext`] parameter which can be used to track and modify cells creation.
28//!
29//! ## BOC
30//!
31//! BOC (Bag Of Cells) is a format for representing a tree of cells as bytes.
32//! [`Boc`] type is used to convert between bytes and **cells** of the same family.
33//! [`BocRepr`] helper can be used to convert between bytes and **models** (which
34//! are representable as cells).
35//!
36//! ### Merkle stuff
37//!
38//! - Pruned branch is a "building block" of merkle structures. A single pruned branch
39//!   cell replaces a whole subtree and contains just the hash of its root cell hash.
40//!
41//! - [`MerkleProof`] contains a subset of original tree of cells. In most cases
42//!   it is created from [`UsageTree`] of some visited cells. Merkle proof is used
43//!   to proof that something was presented in the origin tree and provide some additional
44//!   context.
45//!
46//! - [`MerkleUpdate`] describes a difference between two trees of cells. It can be
47//!   applied to old cell to create a new cell.
48//!
49//! ### Numeric stuff
50//!
51//! This crate introduces some unusual number types with custom bit size or variable
52//! encoding. They are only used in models, but may be useful in user code.
53//!
54//! ### Dictionaries
55//!
56//! Dictionary, erroneously called HashmapE in the original TLB schema, is an
57//! important building block of blockchain models. It is similar to `BTreeMap`.
58//! Dictionary is an immutable structure over tree of cells with fixed-length
59//! keys and arbitrary values. Updates create a new cell tree each time, so
60//! it's quite an expensive data structure to work with.
61//!
62//! ### Models
63//!
64//! There is a simple definition of nearly all blockchain models. This definition
65//! doesn't contain any complex logic, but could be extended via extension traits.
66//! The names and structure of the models are slightly different from the
67//! definition in the TLB for the sake of consistency of use.
68//!
69//! All models implement [`Load`] and [`Store`] traits for conversion from/to cells.
70//!
71//! - [`RawDict`] constrains only key size in bits. It is useful when a dictionary
72//!   can contain multiple types of values.
73//!
74//! - [`Dict`] is a strongly typed version of definition and is a preferable way
75//!   of working with this data structure. Key type must implement [`DictKey`] trait,
76//!   which is implemented for numbers and addresses.
77//!
78//! - [`AugDict`] adds additional values for all nodes. You can use it to quickly
79//!   access a subtotal of values for each subtree.
80//!   NOTE: this type is partially implemented due to its complexity.
81//!
82//! ## Supported Rust Versions
83//!
84//! This crate is built against the latest stable release. The minimum supported
85//! version is 1.65. The current crate version is not guaranteed to build on
86//! Rust versions earlier than the minimum supported version.
87//!
88//! [`Cell`]: cell::Cell
89//! [`Rc`]: std::rc::Rc
90//! [`Arc`]: std::sync::Arc
91//! [`RcCell`]: prelude::RcCell
92//! [`ArcCell`]: prelude::ArcCell
93//! [`CellSlice`]: cell::CellSlice
94//! [`CellBuilder`]: cell::CellBuilder
95//! [`Cell::as_slice`]: cell::CellImpl::as_slice
96//! [`CellBuilder::build_ext`]: cell::CellBuilder::build_ext
97//! [`CellContext`]: cell::CellContext
98//! [`Boc`]: boc::Boc
99//! [`BocRepr`]: boc::BocRepr
100//! [`UsageTree`]: cell::UsageTree
101//! [`MerkleProof`]: merkle::MerkleProof
102//! [`MerkleUpdate`]: merkle::MerkleUpdate
103//! [`RawDict`]: dict::RawDict
104//! [`Dict`]: dict::Dict
105//! [`DictKey`]: dict::DictKey
106//! [`AugDict`]: dict::AugDict
107//! [`Load`]: cell::Load
108//! [`Store`]: cell::Store
109/// Prevents using `From::from` for plain error conversion.
110macro_rules! ok {
111    ($e:expr $(,)?) => {
112        match $e {
113            core::result::Result::Ok(val) => val,
114            core::result::Result::Err(err) => return core::result::Result::Err(err),
115        }
116    };
117}
118
119#[allow(unused)]
120macro_rules! assert_impl_all {
121    ($type:ty: $($trait:path),+ $(,)?) => {
122        const _: fn() = || {
123            // Only callable when `$type` implements all traits in `$($trait)+`.
124            fn assert_impl_all<T: ?Sized $(+ $trait)+>() {}
125            assert_impl_all::<$type>();
126        };
127    };
128}
129
130extern crate self as everscale_types;
131
132pub mod boc;
133pub mod cell;
134pub mod dict;
135pub mod merkle;
136pub mod num;
137pub mod prelude;
138pub mod util;
139
140#[cfg(feature = "models")]
141pub mod models;
142
143#[cfg(feature = "abi")]
144pub mod abi;
145
146pub mod error;
147
148#[cfg(test)]
149mod tests {
150    use crate::cell::{CellTreeStats, MAX_BIT_LEN};
151    use crate::prelude::*;
152    use crate::util::decode_base64;
153
154    #[test]
155    fn correct_deserialization() {
156        let data = decode_base64("te6ccgEBBAEAzwACg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAIBAEAAAAAAAAAAAAAAAAAAAAAAAAAAm2c6ClpzoTVSAHvzVQGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHKq1w7OAAkYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRwAwBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEljGP8=").unwrap();
157
158        let cell = Boc::decode(&data).unwrap();
159        assert_eq!(
160            cell.repr_hash(),
161            &[
162                0x63, 0xd4, 0x75, 0x13, 0x9a, 0xc1, 0x4f, 0x3e, 0xfe, 0x69, 0x0e, 0xd7, 0xfd, 0x4f,
163                0xf0, 0x02, 0x1c, 0xf2, 0x6b, 0xc4, 0xab, 0xd0, 0xaf, 0x01, 0x40, 0xa3, 0xb4, 0xc8,
164                0x95, 0xf0, 0x73, 0x76
165            ]
166        );
167
168        let serialized = Boc::encode(cell.as_ref());
169        assert_eq!(serialized, data);
170    }
171
172    #[test]
173    fn big_cell_deserialization() {
174        let data = decode_base64("te6ccgIDAAwAAQAAAACIAAAEBAABAAEAAQABAAEEBAACAAIAAgACAAIEBAADAAMAAwADAAMEBAAEAAQABAAEAAQEBAAFAAUABQAFAAUEBAAGAAYABgAGAAYEBAAHAAcABwAHAAcEBAAIAAgACAAIAAgEBAAJAAkACQAJAAkEBAAKAAoACgAKAAoEBAALAAsACwALAAsABAAA").unwrap();
175        let cell = Boc::decode(data).unwrap();
176
177        let stats = cell.compute_unique_stats(1 << 22).unwrap();
178        assert_eq!(
179            stats,
180            CellTreeStats {
181                bit_count: 192,
182                cell_count: 12
183            }
184        );
185    }
186
187    #[test]
188    fn test_builder() -> anyhow::Result<()> {
189        let parsed_cell = Boc::decode_base64("te6ccgEBAQEAAwAAAbE=")?;
190
191        let mut builder = CellBuilder::new();
192        builder.store_bit_one()?;
193        builder.store_bit_zero()?;
194        builder.store_bit_one()?;
195        builder.store_bit_one()?;
196        builder.store_bit_zero()?;
197        builder.store_bit_zero()?;
198        builder.store_bit_zero()?;
199        let built_cell = builder.build()?;
200
201        assert_eq!(parsed_cell.repr_hash(), built_cell.repr_hash());
202
203        let parsed_cell = Boc::decode_base64("te6ccgEBAQEAggAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////")?;
204
205        let mut builder = CellBuilder::new();
206        for _ in 0..MAX_BIT_LEN {
207            builder.store_bit_one()?;
208        }
209        assert!(builder.store_bit_one().is_err());
210        let built_cell = builder.build()?;
211
212        assert_eq!(parsed_cell.repr_hash(), built_cell.repr_hash());
213
214        let mut builder = CellBuilder::new();
215        builder.store_bit_one()?;
216        builder.store_u128(0xaaffaaffaaffaaffaaffaaffaaffaaff)?;
217        let cell = builder.build()?;
218
219        let mut builder = CellBuilder::new();
220        builder.store_bit_one()?;
221        builder.store_u64(0xaaffaaffaaffaaff)?;
222        builder.store_u64(0xaaffaaffaaffaaff)?;
223        assert_eq!(cell.as_ref(), builder.build()?.as_ref());
224
225        let mut builder = CellBuilder::new();
226        builder.store_zeros(1020)?;
227        builder.store_small_uint(0x5, 3)?;
228        builder.build()?;
229
230        let mut builder = CellBuilder::new();
231        builder.store_small_uint(5, 3)?;
232        builder.store_u256(HashBytes::wrap(&[
233            0xdf, 0x86, 0xce, 0xbc, 0xe8, 0xd5, 0xab, 0x0c, 0x69, 0xb4, 0xce, 0x33, 0xfe, 0x9b,
234            0x0e, 0x2c, 0xdf, 0x69, 0xa3, 0xe1, 0x13, 0x7e, 0x64, 0x85, 0x6b, 0xbc, 0xfd, 0x39,
235            0xe7, 0x9b, 0xc1, 0x6f,
236        ]))?;
237        let cell = builder.build()?;
238
239        let target_cell =
240            Boc::decode_base64("te6ccgEBAQEAIwAAQbvw2dedGrVhjTaZxn/TYcWb7TR8Im/MkK13n6c883gt8A==")?;
241        assert_eq!(cell.as_ref(), target_cell.as_ref());
242
243        let mut builder = CellBuilder::new();
244        builder.store_zeros(3)?;
245        builder.store_raw(&[0xdd, 0x55], 10)?;
246        builder.store_reference(target_cell)?;
247        builder.store_reference(cell)?;
248        let cell = builder.build()?;
249
250        let mut builder = CellBuilder::new();
251        builder.store_slice(cell.as_slice()?)?;
252        let cell = builder.build()?;
253        println!("{}", cell.display_tree());
254
255        Ok(())
256    }
257
258    #[test]
259    fn test_tx() {
260        let cell = Boc::decode_base64("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").unwrap();
261
262        let stats = cell.compute_unique_stats(1 << 22).unwrap();
263        assert_eq!(
264            stats,
265            CellTreeStats {
266                bit_count: 4681,
267                cell_count: 266
268            }
269        );
270    }
271}