spl_account_compression/
concurrent_tree_wrapper.rs

1//! This module provides a wrapper around the `ConcurrentMerkleTree` struct from
2//! the `spl_concurrent_merkle_tree` crate. It provides a set of functions that
3//! can be called from the Anchor program to interact with the tree.
4//! The functions are used to initialize the tree, set a leaf, fill empty or
5//! append a leaf, and prove a leaf. As the tree is generic over the depth and
6//! buffer size, the functions are implemented using macros that infer the depth
7//! and buffer size from the header information stored on-chain. Usage of the
8//! macros directly is discouraged, as they have huge match statements with
9//! every case taking it's own stack frame. Instead, use the exported functions
10//! from this module and refenrece or Box the arguments to the functions to
11//! avoid the stack frame explosion.
12
13pub use crate::error::AccountCompressionError;
14/// Exported for Anchor / Solita
15pub use spl_concurrent_merkle_tree::{
16    concurrent_merkle_tree::{
17        ConcurrentMerkleTree, FillEmptyOrAppendArgs, InitializeWithRootArgs, ProveLeafArgs,
18        SetLeafArgs,
19    },
20    error::ConcurrentMerkleTreeError,
21    node::Node,
22    node::EMPTY,
23};
24use {
25    crate::{
26        events::ChangeLogEvent, macros::*, state::ConcurrentMerkleTreeHeader, zero_copy::ZeroCopy,
27    },
28    anchor_lang::prelude::*,
29};
30
31#[inline(never)]
32pub fn merkle_tree_initialize_empty(
33    header: &ConcurrentMerkleTreeHeader,
34    tree_id: Pubkey,
35    tree_bytes: &mut [u8],
36) -> Result<Box<ChangeLogEvent>> {
37    merkle_tree_apply_fn_mut!(header, tree_id, tree_bytes, initialize,)
38}
39
40#[inline(never)]
41pub fn merkle_tree_initialize_with_root(
42    header: &ConcurrentMerkleTreeHeader,
43    tree_id: Pubkey,
44    tree_bytes: &mut [u8],
45    args: &InitializeWithRootArgs,
46) -> Result<Box<ChangeLogEvent>> {
47    merkle_tree_apply_fn_mut!(header, tree_id, tree_bytes, initialize_with_root, args)
48}
49
50#[inline(never)]
51pub fn merkle_tree_set_leaf(
52    header: &ConcurrentMerkleTreeHeader,
53    tree_id: Pubkey,
54    tree_bytes: &mut [u8],
55    args: &SetLeafArgs,
56) -> Result<Box<ChangeLogEvent>> {
57    merkle_tree_apply_fn_mut!(header, tree_id, tree_bytes, set_leaf, args)
58}
59
60#[inline(never)]
61pub fn merkle_tree_fill_empty_or_append(
62    header: &ConcurrentMerkleTreeHeader,
63    tree_id: Pubkey,
64    tree_bytes: &mut [u8],
65    args: &FillEmptyOrAppendArgs,
66) -> Result<Box<ChangeLogEvent>> {
67    merkle_tree_apply_fn_mut!(header, tree_id, tree_bytes, fill_empty_or_append, args)
68}
69
70#[inline(never)]
71pub fn merkle_tree_prove_leaf(
72    header: &ConcurrentMerkleTreeHeader,
73    tree_id: Pubkey,
74    tree_bytes: &[u8],
75    args: &ProveLeafArgs,
76) -> Result<Box<ChangeLogEvent>> {
77    merkle_tree_apply_fn!(header, tree_id, tree_bytes, prove_leaf, args)
78}
79
80#[inline(never)]
81pub fn merkle_tree_append_leaf(
82    header: &ConcurrentMerkleTreeHeader,
83    tree_id: Pubkey,
84    tree_bytes: &mut [u8],
85    args: &[u8; 32],
86) -> Result<Box<ChangeLogEvent>> {
87    merkle_tree_apply_fn_mut!(header, tree_id, tree_bytes, append, *args)
88}
89
90#[inline(never)]
91pub fn merkle_tree_prove_tree_is_empty(
92    header: &ConcurrentMerkleTreeHeader,
93    tree_id: Pubkey,
94    tree_bytes: &mut [u8],
95) -> Result<Box<ChangeLogEvent>> {
96    merkle_tree_apply_fn_mut!(header, tree_id, tree_bytes, prove_tree_is_empty,)
97}