Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit dad3fba

Browse files
authored
Account Compression: Version ChangeLog + Test (#3632)
* AC: export idl in SDK, add cmt helper functions * AC: remove unnecessary events, emit statements * AC: update noop program id * AC: make events a typed struct (remove anchor event attr) * AC: update AC program id, only emit events via cpi * AC: update TS sdk * AC: add event tests * AC: update Anchor.toml * AC: remove old program ids
1 parent 7fdb082 commit dad3fba

35 files changed

+713
-312
lines changed

account-compression/Anchor.toml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
[programs.localnet]
2-
spl_account_compression = "GRoLLzvxpxxu2PGNJMMeZPyMxjAUH9pKqxGXV9DGiceU"
3-
4-
[programs.testnet]
5-
spl_account_compression = "GRoLLMza82AiYN7W9S9KCCtCyyPRAQP2ifBy4v4D5RMD"
2+
spl_account_compression = "cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK"
63

74
[[test.genesis]]
8-
address = "WRAPYChf58WFCnyjXKJHtrPgzKXgHp6MD9aVDqJBbGh"
5+
address = "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV"
96
program = "./target/deploy/wrapper.so"
107

118
[registry]

account-compression/programs/account-compression/src/canopy.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,20 @@ fn get_cached_path_length(canopy: &mut [Node], max_depth: u32) -> Result<u32> {
6969
pub fn update_canopy(
7070
canopy_bytes: &mut [u8],
7171
max_depth: u32,
72-
change_log: Option<Box<ChangeLogEvent>>,
72+
change_log: Option<&ChangeLogEvent>,
7373
) -> Result<()> {
7474
check_canopy_bytes(canopy_bytes)?;
7575
let canopy = cast_slice_mut::<u8, Node>(canopy_bytes);
7676
let path_len = get_cached_path_length(canopy, max_depth)?;
77-
if let Some(cl) = change_log {
78-
// Update the canopy from the newest change log
79-
for path_node in cl.path.iter().rev().skip(1).take(path_len as usize) {
80-
// node_idx - 2 maps to the canopy index
81-
canopy[(path_node.index - 2) as usize] = path_node.node;
77+
if let Some(cl_event) = change_log {
78+
match &*cl_event {
79+
ChangeLogEvent::V1(cl) => {
80+
// Update the canopy from the newest change log
81+
for path_node in cl.path.iter().rev().skip(1).take(path_len as usize) {
82+
// node_idx - 2 maps to the canopy index
83+
canopy[(path_node.index - 2) as usize] = path_node.node;
84+
}
85+
}
8286
}
8387
}
8488
Ok(())

account-compression/programs/account-compression/src/data_wrapper/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//! vital to the functioning of compression. When compression logs are truncated, indexers can fallback to
88
//! deserializing the CPI instruction data.
99
10+
use crate::events::AccountCompressionEvent;
1011
use anchor_lang::{prelude::*, solana_program::program::invoke};
1112

1213
#[derive(Clone)]
@@ -19,11 +20,11 @@ impl anchor_lang::Id for Wrapper {
1920
}
2021

2122
pub fn wrap_event<'info>(
22-
data: Vec<u8>,
23+
event: &AccountCompressionEvent,
2324
log_wrapper_program: &Program<'info, Wrapper>,
2425
) -> Result<()> {
2526
invoke(
26-
&spl_noop::instruction(data),
27+
&spl_noop::instruction(event.try_to_vec()?),
2728
&[log_wrapper_program.to_account_info()],
2829
)?;
2930
Ok(())

account-compression/programs/account-compression/src/events/changelog_event.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
use crate::state::PathNode;
2+
23
use anchor_lang::prelude::*;
34
use spl_concurrent_merkle_tree::changelog::ChangeLog;
45

5-
#[event]
6-
pub struct ChangeLogEvent {
6+
#[derive(AnchorDeserialize, AnchorSerialize)]
7+
#[repr(C)]
8+
pub enum ChangeLogEvent {
9+
V1(ChangeLogEventV1),
10+
}
11+
12+
#[derive(AnchorDeserialize, AnchorSerialize)]
13+
pub struct ChangeLogEventV1 {
714
/// Public key of the ConcurrentMerkleTree
815
pub id: Pubkey,
916

@@ -36,11 +43,11 @@ impl<const MAX_DEPTH: usize> From<(Box<ChangeLog<MAX_DEPTH>>, Pubkey, u64)>
3643
})
3744
.collect();
3845
path.push(PathNode::new(changelog.root, 1));
39-
Box::new(ChangeLogEvent {
46+
Box::new(ChangeLogEvent::V1(ChangeLogEventV1 {
4047
id: tree_id,
4148
path,
4249
seq,
4350
index: changelog.index,
44-
})
51+
}))
4552
}
4653
}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
//! Anchor events are used to emit information necessary to
22
//! index changes made to a SPL ConcurrentMerkleTree
3+
4+
use anchor_lang::prelude::*;
5+
36
mod changelog_event;
4-
mod new_leaf_event;
57

68
pub use changelog_event::ChangeLogEvent;
7-
pub use new_leaf_event::NewLeafEvent;
9+
10+
#[derive(AnchorDeserialize, AnchorSerialize)]
11+
#[repr(C)]
12+
pub enum AccountCompressionEvent {
13+
ChangeLog(ChangeLogEvent),
14+
}

account-compression/programs/account-compression/src/events/new_leaf_event.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.

account-compression/programs/account-compression/src/lib.rs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
//! A production-ready indexer (Plerkle) can be found in the [Metaplex program library](https://github.com/metaplex-foundation/digital-asset-validator-plugin)
2424
2525
use anchor_lang::{
26-
emit,
2726
prelude::*,
2827
solana_program::sysvar::{clock::Clock, rent::Rent},
2928
};
@@ -40,7 +39,7 @@ pub mod zero_copy;
4039
use crate::canopy::{fill_in_proof_from_canopy, update_canopy};
4140
use crate::data_wrapper::{wrap_event, Wrapper};
4241
use crate::error::AccountCompressionError;
43-
use crate::events::ChangeLogEvent;
42+
use crate::events::{AccountCompressionEvent, ChangeLogEvent};
4443
use crate::state::{ConcurrentMerkleTreeHeader, CONCURRENT_MERKLE_TREE_HEADER_SIZE_V1};
4544
use crate::zero_copy::ZeroCopy;
4645

@@ -49,7 +48,7 @@ pub use spl_concurrent_merkle_tree::{
4948
concurrent_merkle_tree::ConcurrentMerkleTree, error::ConcurrentMerkleTreeError, node::Node,
5049
};
5150

52-
declare_id!("GRoLLzvxpxxu2PGNJMMeZPyMxjAUH9pKqxGXV9DGiceU");
51+
declare_id!("cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK");
5352

5453
/// Context for initializing a new SPL ConcurrentMerkleTree
5554
#[derive(Accounts)]
@@ -243,9 +242,11 @@ pub mod spl_account_compression {
243242
let merkle_tree_size = merkle_tree_get_size(&header)?;
244243
let (tree_bytes, canopy_bytes) = rest.split_at_mut(merkle_tree_size);
245244
let id = ctx.accounts.merkle_tree.key();
246-
let change_log = merkle_tree_apply_fn!(header, id, tree_bytes, initialize,)?;
247-
wrap_event(change_log.try_to_vec()?, &ctx.accounts.log_wrapper)?;
248-
emit!(*change_log);
245+
let change_log_event = merkle_tree_apply_fn!(header, id, tree_bytes, initialize,)?;
246+
wrap_event(
247+
&AccountCompressionEvent::ChangeLog(*change_log_event),
248+
&ctx.accounts.log_wrapper,
249+
)?;
249250
update_canopy(canopy_bytes, header.get_max_depth(), None)
250251
}
251252

@@ -310,7 +311,6 @@ pub mod spl_account_compression {
310311
// index
311312
// )?;
312313
// wrap_event(change_log.try_to_vec()?, &ctx.accounts.log_wrapper)?;
313-
// emit!(*change_log);
314314
// update_canopy(canopy_bytes, header.max_depth, Some(change_log))
315315
// }
316316

@@ -346,7 +346,7 @@ pub mod spl_account_compression {
346346
fill_in_proof_from_canopy(canopy_bytes, header.get_max_depth(), index, &mut proof)?;
347347
let id = ctx.accounts.merkle_tree.key();
348348
// A call is made to ConcurrentMerkleTree::set_leaf(root, previous_leaf, new_leaf, proof, index)
349-
let change_log = merkle_tree_apply_fn!(
349+
let change_log_event = merkle_tree_apply_fn!(
350350
header,
351351
id,
352352
tree_bytes,
@@ -357,9 +357,15 @@ pub mod spl_account_compression {
357357
&proof,
358358
index,
359359
)?;
360-
wrap_event(change_log.try_to_vec()?, &ctx.accounts.log_wrapper)?;
361-
emit!(*change_log);
362-
update_canopy(canopy_bytes, header.get_max_depth(), Some(change_log))
360+
update_canopy(
361+
canopy_bytes,
362+
header.get_max_depth(),
363+
Some(&change_log_event),
364+
)?;
365+
wrap_event(
366+
&AccountCompressionEvent::ChangeLog(*change_log_event),
367+
&ctx.accounts.log_wrapper,
368+
)
363369
}
364370

365371
/// Transfers `authority`.
@@ -442,10 +448,16 @@ pub mod spl_account_compression {
442448
let id = ctx.accounts.merkle_tree.key();
443449
let merkle_tree_size = merkle_tree_get_size(&header)?;
444450
let (tree_bytes, canopy_bytes) = rest.split_at_mut(merkle_tree_size);
445-
let change_log = merkle_tree_apply_fn!(header, id, tree_bytes, append, leaf)?;
446-
wrap_event(change_log.try_to_vec()?, &ctx.accounts.log_wrapper)?;
447-
emit!(*change_log);
448-
update_canopy(canopy_bytes, header.get_max_depth(), Some(change_log))
451+
let change_log_event = merkle_tree_apply_fn!(header, id, tree_bytes, append, leaf)?;
452+
update_canopy(
453+
canopy_bytes,
454+
header.get_max_depth(),
455+
Some(&change_log_event),
456+
)?;
457+
wrap_event(
458+
&AccountCompressionEvent::ChangeLog(*change_log_event),
459+
&ctx.accounts.log_wrapper,
460+
)
449461
}
450462

451463
/// This instruction takes a proof, and will attempt to write the given leaf
@@ -480,7 +492,7 @@ pub mod spl_account_compression {
480492
fill_in_proof_from_canopy(canopy_bytes, header.get_max_depth(), index, &mut proof)?;
481493
// A call is made to ConcurrentMerkleTree::fill_empty_or_append
482494
let id = ctx.accounts.merkle_tree.key();
483-
let change_log = merkle_tree_apply_fn!(
495+
let change_log_event = merkle_tree_apply_fn!(
484496
header,
485497
id,
486498
tree_bytes,
@@ -490,8 +502,14 @@ pub mod spl_account_compression {
490502
&proof,
491503
index,
492504
)?;
493-
wrap_event(change_log.try_to_vec()?, &ctx.accounts.log_wrapper)?;
494-
emit!(*change_log);
495-
update_canopy(canopy_bytes, header.get_max_depth(), Some(change_log))
505+
update_canopy(
506+
canopy_bytes,
507+
header.get_max_depth(),
508+
Some(&change_log_event),
509+
)?;
510+
wrap_event(
511+
&AccountCompressionEvent::ChangeLog(*change_log_event),
512+
&ctx.accounts.log_wrapper,
513+
)
496514
}
497515
}

account-compression/programs/noop/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use solana_program::{
33
pubkey::Pubkey,
44
};
55

6-
declare_id!("WRAPYChf58WFCnyjXKJHtrPgzKXgHp6MD9aVDqJBbGh");
6+
declare_id!("noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV");
77

88
#[cfg(not(feature = "no-entrypoint"))]
99
use solana_program::entrypoint;

account-compression/sdk/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist/
2+
test-ledger/
3+
yarn-error.log

account-compression/sdk/.npmignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
test-ledger/
3+
tests/
4+
yarn-error.log

0 commit comments

Comments
 (0)