spl_account_compression/
macros.rs

1#[allow(dead_code)]
2enum TreeLoad {
3    Immutable,
4    Mutable,
5}
6
7/// This macro applies functions on a ConcurrentMerkleT:ee and emits leaf
8/// information needed to sync the merkle tree state with off-chain indexers.
9#[macro_export]
10macro_rules! _merkle_tree_depth_size_apply_fn {
11    ($max_depth:literal, $max_size:literal, $id:ident, $bytes:ident, $func:ident, TreeLoad::Mutable, $($arg:tt)*)
12     => {
13        match ConcurrentMerkleTree::<$max_depth, $max_size>::load_mut_bytes($bytes) {
14            Ok(merkle_tree) => {
15                match merkle_tree.$func($($arg)*) {
16                    Ok(_) => {
17                        Ok(Box::<ChangeLogEvent>::from((merkle_tree.get_change_log(), $id, merkle_tree.sequence_number)))
18                    }
19                    Err(err) => {
20                        msg!("Error using concurrent merkle tree: {}", err);
21                        err!(AccountCompressionError::ConcurrentMerkleTreeError)
22                    }
23                }
24            }
25            Err(err) => {
26                msg!("Error zero copying concurrent merkle tree: {}", err);
27                err!(AccountCompressionError::ZeroCopyError)
28            }
29        }
30    };
31    ($max_depth:literal, $max_size:literal, $id:ident, $bytes:ident, $func:ident, TreeLoad::Immutable, $($arg:tt)*) => {
32        match ConcurrentMerkleTree::<$max_depth, $max_size>::load_bytes($bytes) {
33            Ok(merkle_tree) => {
34                match merkle_tree.$func($($arg)*) {
35                    Ok(_) => {
36                        Ok(Box::<ChangeLogEvent>::from((merkle_tree.get_change_log(), $id, merkle_tree.sequence_number)))
37                    }
38                    Err(err) => {
39                        msg!("Error using concurrent merkle tree: {}", err);
40                        err!(AccountCompressionError::ConcurrentMerkleTreeError)
41                    }
42                }
43            }
44            Err(err) => {
45                msg!("Error zero copying concurrent merkle tree: {}", err);
46                err!(AccountCompressionError::ZeroCopyError)
47            }
48        }
49    };
50}
51
52/// This applies a given function on a ConcurrentMerkleTree by
53/// allowing the compiler to infer the size of the tree based
54/// upon the header information stored on-chain
55#[macro_export]
56macro_rules! _merkle_tree_apply_fn {
57    ($header:ident, $($arg:tt)*) => {
58        // Note: max_buffer_size MUST be a power of 2
59        match ($header.get_max_depth(), $header.get_max_buffer_size()) {
60            (3, 8) => _merkle_tree_depth_size_apply_fn!(3, 8, $($arg)*),
61            (5, 8) => _merkle_tree_depth_size_apply_fn!(5, 8, $($arg)*),
62            (6, 16) => _merkle_tree_depth_size_apply_fn!(6, 16, $($arg)*),
63            (7, 16) => _merkle_tree_depth_size_apply_fn!(7, 16, $($arg)*),
64            (8, 16) => _merkle_tree_depth_size_apply_fn!(8, 16, $($arg)*),
65            (9, 16) => _merkle_tree_depth_size_apply_fn!(9, 16, $($arg)*),
66            (10, 32) => _merkle_tree_depth_size_apply_fn!(10, 32, $($arg)*),
67            (11, 32) => _merkle_tree_depth_size_apply_fn!(11, 32, $($arg)*),
68            (12, 32) => _merkle_tree_depth_size_apply_fn!(12, 32, $($arg)*),
69            (13, 32) => _merkle_tree_depth_size_apply_fn!(13, 32, $($arg)*),
70            (14, 64) => _merkle_tree_depth_size_apply_fn!(14, 64, $($arg)*),
71            (14, 256) => _merkle_tree_depth_size_apply_fn!(14, 256, $($arg)*),
72            (14, 1024) => _merkle_tree_depth_size_apply_fn!(14, 1024, $($arg)*),
73            (14, 2048) => _merkle_tree_depth_size_apply_fn!(14, 2048, $($arg)*),
74            (15, 64) => _merkle_tree_depth_size_apply_fn!(15, 64, $($arg)*),
75            (16, 64) => _merkle_tree_depth_size_apply_fn!(16, 64, $($arg)*),
76            (17, 64) => _merkle_tree_depth_size_apply_fn!(17, 64, $($arg)*),
77            (18, 64) => _merkle_tree_depth_size_apply_fn!(18, 64, $($arg)*),
78            (19, 64) => _merkle_tree_depth_size_apply_fn!(19, 64, $($arg)*),
79            (20, 64) => _merkle_tree_depth_size_apply_fn!(20, 64, $($arg)*),
80            (20, 256) => _merkle_tree_depth_size_apply_fn!(20, 256, $($arg)*),
81            (20, 1024) => _merkle_tree_depth_size_apply_fn!(20, 1024, $($arg)*),
82            (20, 2048) => _merkle_tree_depth_size_apply_fn!(20, 2048, $($arg)*),
83            (24, 64) => _merkle_tree_depth_size_apply_fn!(24, 64, $($arg)*),
84            (24, 256) => _merkle_tree_depth_size_apply_fn!(24, 256, $($arg)*),
85            (24, 512) => _merkle_tree_depth_size_apply_fn!(24, 512, $($arg)*),
86            (24, 1024) => _merkle_tree_depth_size_apply_fn!(24, 1024, $($arg)*),
87            (24, 2048) => _merkle_tree_depth_size_apply_fn!(24, 2048, $($arg)*),
88            (26, 512) => _merkle_tree_depth_size_apply_fn!(26, 512, $($arg)*),
89            (26, 1024) => _merkle_tree_depth_size_apply_fn!(26, 1024, $($arg)*),
90            (26, 2048) => _merkle_tree_depth_size_apply_fn!(26, 2048, $($arg)*),
91            (30, 512) => _merkle_tree_depth_size_apply_fn!(30, 512, $($arg)*),
92            (30, 1024) => _merkle_tree_depth_size_apply_fn!(30, 1024, $($arg)*),
93            (30, 2048) => _merkle_tree_depth_size_apply_fn!(30, 2048, $($arg)*),
94            _ => {
95                msg!("Failed to apply {} on concurrent merkle tree with max depth {} and max buffer size {}",
96                    stringify!($func),
97                    $header.get_max_depth(),
98                    $header.get_max_buffer_size()
99                );
100                err!(AccountCompressionError::ConcurrentMerkleTreeConstantsError)
101            }
102        }
103    };
104}
105
106/// This applies a given function on a mutable ConcurrentMerkleTree
107#[macro_export]
108macro_rules! merkle_tree_apply_fn_mut {
109    ($header:ident, $id:ident, $bytes:ident, $func:ident, $($arg:tt)*) => {
110        _merkle_tree_apply_fn!($header, $id, $bytes, $func, TreeLoad::Mutable, $($arg)*)
111    };
112}
113
114/// This applies a given function on a read-only ConcurrentMerkleTree
115#[macro_export]
116macro_rules! merkle_tree_apply_fn {
117    ($header:ident, $id:ident, $bytes:ident, $func:ident, $($arg:tt)*) => {
118        _merkle_tree_apply_fn!($header, $id, $bytes, $func, TreeLoad::Immutable, $($arg)*)
119    };
120}
121
122pub(crate) use {
123    _merkle_tree_apply_fn, _merkle_tree_depth_size_apply_fn, merkle_tree_apply_fn,
124    merkle_tree_apply_fn_mut,
125};