Skip to content

Commit 8b019bf

Browse files
wip
1 parent 091fb97 commit 8b019bf

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

sdk-libs/program-test/src/indexer/test_indexer.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,35 @@ impl Indexer for TestIndexer {
230230
res
231231
};
232232

233-
let account_data = account
233+
let mut account_data: CompressedAccount = account
234234
.ok_or(IndexerError::AccountNotFound)?
235235
.clone()
236236
.try_into()?;
237237

238+
// CRITICAL FIX: For V2 trees, if the account is found in the output queue by its leaf index,
239+
// use the event hash from the queue instead of the calculated hash
240+
// This ensures that the returned account hash matches what's in the output queue
241+
if account_data.tree_info.tree_type == TreeType::StateV2 {
242+
println!("using output queue");
243+
if let Some(merkle_tree) = self
244+
.state_merkle_trees
245+
.iter()
246+
.find(|t| t.accounts.merkle_tree == account_data.tree_info.tree)
247+
{
248+
println!("found merkle tree");
249+
if let Some((event_hash, _)) = merkle_tree
250+
.output_queue_elements
251+
.iter()
252+
.find(|(_, leaf_idx)| *leaf_idx == account_data.leaf_index as u64)
253+
{
254+
println!("found hash in output queue: {:?}", event_hash);
255+
// Found the account in output queue by leaf index - use the event hash
256+
// This allows the account to be found in output queue for prove_by_index
257+
account_data.hash = *event_hash;
258+
}
259+
}
260+
}
261+
238262
Ok(Response {
239263
context: Context {
240264
slot: self.get_current_slot(),
@@ -445,6 +469,7 @@ impl Indexer for TestIndexer {
445469
new_addresses_with_trees: Vec<AddressWithTree>,
446470
_config: Option<IndexerRpcConfig>,
447471
) -> Result<Response<ValidityProofWithContext>, IndexerError> {
472+
// DEBUG: Only print essential info
448473
#[cfg(feature = "v2")]
449474
{
450475
// V2 implementation with queue handling
@@ -457,9 +482,11 @@ impl Indexer for TestIndexer {
457482
let mut proof_inputs = vec![];
458483

459484
let mut indices_to_remove = Vec::new();
460-
// for all accounts in batched trees, check whether values are in tree or queue
485+
// For all accounts in batched trees, check whether values are in tree or queue.
486+
461487
let compressed_accounts = if !hashes.is_empty() && !state_merkle_tree_pubkeys.is_empty()
462488
{
489+
// Processing compressed accounts
463490
let zipped_accounts = hashes.iter().zip(state_merkle_tree_pubkeys.iter());
464491

465492
for (i, (compressed_account, state_merkle_tree_pubkey)) in
@@ -469,7 +496,7 @@ impl Indexer for TestIndexer {
469496
x.accounts.merkle_tree == *state_merkle_tree_pubkey
470497
&& x.tree_type == TreeType::StateV2
471498
});
472-
499+
// Check if account is in output queue
473500
if let Some(accounts) = accounts {
474501
let queue_element = accounts
475502
.output_queue_elements
@@ -481,6 +508,8 @@ impl Indexer for TestIndexer {
481508
{
482509
use light_client::indexer::RootIndex;
483510

511+
// Account found in output queue - use prove_by_index
512+
484513
indices_to_remove.push(i);
485514
proof_inputs.push(AccountProofInputs {
486515
hash: *compressed_account,
@@ -500,8 +529,14 @@ impl Indexer for TestIndexer {
500529
tree_type: accounts.tree_type,
501530
},
502531
})
532+
} else {
533+
// Account found but not in valid queue range
503534
}
535+
} else {
536+
// Account not found in output queue - will need merkle proof
504537
}
538+
} else {
539+
// No StateV2 tree found
505540
}
506541
}
507542

@@ -512,15 +547,22 @@ impl Indexer for TestIndexer {
512547
.map(|(_, x)| *x)
513548
.collect::<Vec<[u8; 32]>>();
514549

550+
// Final compressed_accounts that need merkle proofs
551+
515552
if compress_accounts.is_empty() {
516553
None
517554
} else {
518555
Some(compress_accounts)
519556
}
520557
} else {
558+
println!(
559+
"No hashes or state_merkle_tree_pubkeys provided, skipping compressed_accounts computation."
560+
);
521561
None
522562
};
523563

564+
// Processing remaining accounts that need merkle proofs
565+
524566
// Get the basic validity proof if needed
525567
let rpc_result: Option<ValidityProofWithContext> = if (compressed_accounts.is_some()
526568
&& !compressed_accounts.as_ref().unwrap().is_empty())
@@ -1920,6 +1962,7 @@ impl TestIndexer {
19201962
tree_types.push(bundle.tree_type);
19211963
println!("merkle_tree {:?}", merkle_tree);
19221964
println!("account {:?}", account);
1965+
println!("bundle {:?}", bundle.accounts);
19231966
let leaf_index = merkle_tree.get_leaf_index(account).unwrap();
19241967
let proof = merkle_tree.get_proof_of_leaf(leaf_index, true).unwrap();
19251968

sdk-tests/anchor-compressible/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ light-compressed-token-types = { workspace = true, features = ["anchor"] }
3232

3333
[dev-dependencies]
3434
light-program-test = { workspace = true, features = ["v2"] }
35-
light-client = { workspace = true, features = ["devenv", "v2"] }
35+
light-client = { workspace = true, features = ["v2"] }
3636
light-compressible-client = { workspace = true, features = ["anchor"] }
3737
light-test-utils = { workspace = true}
3838
tokio = { workspace = true }

sdk-tests/anchor-compressible/tests/test_decompress_multiple.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![cfg(feature = "test-sbf")]
22

3+
use std::{thread::sleep, time::Duration};
4+
35
use anchor_compressible::{CompressedAccountVariant, GameSession, UserRecord};
46
use anchor_lang::{
57
AccountDeserialize, AnchorDeserialize, Discriminator, InstructionData, ToAccountMetas,
@@ -37,7 +39,9 @@ pub const RENT_RECIPIENT: Pubkey = pubkey!("CLEuMG7pzJX9xAuKCFzBP154uiG1GaNo4Fq7
3739
#[tokio::test]
3840
async fn test_create_and_decompress_two_accounts() {
3941
let program_id = anchor_compressible::ID;
40-
let config = ProgramTestConfig::new_v2(true, Some(vec![("anchor_compressible", program_id)]));
42+
let mut config =
43+
ProgramTestConfig::new_v2(true, Some(vec![("anchor_compressible", program_id)]));
44+
config = config.with_light_protocol_events();
4145
let mut rpc = LightProgramTest::new(config).await.unwrap();
4246
let payer = rpc.get_payer().insecure_clone();
4347

@@ -132,6 +136,7 @@ async fn test_create_and_decompress_two_accounts() {
132136

133137
rpc.warp_to_slot(200).unwrap();
134138

139+
// sleep(Duration::from_secs(10));
135140
println!("henlo? decompress multiple");
136141
test_decompress_multiple_pdas(
137142
&mut rpc,
@@ -485,6 +490,13 @@ async fn test_decompress_multiple_pdas(
485490
"test-decompress-multiple-pdas: c_game_session: {:?}",
486491
c_game_session
487492
);
493+
494+
println!("c_user_pda: {:?}", c_user_pda);
495+
println!("c_user_pda hash: {:?}", c_user_pda.hash);
496+
println!("c_user_pda tree_info: {:?}", c_user_pda.tree_info);
497+
println!("c_game_pda: {:?}", c_game_pda);
498+
println!("c_game_pda hash: {:?}", c_game_pda.hash);
499+
println!("c_game_pda tree_info: {:?}", c_game_pda.tree_info);
488500
// Get validity proof for both compressed accounts
489501
let rpc_result = rpc
490502
.get_validity_proof(vec![c_user_pda.hash, c_game_pda.hash], vec![], None)

0 commit comments

Comments
 (0)