@@ -27,11 +27,12 @@ use anchor_lang::{
27
27
solana_program:: sysvar:: { clock:: Clock , rent:: Rent } ,
28
28
} ;
29
29
use borsh:: { BorshDeserialize , BorshSerialize } ;
30
- use std:: mem:: size_of;
31
30
32
31
pub mod canopy;
33
32
pub mod error;
34
33
pub mod events;
34
+ #[ macro_use]
35
+ pub mod macros;
35
36
mod noop;
36
37
pub mod state;
37
38
pub mod zero_copy;
@@ -42,7 +43,9 @@ use crate::canopy::{fill_in_proof_from_canopy, update_canopy};
42
43
use crate :: error:: AccountCompressionError ;
43
44
use crate :: events:: { AccountCompressionEvent , ChangeLogEvent } ;
44
45
use crate :: noop:: wrap_event;
45
- use crate :: state:: { ConcurrentMerkleTreeHeader , CONCURRENT_MERKLE_TREE_HEADER_SIZE_V1 } ;
46
+ use crate :: state:: {
47
+ merkle_tree_get_size, ConcurrentMerkleTreeHeader , CONCURRENT_MERKLE_TREE_HEADER_SIZE_V1 ,
48
+ } ;
46
49
use crate :: zero_copy:: ZeroCopy ;
47
50
48
51
/// Exported for Anchor / Solita
@@ -120,111 +123,6 @@ pub struct CloseTree<'info> {
120
123
pub recipient : AccountInfo < ' info > ,
121
124
}
122
125
123
- /// This macro applies functions on a ConcurrentMerkleT:ee and emits leaf information
124
- /// needed to sync the merkle tree state with off-chain indexers.
125
- macro_rules! merkle_tree_depth_size_apply_fn {
126
- ( $max_depth: literal, $max_size: literal, $id: ident, $bytes: ident, $func: ident, $( $arg: tt) * ) => {
127
- match ConcurrentMerkleTree :: <$max_depth, $max_size>:: load_mut_bytes( $bytes) {
128
- Ok ( merkle_tree) => {
129
- match merkle_tree. $func( $( $arg) * ) {
130
- Ok ( _) => {
131
- Ok ( Box :: <ChangeLogEvent >:: from( ( merkle_tree. get_change_log( ) , $id, merkle_tree. sequence_number) ) )
132
- }
133
- Err ( err) => {
134
- msg!( "Error using concurrent merkle tree: {}" , err) ;
135
- err!( AccountCompressionError :: ConcurrentMerkleTreeError )
136
- }
137
- }
138
- }
139
- Err ( err) => {
140
- msg!( "Error zero copying concurrent merkle tree: {}" , err) ;
141
- err!( AccountCompressionError :: ZeroCopyError )
142
- }
143
- }
144
- }
145
- }
146
-
147
- fn merkle_tree_get_size ( header : & ConcurrentMerkleTreeHeader ) -> Result < usize > {
148
- // Note: max_buffer_size MUST be a power of 2
149
- match ( header. get_max_depth ( ) , header. get_max_buffer_size ( ) ) {
150
- ( 3 , 8 ) => Ok ( size_of :: < ConcurrentMerkleTree < 3 , 8 > > ( ) ) ,
151
- ( 5 , 8 ) => Ok ( size_of :: < ConcurrentMerkleTree < 5 , 8 > > ( ) ) ,
152
- ( 14 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 14 , 64 > > ( ) ) ,
153
- ( 14 , 256 ) => Ok ( size_of :: < ConcurrentMerkleTree < 14 , 256 > > ( ) ) ,
154
- ( 14 , 1024 ) => Ok ( size_of :: < ConcurrentMerkleTree < 14 , 1024 > > ( ) ) ,
155
- ( 14 , 2048 ) => Ok ( size_of :: < ConcurrentMerkleTree < 14 , 2048 > > ( ) ) ,
156
- ( 15 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 15 , 64 > > ( ) ) ,
157
- ( 16 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 16 , 64 > > ( ) ) ,
158
- ( 17 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 17 , 64 > > ( ) ) ,
159
- ( 18 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 18 , 64 > > ( ) ) ,
160
- ( 19 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 19 , 64 > > ( ) ) ,
161
- ( 20 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 20 , 64 > > ( ) ) ,
162
- ( 20 , 256 ) => Ok ( size_of :: < ConcurrentMerkleTree < 20 , 256 > > ( ) ) ,
163
- ( 20 , 1024 ) => Ok ( size_of :: < ConcurrentMerkleTree < 20 , 1024 > > ( ) ) ,
164
- ( 20 , 2048 ) => Ok ( size_of :: < ConcurrentMerkleTree < 20 , 2048 > > ( ) ) ,
165
- ( 24 , 64 ) => Ok ( size_of :: < ConcurrentMerkleTree < 24 , 64 > > ( ) ) ,
166
- ( 24 , 256 ) => Ok ( size_of :: < ConcurrentMerkleTree < 24 , 256 > > ( ) ) ,
167
- ( 24 , 512 ) => Ok ( size_of :: < ConcurrentMerkleTree < 24 , 512 > > ( ) ) ,
168
- ( 24 , 1024 ) => Ok ( size_of :: < ConcurrentMerkleTree < 24 , 1024 > > ( ) ) ,
169
- ( 24 , 2048 ) => Ok ( size_of :: < ConcurrentMerkleTree < 24 , 2048 > > ( ) ) ,
170
- ( 26 , 512 ) => Ok ( size_of :: < ConcurrentMerkleTree < 26 , 512 > > ( ) ) ,
171
- ( 26 , 1024 ) => Ok ( size_of :: < ConcurrentMerkleTree < 26 , 1024 > > ( ) ) ,
172
- ( 26 , 2048 ) => Ok ( size_of :: < ConcurrentMerkleTree < 26 , 2048 > > ( ) ) ,
173
- ( 30 , 512 ) => Ok ( size_of :: < ConcurrentMerkleTree < 30 , 512 > > ( ) ) ,
174
- ( 30 , 1024 ) => Ok ( size_of :: < ConcurrentMerkleTree < 30 , 1024 > > ( ) ) ,
175
- ( 30 , 2048 ) => Ok ( size_of :: < ConcurrentMerkleTree < 30 , 2048 > > ( ) ) ,
176
- _ => {
177
- msg ! (
178
- "Failed to get size of max depth {} and max buffer size {}" ,
179
- header. get_max_depth( ) ,
180
- header. get_max_buffer_size( )
181
- ) ;
182
- err ! ( AccountCompressionError :: ConcurrentMerkleTreeConstantsError )
183
- }
184
- }
185
- }
186
-
187
- /// This applies a given function on a ConcurrentMerkleTree by
188
- /// allowing the compiler to infer the size of the tree based
189
- /// upon the header information stored on-chain
190
- macro_rules! merkle_tree_apply_fn {
191
- ( $header: ident, $id: ident, $bytes: ident, $func: ident, $( $arg: tt) * ) => {
192
- // Note: max_buffer_size MUST be a power of 2
193
- match ( $header. get_max_depth( ) , $header. get_max_buffer_size( ) ) {
194
- ( 3 , 8 ) => merkle_tree_depth_size_apply_fn!( 3 , 8 , $id, $bytes, $func, $( $arg) * ) ,
195
- ( 5 , 8 ) => merkle_tree_depth_size_apply_fn!( 5 , 8 , $id, $bytes, $func, $( $arg) * ) ,
196
- ( 14 , 64 ) => merkle_tree_depth_size_apply_fn!( 14 , 64 , $id, $bytes, $func, $( $arg) * ) ,
197
- ( 14 , 256 ) => merkle_tree_depth_size_apply_fn!( 14 , 256 , $id, $bytes, $func, $( $arg) * ) ,
198
- ( 14 , 1024 ) => merkle_tree_depth_size_apply_fn!( 14 , 1024 , $id, $bytes, $func, $( $arg) * ) ,
199
- ( 14 , 2048 ) => merkle_tree_depth_size_apply_fn!( 14 , 2048 , $id, $bytes, $func, $( $arg) * ) ,
200
- ( 15 , 64 ) => merkle_tree_depth_size_apply_fn!( 15 , 64 , $id, $bytes, $func, $( $arg) * ) ,
201
- ( 16 , 64 ) => merkle_tree_depth_size_apply_fn!( 16 , 64 , $id, $bytes, $func, $( $arg) * ) ,
202
- ( 17 , 64 ) => merkle_tree_depth_size_apply_fn!( 17 , 64 , $id, $bytes, $func, $( $arg) * ) ,
203
- ( 18 , 64 ) => merkle_tree_depth_size_apply_fn!( 18 , 64 , $id, $bytes, $func, $( $arg) * ) ,
204
- ( 19 , 64 ) => merkle_tree_depth_size_apply_fn!( 19 , 64 , $id, $bytes, $func, $( $arg) * ) ,
205
- ( 20 , 64 ) => merkle_tree_depth_size_apply_fn!( 20 , 64 , $id, $bytes, $func, $( $arg) * ) ,
206
- ( 20 , 256 ) => merkle_tree_depth_size_apply_fn!( 20 , 256 , $id, $bytes, $func, $( $arg) * ) ,
207
- ( 20 , 1024 ) => merkle_tree_depth_size_apply_fn!( 20 , 1024 , $id, $bytes, $func, $( $arg) * ) ,
208
- ( 20 , 2048 ) => merkle_tree_depth_size_apply_fn!( 20 , 2048 , $id, $bytes, $func, $( $arg) * ) ,
209
- ( 24 , 64 ) => merkle_tree_depth_size_apply_fn!( 24 , 64 , $id, $bytes, $func, $( $arg) * ) ,
210
- ( 24 , 256 ) => merkle_tree_depth_size_apply_fn!( 24 , 256 , $id, $bytes, $func, $( $arg) * ) ,
211
- ( 24 , 512 ) => merkle_tree_depth_size_apply_fn!( 24 , 512 , $id, $bytes, $func, $( $arg) * ) ,
212
- ( 24 , 1024 ) => merkle_tree_depth_size_apply_fn!( 24 , 1024 , $id, $bytes, $func, $( $arg) * ) ,
213
- ( 24 , 2048 ) => merkle_tree_depth_size_apply_fn!( 24 , 2048 , $id, $bytes, $func, $( $arg) * ) ,
214
- ( 26 , 512 ) => merkle_tree_depth_size_apply_fn!( 26 , 512 , $id, $bytes, $func, $( $arg) * ) ,
215
- ( 26 , 1024 ) => merkle_tree_depth_size_apply_fn!( 26 , 1024 , $id, $bytes, $func, $( $arg) * ) ,
216
- ( 26 , 2048 ) => merkle_tree_depth_size_apply_fn!( 26 , 2048 , $id, $bytes, $func, $( $arg) * ) ,
217
- ( 30 , 512 ) => merkle_tree_depth_size_apply_fn!( 30 , 512 , $id, $bytes, $func, $( $arg) * ) ,
218
- ( 30 , 1024 ) => merkle_tree_depth_size_apply_fn!( 30 , 1024 , $id, $bytes, $func, $( $arg) * ) ,
219
- ( 30 , 2048 ) => merkle_tree_depth_size_apply_fn!( 30 , 2048 , $id, $bytes, $func, $( $arg) * ) ,
220
- _ => {
221
- msg!( "Failed to apply {} on concurrent merkle tree with max depth {} and max buffer size {}" , stringify!( $func) , $header. get_max_depth( ) , $header. get_max_buffer_size( ) ) ;
222
- err!( AccountCompressionError :: ConcurrentMerkleTreeConstantsError )
223
- }
224
- }
225
- } ;
226
- }
227
-
228
126
#[ program]
229
127
pub mod spl_account_compression {
230
128
use super :: * ;
@@ -267,7 +165,7 @@ pub mod spl_account_compression {
267
165
let merkle_tree_size = merkle_tree_get_size ( & header) ?;
268
166
let ( tree_bytes, canopy_bytes) = rest. split_at_mut ( merkle_tree_size) ;
269
167
let id = ctx. accounts . merkle_tree . key ( ) ;
270
- let change_log_event = merkle_tree_apply_fn ! ( header, id, tree_bytes, initialize, ) ?;
168
+ let change_log_event = merkle_tree_apply_fn_mut ! ( header, id, tree_bytes, initialize, ) ?;
271
169
wrap_event (
272
170
& AccountCompressionEvent :: ChangeLog ( * change_log_event) ,
273
171
& ctx. accounts . noop ,
@@ -372,7 +270,7 @@ pub mod spl_account_compression {
372
270
fill_in_proof_from_canopy ( canopy_bytes, header. get_max_depth ( ) , index, & mut proof) ?;
373
271
let id = ctx. accounts . merkle_tree . key ( ) ;
374
272
// A call is made to ConcurrentMerkleTree::set_leaf(root, previous_leaf, new_leaf, proof, index)
375
- let change_log_event = merkle_tree_apply_fn ! (
273
+ let change_log_event = merkle_tree_apply_fn_mut ! (
376
274
header,
377
275
id,
378
276
tree_bytes,
@@ -431,16 +329,16 @@ pub mod spl_account_compression {
431
329
crate :: id( ) ,
432
330
AccountCompressionError :: IncorrectAccountOwner
433
331
) ;
434
- let mut merkle_tree_bytes = ctx. accounts . merkle_tree . try_borrow_mut_data ( ) ?;
332
+ let merkle_tree_bytes = ctx. accounts . merkle_tree . try_borrow_data ( ) ?;
435
333
let ( header_bytes, rest) =
436
- merkle_tree_bytes. split_at_mut ( CONCURRENT_MERKLE_TREE_HEADER_SIZE_V1 ) ;
334
+ merkle_tree_bytes. split_at ( CONCURRENT_MERKLE_TREE_HEADER_SIZE_V1 ) ;
437
335
438
336
let header = ConcurrentMerkleTreeHeader :: try_from_slice ( header_bytes) ?;
439
337
header. assert_valid ( ) ?;
440
338
header. assert_valid_leaf_index ( index) ?;
441
339
442
340
let merkle_tree_size = merkle_tree_get_size ( & header) ?;
443
- let ( tree_bytes, canopy_bytes) = rest. split_at_mut ( merkle_tree_size) ;
341
+ let ( tree_bytes, canopy_bytes) = rest. split_at ( merkle_tree_size) ;
444
342
445
343
let mut proof = vec ! [ ] ;
446
344
for node in ctx. remaining_accounts . iter ( ) {
@@ -475,7 +373,7 @@ pub mod spl_account_compression {
475
373
let id = ctx. accounts . merkle_tree . key ( ) ;
476
374
let merkle_tree_size = merkle_tree_get_size ( & header) ?;
477
375
let ( tree_bytes, canopy_bytes) = rest. split_at_mut ( merkle_tree_size) ;
478
- let change_log_event = merkle_tree_apply_fn ! ( header, id, tree_bytes, append, leaf) ?;
376
+ let change_log_event = merkle_tree_apply_fn_mut ! ( header, id, tree_bytes, append, leaf) ?;
479
377
update_canopy (
480
378
canopy_bytes,
481
379
header. get_max_depth ( ) ,
@@ -520,7 +418,7 @@ pub mod spl_account_compression {
520
418
fill_in_proof_from_canopy ( canopy_bytes, header. get_max_depth ( ) , index, & mut proof) ?;
521
419
// A call is made to ConcurrentMerkleTree::fill_empty_or_append
522
420
let id = ctx. accounts . merkle_tree . key ( ) ;
523
- let change_log_event = merkle_tree_apply_fn ! (
421
+ let change_log_event = merkle_tree_apply_fn_mut ! (
524
422
header,
525
423
id,
526
424
tree_bytes,
@@ -558,7 +456,7 @@ pub mod spl_account_compression {
558
456
let ( tree_bytes, canopy_bytes) = rest. split_at_mut ( merkle_tree_size) ;
559
457
560
458
let id = ctx. accounts . merkle_tree . key ( ) ;
561
- merkle_tree_apply_fn ! ( header, id, tree_bytes, prove_tree_is_empty, ) ?;
459
+ merkle_tree_apply_fn_mut ! ( header, id, tree_bytes, prove_tree_is_empty, ) ?;
562
460
563
461
// Close merkle tree account
564
462
// 1. Move lamports
0 commit comments