Skip to content

refactor: get_queue_elements#2118

Merged
SwenSchaeferjohann merged 10 commits intomainfrom
sergey/get_queue_elements_refactored
Dec 8, 2025
Merged

refactor: get_queue_elements#2118
SwenSchaeferjohann merged 10 commits intomainfrom
sergey/get_queue_elements_refactored

Conversation

@sergeytimoshin
Copy link
Contributor

@sergeytimoshin sergeytimoshin commented Dec 8, 2025

Consolidated get_queue_elements, get_batch_adress_queue_info, and get_queue_elements_v2 into one get_queue_elements.

Summary by CodeRabbit

  • Refactor

    • Unified separate queue endpoints into a single queue API and consolidated request parameters into one options payload.
  • New Features

    • Responses now return consolidated state + address queue results.
    • Queue data uses deduplicated-node representations to reduce payload size.
    • Added helpers to reconstruct proofs from deduplicated data for address-queue responses.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Walkthrough

This PR unifies the queue-elements API: it removes the v2 endpoint/types and consolidates fetching under get_queue_elements with a single QueueElementsV2Options parameter and new deduplicated-node response types (e.g., StateQueueData, AddressQueueData). Call sites, clients, photon-api models, SDK types, tests, and one forester processor call were updated.

Changes

Cohort / File(s) Summary
Indexer Trait & Core API
sdk-libs/client/src/indexer/indexer_trait.rs, sdk-libs/client/src/indexer/mod.rs
Removes get_queue_elements_v2, adds QueueElementsV2Options, changes get_queue_elements to take QueueElementsV2Options and return the consolidated result type; renames/re-exports queue data types (*V2 → base names).
Client Implementations
sdk-libs/client/src/indexer/photon_indexer.rs, sdk-libs/client/src/rpc/indexer.rs
Reworks PhotonIndexer get_queue_elements to be v2-aware (cfg gated), constructs nested QueueRequest objects, maps API responses into deduplicated-node structures; RPC wrapper now forwards QueueElementsV2Options.
SDK Type System
sdk-libs/client/src/indexer/types.rs
Replaces *V2 queue structs with deduplicated-node variants (StateQueueData, AddressQueueData, OutputQueueData, InputQueueData), adds QueueElementsResult, and implements reconstruction helpers (reconstruct_proof, reconstruct_all_proofs, encode_node_index).
Photon API Models & Endpoints
sdk-libs/photon-api/src/apis/default_api.rs, sdk-libs/photon-api/src/models/*
Removes get_queue_elements_v2 API function and related model files; introduces QueueRequest and Node models; changes GetQueueElementsPostRequestParams to use queue request objects; GetQueueElementsPost200ResponseResult now exposes stateQueue and addressQueue.
Photon API Model Internals
sdk-libs/photon-api/src/models/state_queue_data_v2.rs, sdk-libs/photon-api/src/models/address_queue_data_v2.rs, sdk-libs/photon-api/src/models/node.rs, sdk-libs/photon-api/src/models/queue_request.rs, sdk-libs/photon-api/src/models/mod.rs
Converts node storage to Vec<models::Node>, removes node_hashes, adds root_seq, applies serde(rename_all = "camelCase"), adds QueueRequest and Node exports and constructors.
Tests & Test-indexer
sdk-libs/program-test/src/indexer/test_indexer.rs, sdk-libs/program-test/src/program_test/indexer.rs, forester/tests/legacy/batched_address_test.rs
Update tests and test-indexer implementations to construct and pass QueueElementsV2Options and handle new result shape; remove V2-specific methods.
Processor Integration
forester/src/processor/v2/state/helpers.rs, forester/src/processor/v2/state/supervisor.rs
fetch_batches and supervisor methods updated to use the renamed StateQueueData type; fetch_batches now calls indexer.get_queue_elements(...) (options-based) instead of get_queue_elements_v2(...).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Forester as Forester (processor)
    participant LightClient as LightClient / Indexer trait
    participant Photon as Photon API
    participant DB as Consumer (e.g., Supervisor / TestIndexer)

    Note over Forester,LightClient: Caller builds QueueElementsV2Options
    Forester->>LightClient: get_queue_elements(pubkey, options, config)
    LightClient->>Photon: POST /getQueueElements (payload with QueueRequest objects)
    Photon-->>LightClient: 200 { stateQueue, addressQueue } (nodes as Node{index,hash}, subtrees...)
    LightClient->>DB: Map API response → SDK types (StateQueueData, AddressQueueData)
    DB-->>Forester: consume mapped result (append/nullify job builders)
    Note right of DB: reconstruction helpers may be invoked to build Merkle proofs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • Areas needing careful review:
    • sdk-libs/client/src/indexer/photon_indexer.rs — mapping from API response to SDK types, proof/slot-sync handling, cfg(feature="v2") paths.
    • sdk-libs/client/src/indexer/types.rs — correctness and edge cases of reconstruct_proof / reconstruct_all_proofs and node index encoding.
    • sdk-libs/photon-api/src/models/* — serde renames/defaults, Node compatibility, and constructors.
    • Forester fetch_batches and supervisor signature changes for consistency.

Possibly related PRs

Suggested labels

ai-review

Suggested reviewers

  • SwenSchaeferjohann
  • ananas-block

Poem

✨ One call to fetch the queues anew,
Nodes stitched tight and proofs in view.
Options gathered, endpoints aligned,
V2’s pieces folded into one design.
🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.24% which is insufficient. The required threshold is 70.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: get_queue_elements' directly and clearly describes the main change: consolidating three queue element functions into one refactored implementation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sergey/get_queue_elements_refactored

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 458552a and 17ee830.

⛔ Files ignored due to path filters (4)
  • cli/src/utils/constants.ts is excluded by none and included by none
  • program-tests/utils/src/e2e_test_env.rs is excluded by none and included by none
  • program-tests/utils/src/test_batch_forester.rs is excluded by none and included by none
  • scripts/devenv/versions.sh is excluded by none and included by none
📒 Files selected for processing (20)
  • forester/src/processor/v2/state/helpers.rs (1 hunks)
  • sdk-libs/client/src/indexer/indexer_trait.rs (2 hunks)
  • sdk-libs/client/src/indexer/mod.rs (1 hunks)
  • sdk-libs/client/src/indexer/photon_indexer.rs (3 hunks)
  • sdk-libs/client/src/indexer/types.rs (1 hunks)
  • sdk-libs/client/src/rpc/indexer.rs (2 hunks)
  • sdk-libs/photon-api/src/apis/default_api.rs (0 hunks)
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs (1 hunks)
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs (1 hunks)
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_200_response.rs (0 hunks)
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_200_response_result.rs (0 hunks)
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_request.rs (0 hunks)
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_request_params.rs (0 hunks)
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs (3 hunks)
  • sdk-libs/photon-api/src/models/mod.rs (1 hunks)
  • sdk-libs/photon-api/src/models/node.rs (1 hunks)
  • sdk-libs/photon-api/src/models/queue_request.rs (1 hunks)
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs (2 hunks)
  • sdk-libs/program-test/src/indexer/test_indexer.rs (3 hunks)
  • sdk-libs/program-test/src/program_test/indexer.rs (2 hunks)
💤 Files with no reviewable changes (5)
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_request_params.rs
  • sdk-libs/photon-api/src/apis/default_api.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_200_response_result.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_request.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_v2_post_200_response.rs
🧰 Additional context used
📓 Path-based instructions (1)
sdk-libs/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in sdk-libs must not depend on light-test-utils; integration tests must be located in sdk-tests/

Files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/node.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
🧠 Learnings (71)
📚 Learning: 2025-11-24T17:57:02.558Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_ADDRESS_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:02.558Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Always increment `queue_next_index` by 1 after successfully inserting an address. This value serves as a sequence number for indexers to track address insertion order.

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Validate queue type is `OUTPUT_STATE_QUEUE_TYPE_V2` when deserializing `BatchedQueueAccount`

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:24.369Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:24.369Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Transition batch state from `Fill` to `Full` and increment currently_processing_batch_index when num_inserted_elements reaches batch_size in the output queue

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Set output queue account discriminator to b`queueacc` (8 bytes) and initialize queue metadata with QueueType::OutputStateV2

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/merkle_tree.rs : State tree nullifier insertion must use the BatchedMerkleTreeAccount::insert_nullifier_into_queue method

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Use zero-copy deserialization for all `BatchedQueueAccount` operations

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:24.369Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:24.369Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : When a batch is in `Inserted` state, clear the value vec and hash chain stores, advance batch state to `Fill`, and reset batch metadata before allowing new insertions

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/merkle_tree.rs : Tree updates from input queue must use update_tree_from_input_queue function for state trees and update_tree_from_address_queue for address trees with ZKP verification

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/queue.rs : Output queue insertion must use BatchedQueueAccount::insert_into_current_batch method

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:58:10.392Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:10.392Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In src/merkle_tree.rs, implement BatchedMerkleTreeAccount::update_tree_from_input_queue method for batch nullify operations on StateV2 trees. The method must verify ZKP proving correctness of: old_root + queue nullifiers → new_root, update tree root, increment tree sequence_number, increment tree nullifier_next_index by zkp_batch_size, mark ZKP batch as inserted, transition batch state to Inserted when all ZKP batches complete, and zero out bloom filter when current batch is 50% inserted.

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Initialize output queue value vectors (2 vectors, one per batch with capacity = batch_size each) and hash chain stores (2 vectors with capacity = batch_size / zkp_batch_size each)

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
📚 Learning: 2025-11-24T17:57:24.369Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:24.369Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Before inserting into the output queue, validate that the tree is not full by checking that next_index < tree_capacity

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : In `src/queue.rs`, define BatchedQueueAccount layout and implement `mark_as_inserted_in_merkle_tree` method to increment `num_inserted_zkp_batches` and transition batch state to `Inserted` when all ZKP batches are complete

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Initialize output queue with 2 alternating batches, each with batch_size = output_queue_batch_size and zkp_batch_size = output_queue_zkp_batch_size

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : After successful ZKP verification, increment tree `next_index` by `zkp_batch_size` (represents leaf index for next insertion)

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Use `get_output_queue_account_size` function from src/queue.rs to calculate queue account size based on output_queue_batch_size and output_queue_zkp_batch_size

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:14.561Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:14.561Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In `BatchedMerkleTreeAccount::insert_nullifier_into_queue`, increment `nullifier_next_index` after each insertion to provide sequence number for indexers

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Implement two hash chain stores (`[ZeroCopyVecU64<[u8; 32]>; 2]`), one per batch, each with `batch_size / zkp_batch_size` hash chains storing Poseidon hashes of ZKP batches in `BatchedQueueAccount`

Applied to files:

  • forester/src/processor/v2/state/helpers.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Validate account ownership by Light account compression program using `check_owner` from `light-account-checks` when deserializing `BatchedQueueAccount` with `output_from_account_info`

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Depend on light-compressed-account crate for compressed account types and utilities

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-12-06T00:49:21.983Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:21.983Z
Learning: Applies to program-libs/compressible/src/config.rs : CompressibleConfig account structure must support serialization via Anchor, Pinocchio, and Borsh formats for Light Registry program integration

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/variant_enum.rs : Account variant enum (`CompressedAccountVariant`) generation and `CompressedAccountData` wrapper struct should be implemented in `variant_enum.rs`

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Store `BatchedQueueAccount` layout and `BatchedQueueMetadata` in src/queue.rs

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/photon-api/src/models/queue_request.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Use two value vectors (`[ZeroCopyVecU64<[u8; 32]>; 2]`), one per batch, to store compressed account hashes in `BatchedQueueAccount`

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Store compressed account hashes in `BatchedQueueAccount` value vectors for immediate proof-by-index access before tree insertion

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:59:03.485Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_INFO_TRAIT.md:0-0
Timestamp: 2025-11-24T17:59:03.485Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/account_info/solana.rs : Use `std::cell::Ref` and `std::cell::RefMut` for DataRef and DataRefMut associated types when implementing AccountInfoTrait for solana-program SDK

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Initialize an output queue account as `BatchedQueueAccount` with `QueueType::OutputStateV2`, temporary storage for compressed account hashes before tree insertion with immediate spending capability via proof-by-index, using discriminator b`queueacc` [113, 117, 101, 117, 101, 97, 99, 99]

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: In client code, deserialize output queues using `BatchedQueueAccount::output_from_bytes(&mut account_data)?` from the `light_batched_merkle_tree::queue` module

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In `src/merkle_tree.rs`, implement `BatchedMerkleTreeAccount::update_tree_from_output_queue_account` method that batch appends values from output queue to state Merkle tree with ZKP verification, verifying proof of old_root + queue_values → new_root

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:58:10.392Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:10.392Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In src/merkle_tree.rs, implement BatchedMerkleTreeAccount::update_tree_from_address_queue method for batch address append operations on AddressV2 trees. The method must verify ZKP proving correctness of: old_root + queue addresses → new_root using indexed Merkle tree insertion, update tree root, increment tree sequence_number, increment tree next_index by zkp_batch_size, mark ZKP batch as inserted, transition batch state to Inserted when all ZKP batches complete, and zero out bloom filter when current batch is 50% inserted.

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : In Solana programs, deserialize output queues using `BatchedQueueAccount::output_from_account_info(account_info)?` from the `light_batched_merkle_tree::queue` module

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Set tree_type to `TreeType::AddressV2` (5) and associated_queue to Pubkey::default() for address trees in `src/initialize_address_tree.rs`. Address trees have no separate output queue - the address queue is integrated into the tree account.

Applied to files:

  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use BatchedMerkleTreeAccount for state trees with integrated input queue (for nullifiers) and separate BatchedQueueAccount for output operations

Applied to files:

  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use BatchedMerkleTreeAccount with integrated input queue (for addresses) for address trees without a separate output queue account

Applied to files:

  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : BatchedMerkleTreeAccount must be of type `TreeType::StateV2` when updating tree from output queue

Applied to files:

  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/queue.rs : Output queues must store compressed account hashes in value vectors (one per batch) enabling access by leaf index before tree insertion

Applied to files:

  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : `InitAddressTreeAccountsInstructionData` struct in `src/initialize_address_tree.rs` must include: height (u32, default 40), index (u64), root_history_capacity (u32, default 200), input_queue_batch_size (u64, default 15,000), input_queue_zkp_batch_size (u64, default 250), bloom_filter_capacity (u64, default batch_size * 8), bloom_filter_num_iters (u64, default 3 for test/10 for production), program_owner (Option<Pubkey>), forester (Option<Pubkey>), rollover_threshold (Option<u64>, default 95%), network_fee (Option<u64>, default 10,000 lamports), and close_threshold (Option<u64>).

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/merkle_tree.rs : Address tree address insertion must use the BatchedMerkleTreeAccount::insert_address_into_queue method

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/photon-api/src/models/mod.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use constants from constants.rs including ADDRESS_TREE_INIT_ROOT_40 generated from IndexedMerkleTree reference implementation

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Initialize address tree with integrated address queue in `src/initialize_address_tree.rs`. Creates one `BatchedMerkleTreeAccount` with account layout defined in `src/merkle_tree.rs`, metadata in `src/merkle_tree_metadata.rs`, tree type `TreeType::AddressV2` (5), initial root `ADDRESS_TREE_INIT_ROOT_40`, starts at next_index 1, and discriminator `BatchMta` (8 bytes).

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Initialize integrated address queue in merkle tree account with 2 bloom filter stores and 2 hash chain stores. Bloom filter capacity = bloom_filter_capacity / 8 bytes each. Hash chain stores capacity = (input_queue_batch_size / input_queue_zkp_batch_size) each.

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Initialize root history as cyclic buffer with capacity=root_history_capacity and first entry = `ADDRESS_TREE_INIT_ROOT_40` in `src/initialize_address_tree.rs`.

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Validate root_history_capacity is at least equal to (input_queue_batch_size / input_queue_zkp_batch_size) in `src/initialize_address_tree.rs`. This ensures sufficient space for roots generated by address queue operations.

Applied to files:

  • sdk-libs/photon-api/src/models/address_queue_data_v2.rs
📚 Learning: 2025-11-24T17:59:03.485Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_INFO_TRAIT.md:0-0
Timestamp: 2025-11-24T17:59:03.485Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/account_info/{solana,pinocchio}.rs : Implement AccountInfoTrait with SDK-specific Pubkey types: `solana_pubkey::Pubkey` for solana-program feature and `[u8; 32]` raw bytes for pinocchio feature

Applied to files:

  • sdk-libs/program-test/src/program_test/indexer.rs
📚 Learning: 2025-11-24T17:54:38.537Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/README.md:0-0
Timestamp: 2025-11-24T17:54:38.537Z
Learning: Implement compressed token program interfaces for third-party token creation and usage on Solana using ZK Compression

Applied to files:

  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/decompress_context.rs : Decompression trait implementation (`DecompressContext`) with account accessors, PDA/token separation logic, and token processing delegation should be in `decompress_context.rs`

Applied to files:

  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Check `tree_capacity` (2^height) against new insertions to prevent overflow in `BatchedQueueAccount`

Applied to files:

  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/client/src/rpc/indexer.rs
📚 Learning: 2025-12-07T18:10:14.595Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-07T18:10:14.595Z
Learning: All compressed token account implementations must reference and comply with the account layout specifications in programs/compressed-token/program/docs/ACCOUNTS.md

Applied to files:

  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-12-07T03:17:28.794Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-07T03:17:28.794Z
Learning: Use compressible token account extensions that allow accounts to be compressed back into compressed state with rent payment mechanisms

Applied to files:

  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Verify queue and tree association by matching pubkeys; error with `MerkleTreeAndQueueNotAssociated` (14001) if they don't match

Applied to files:

  • sdk-libs/client/src/rpc/indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Set Merkle tree next_index to 0 (starts empty) and sequence_number to 0 (increments with each tree update)

Applied to files:

  • sdk-libs/photon-api/src/models/node.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree_metadata.rs : Define `BatchedMerkleTreeMetadata` structure in `src/merkle_tree_metadata.rs`. Include tree_type, associated_queue, rollover_fee calculation, access_metadata (owner, program_owner, forester), rollover_metadata (index, rollover_fee, rollover_threshold, network_fee, close_threshold, additional_bytes), hashed_pubkey, next_index, and sequence_number fields.

Applied to files:

  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Pre-hash merkle tree pubkeys to 31 bytes (248 bits) with 1 byte padding for bn254 field size compatibility in Poseidon hashing within ZK circuits

Applied to files:

  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Pre-hash queue pubkeys to 31 bytes (248 bits) with 1 byte padding for bn254 field size compatibility in Poseidon hashing within ZK circuits

Applied to files:

  • sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : State trees must initialize with zero bytes root for the specified height and have a separate BatchedQueueAccount for output operations

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Address trees must initialize with `ADDRESS_TREE_INIT_ROOT_40` (hardcoded for height 40) and start with next_index = 1 (pre-initialized with one element at index 0)

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Tree height must be fixed at 40 for address trees in `src/initialize_address_tree.rs`. Validate that height equals 40.

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Calculate overlapping roots for zeroing using: overlapping if `batch.sequence_number > current_tree.sequence_number`; compute `num_remaining_roots = batch.sequence_number - current_tree.sequence_number`; verify `num_remaining_roots < root_history.len()` and error with `CannotZeroCompleteRootHistory` (14313) if violated

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:02.558Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_ADDRESS_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:02.558Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : When attempting to reuse a batch in the `Inserted` state before its bloom filter has been zeroed by the forester, return `BatchedMerkleTreeError::BloomFilterNotZeroed` (error code 14312).

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:26.329Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/zero-copy/README.md:0-0
Timestamp: 2025-11-24T17:54:26.329Z
Learning: Do not use Light Zero Copy on 32-bit targets with length greater than u32

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:33.614Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/anchor/README.md:0-0
Timestamp: 2025-11-24T17:54:33.614Z
Learning: Implement the Compressed Token Program interface for creating and using compressed tokens on Solana with ZK Compression

Applied to files:

  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
📚 Learning: 2025-11-24T17:53:57.540Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: js/compressed-token/README.md:0-0
Timestamp: 2025-11-24T17:53:57.540Z
Learning: This is the JavaScript SDK for interacting with the Compressed Token program on Solana

Applied to files:

  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Initialize a state Merkle tree with a `TreeType::StateV2` (4) tree type, storing tree roots, root history, and integrated input queue (bloom filters + hash chains for nullifiers) in the `BatchedMerkleTreeAccount` with discriminator b`BatchMta` [66, 97, 116, 99, 104, 77, 116, 97]

Applied to files:

  • sdk-libs/photon-api/src/models/state_queue_data_v2.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Depend on light-account-checks crate for account validation and discriminator checks

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : When deserializing BatchedMerkleTreeAccount in client code, use `BatchedMerkleTreeAccount::state_from_bytes()` for state trees and `BatchedMerkleTreeAccount::address_from_bytes()` for address trees

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Depend on light-zero-copy crate for zero-copy serialization for efficient account data access

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : When deserializing BatchedMerkleTreeAccount in Solana programs, use `BatchedMerkleTreeAccount::state_from_account_info()` for state trees and `BatchedMerkleTreeAccount::address_from_account_info()` for address trees

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Depend on light-verifier crate for ZKP verification of batch updates

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Store `BatchedMerkleTreeAccount` layout in src/merkle_tree.rs and `BatchedMerkleTreeMetadata` in src/merkle_tree_metadata.rs

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Account validation for state trees must check: (1) account ownership by Light account compression program, (2) account discriminator is `BatchMta`, and (3) tree type is `STATE_MERKLE_TREE_TYPE_V2` (4)

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Associate output queue with merkle_tree_account pubkey in queue metadata and calculate rollover_fee based on rollover_threshold, height, and total rent (merkle_tree_rent + additional_bytes_rent + queue_rent)

Applied to files:

  • sdk-libs/program-test/src/indexer/test_indexer.rs
🧬 Code graph analysis (6)
sdk-libs/client/src/indexer/indexer_trait.rs (3)
sdk-libs/client/src/indexer/photon_indexer.rs (1)
  • get_queue_elements (1614-1853)
sdk-libs/client/src/rpc/indexer.rs (1)
  • get_queue_elements (204-216)
sdk-libs/program-test/src/indexer/test_indexer.rs (1)
  • get_queue_elements (615-622)
sdk-libs/photon-api/src/models/node.rs (1)
sdk-libs/photon-api/src/models/queue_request.rs (1)
  • new (23-29)
sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs (2)
sdk-libs/photon-api/src/models/_get_batch_address_update_info_post_request_params.rs (1)
  • new (29-35)
sdk-libs/photon-api/src/models/merkle_context_v2.rs (1)
  • new (31-39)
sdk-libs/photon-api/src/models/queue_request.rs (2)
sdk-libs/photon-api/src/models/node.rs (1)
  • new (21-23)
forester/src/processor/v2/state/supervisor.rs (1)
  • zkp_batch_size (139-141)
sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs (2)
sdk-libs/photon-api/src/models/address_queue_data_v2.rs (1)
  • new (40-70)
sdk-libs/photon-api/src/models/state_queue_data_v2.rs (1)
  • new (32-40)
sdk-libs/client/src/indexer/photon_indexer.rs (4)
sdk-libs/client/src/indexer/error.rs (1)
  • missing_result (65-70)
sdk-libs/client/src/rpc/indexer.rs (1)
  • get_queue_elements (204-216)
sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs (1)
  • new (30-37)
sdk-libs/photon-api/src/apis/default_api.rs (1)
  • get_queue_elements_post (1791-1828)
🪛 GitHub Actions: programs
sdk-libs/program-test/src/indexer/test_indexer.rs

[error] 621-621: not implemented: get_queue_elements not implemented for TestIndexer

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Forester e2e test
🔇 Additional comments (20)
forester/src/processor/v2/state/helpers.rs (1)

72-76: LGTM! Clean migration to unified get_queue_elements API.

The call site correctly transitions from get_queue_elements_v2 to the consolidated get_queue_elements method. The QueueElementsV2Options builder pattern is well-utilized, and the result extraction via res.value.state_queue aligns with the V2 result structure.

sdk-libs/photon-api/src/models/queue_request.rs (1)

14-39: Clean builder pattern implementation.

The QueueRequest struct follows idiomatic Rust patterns with a constructor for required fields and builder methods for optional ones. The skip_serializing_if attributes keep the wire format clean.

One consideration: a limit of 0 is technically valid but semantically useless. If the API should reject zero-limit requests, consider adding validation. However, if the server handles this gracefully, the current implementation is fine.

sdk-libs/client/src/indexer/indexer_trait.rs (1)

186-197: Trait signature correctly consolidated to V2 API.

The updated get_queue_elements method cleanly replaces the previous multi-parameter approach with a single QueueElementsV2Options struct. This is a significant improvement for API ergonomics and future extensibility. The updated documentation accurately describes the enhanced capabilities including address queue support and deduplicated nodes.

sdk-libs/program-test/src/program_test/indexer.rs (1)

200-212: Implementation correctly delegates to V2 API.

The LightProgramTest implementation properly forwards the get_queue_elements call to the underlying indexer with the new QueueElementsV2Options signature. The delegation pattern is consistent with other methods in this impl block.

sdk-libs/client/src/rpc/indexer.rs (1)

204-216: LightClient implementation correctly updated for V2 API.

The get_queue_elements implementation in LightClient properly delegates to the underlying indexer with the consolidated V2 signature. The implementation is consistent with other trait methods and maintains proper error handling for uninitialized indexers.

sdk-libs/client/src/indexer/mod.rs (1)

21-22: Public API surface correctly updated for V2 consolidation.

The removal of QueueElementsResult and export of QueueElementsV2Result is a breaking change. Ensure downstream consumers are aware of this migration requirement. The change aligns with the PR's consolidation objective. No lingering references to the removed QueueElementsResult type remain in the codebase.

sdk-libs/photon-api/src/models/node.rs (1)

11-24: No action needed; serde traits are already in scope via crate-level macro.

The Node struct is correctly defined. Serde's Serialize and Deserialize derives are available throughout the crate via the #[macro_use] extern crate serde_derive; declaration in lib.rs, so no additional imports are required in node.rs.

sdk-libs/photon-api/src/models/mod.rs (1)

341-344: LGTM!

Clean addition of the new Node and QueueRequest modules following the established pattern. These support the consolidated V2 queue elements API.

sdk-libs/photon-api/src/models/state_queue_data_v2.rs (1)

14-28: LGTM!

The struct-level #[serde(rename_all = "camelCase")] is a cleaner approach than per-field renames. The type change from Vec<u64> to Vec<models::Node> aligns with the new deduplicated node representation used across the V2 API surface. The #[serde(default)] on nodes appropriately handles optional fields during deserialization.

sdk-libs/photon-api/src/models/address_queue_data_v2.rs (2)

13-36: LGTM!

The changes consistently align with StateQueueDataV2: struct-level camelCase renaming, Vec<models::Node> for nodes, and appropriate #[serde(default)] attributes for flexible deserialization. The addition of root_seq supports the V2 data model requirements.


38-70: Constructor signature updated correctly.

The new function signature now accepts nodes: Vec<models::Node> and root_seq: u64, matching the struct field changes. This is a breaking change for callers, but necessary for the V2 API consolidation.

sdk-libs/client/src/indexer/types.rs (2)

90-111: Well-documented struct changes.

The new fields (queue_indices, leaves_hash_chains, subtrees, start_index, root_seq, low_element_proofs) properly support the V2 deduplicated node-based proof reconstruction model. The documentation clearly explains that proofs are reconstructed from nodes/node_hashes using low_element_indices.


150-165: LGTM!

The reconstruct_all_proofs and encode_node_index implementations are clean. The encoding scheme (level << 56) | position matches the documented format at line 99, leaving 56 bits for position which is ample for tree heights up to 255.

sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs (2)

13-27: Clean API consolidation.

Replacing four scalar parameters (output_queue_start_index, output_queue_limit, input_queue_start_index, input_queue_limit) with three structured QueueRequest options is a good design choice. It's more extensible and aligns with the PR objective of consolidating the queue element APIs. The addition of address_queue completes the unified interface for all queue types.


29-37: LGTM!

The constructor correctly initializes all three queue options as None, allowing callers to selectively specify which queues they need. This follows the builder pattern used elsewhere in the codebase (see GetBatchAddressUpdateInfoPostRequestParams::new in the relevant snippets).

sdk-libs/program-test/src/indexer/test_indexer.rs (1)

704-728: V2 API wiring looks correct, but verify the field mapping.

The new flow correctly:

  1. Constructs QueueElementsV2Options with address queue parameters
  2. Calls get_queue_elements and extracts address_queue
  3. Maps addresses to AddressQueueIndex using first_queue_index

One concern: Line 722 uses address_queue.first_queue_index + i as u64 for queue_index, but the photon API returns queue_indices as a separate array (see photon_indexer.rs Line 1822). Ensure the test indexer's implementation will populate first_queue_index correctly when you implement it.

sdk-libs/photon-api/src/models/_get_queue_elements_post_200_response_result.rs (1)

13-31: LGTM! Clean V2 model structure.

The refactored response model correctly:

  • Consolidates the old four-field pattern into two optional V2 data structures
  • Uses Box to avoid large stack allocations for nested data
  • Applies proper serde attributes for JSON serialization

This aligns well with the broader API consolidation goal.

sdk-libs/client/src/indexer/photon_indexer.rs (3)

1614-1667: Well-structured V2 request building with proper option mapping.

The request construction cleanly maps QueueElementsV2Options to nested QueueRequest objects. The pattern of conditionally creating queue requests based on limit presence is correct.


1679-1762: StateQueueDataV2 parsing is thorough but verbose.

The parsing correctly handles:

  • Node index/hash extraction from combined objects
  • Output queue with leaf indices, account hashes, old leaves, and hash chains
  • Input queue with nullifiers, tx hashes, and current leaves

The repetitive Result<Vec<[u8; 32]>, IndexerError> conversions could be extracted to a helper, but this is a minor readability concern.


1488-1551: Clean refactor of get_address_queue_with_proofs to use unified V2 API.

The method now:

  1. Delegates to get_queue_elements with address queue options
  2. Extracts and validates address queue data
  3. Builds BatchAddressUpdateIndexerResponse from V2 structures

The error handling with ok_or_else providing context is appropriate.

Comment on lines +125 to +130
for level in 0..tree_height {
let sibling_pos = if pos.is_multiple_of(2) {
pos + 1
} else {
pos - 1
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check if is_multiple_of is used elsewhere and how it's imported
rg -n "is_multiple_of" sdk-libs/client/src/indexer/types.rs -B 5 -A 5

# Check imports at the top of the file
head -50 sdk-libs/client/src/indexer/types.rs

# Check Cargo.toml for num-integer dependency
cat sdk-libs/client/Cargo.toml | grep -A 5 -B 5 "num"

Repository: Lightprotocol/light-protocol

Length of output: 2139


🏁 Script executed:

# Check workspace Cargo.toml for num-integer
find . -name "Cargo.toml" -path "*/Cargo.toml" | head -1 | xargs cat | grep -A 2 "num-integer"

# Also verify if num_integer is available in workspace
rg "num.integer" Cargo.toml

Repository: Lightprotocol/light-protocol

Length of output: 122


🏁 Script executed:

# Find workspace Cargo.toml
find . -maxdepth 2 -name "Cargo.toml" -type f | head -5

# Check for num_integer anywhere in workspace
rg "num_integer|num-integer" --type toml

Repository: Lightprotocol/light-protocol

Length of output: 653


🏁 Script executed:

# Final verification: check the exact Cargo.toml for sdk-libs/client
cat sdk-libs/client/Cargo.toml

Repository: Lightprotocol/light-protocol

Length of output: 2328


is_multiple_of is not available on u64 and will cause a compilation error.

The is_multiple_of method doesn't exist on primitive integer types in standard Rust, and num-integer is not a dependency of sdk-libs/client. Replace with the standard modulo operator:

         for level in 0..tree_height {
-            let sibling_pos = if pos.is_multiple_of(2) {
+            let sibling_pos = if pos % 2 == 0 {
                 pos + 1
             } else {
                 pos - 1
             };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for level in 0..tree_height {
let sibling_pos = if pos.is_multiple_of(2) {
pos + 1
} else {
pos - 1
};
for level in 0..tree_height {
let sibling_pos = if pos % 2 == 0 {
pos + 1
} else {
pos - 1
};
🤖 Prompt for AI Agents
In sdk-libs/client/src/indexer/types.rs around lines 125 to 130, the code calls
pos.is_multiple_of(2) which doesn't exist on u64; replace that check with the
standard modulo check (pos % 2 == 0) so the sibling_pos calculation becomes: if
pos % 2 == 0 { pos + 1 } else { pos - 1 }; no additional dependencies are
needed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
sdk-libs/client/src/indexer/types.rs (1)

124-129: Compilation error: is_multiple_of doesn't exist on primitive integers.

This is a critical issue that will prevent compilation. The is_multiple_of method isn't available on u64 in standard Rust, and num-integer isn't a dependency of this crate.

Apply this diff to fix:

         for level in 0..tree_height {
-            let sibling_pos = if pos.is_multiple_of(2) {
+            let sibling_pos = if pos % 2 == 0 {
                 pos + 1
             } else {
                 pos - 1
             };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17ee830 and 7af9145.

📒 Files selected for processing (2)
  • sdk-libs/client/src/indexer/photon_indexer.rs (4 hunks)
  • sdk-libs/client/src/indexer/types.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
sdk-libs/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in sdk-libs must not depend on light-test-utils; integration tests must be located in sdk-tests/

Files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
🧠 Learnings (53)
📚 Learning: 2025-11-24T17:57:02.558Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_ADDRESS_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:02.558Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Always increment `queue_next_index` by 1 after successfully inserting an address. This value serves as a sequence number for indexers to track address insertion order.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:58:10.392Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:10.392Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In src/merkle_tree.rs, implement BatchedMerkleTreeAccount::update_tree_from_address_queue method for batch address append operations on AddressV2 trees. The method must verify ZKP proving correctness of: old_root + queue addresses → new_root using indexed Merkle tree insertion, update tree root, increment tree sequence_number, increment tree next_index by zkp_batch_size, mark ZKP batch as inserted, transition batch state to Inserted when all ZKP batches complete, and zero out bloom filter when current batch is 50% inserted.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Validate queue type is `OUTPUT_STATE_QUEUE_TYPE_V2` when deserializing `BatchedQueueAccount`

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use BatchedMerkleTreeAccount for state trees with integrated input queue (for nullifiers) and separate BatchedQueueAccount for output operations

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/merkle_tree.rs : Tree updates from input queue must use update_tree_from_input_queue function for state trees and update_tree_from_address_queue for address trees with ZKP verification

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use BatchedMerkleTreeAccount with integrated input queue (for addresses) for address trees without a separate output queue account

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Store `BatchedQueueAccount` layout and `BatchedQueueMetadata` in src/queue.rs

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Set output queue account discriminator to b`queueacc` (8 bytes) and initialize queue metadata with QueueType::OutputStateV2

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Set tree_type to `TreeType::AddressV2` (5) and associated_queue to Pubkey::default() for address trees in `src/initialize_address_tree.rs`. Address trees have no separate output queue - the address queue is integrated into the tree account.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Use zero-copy deserialization for all `BatchedQueueAccount` operations

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Tree height must be fixed at 40 for address trees in `src/initialize_address_tree.rs`. Validate that height equals 40.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Address trees must initialize with `ADDRESS_TREE_INIT_ROOT_40` (hardcoded for height 40) and start with next_index = 1 (pre-initialized with one element at index 0)

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : `InitAddressTreeAccountsInstructionData` struct in `src/initialize_address_tree.rs` must include: height (u32, default 40), index (u64), root_history_capacity (u32, default 200), input_queue_batch_size (u64, default 15,000), input_queue_zkp_batch_size (u64, default 250), bloom_filter_capacity (u64, default batch_size * 8), bloom_filter_num_iters (u64, default 3 for test/10 for production), program_owner (Option<Pubkey>), forester (Option<Pubkey>), rollover_threshold (Option<u64>, default 95%), network_fee (Option<u64>, default 10,000 lamports), and close_threshold (Option<u64>).

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Set tree_capacity = 2^height in output queue metadata

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use constants from constants.rs including ADDRESS_TREE_INIT_ROOT_40 generated from IndexedMerkleTree reference implementation

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:02.558Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_ADDRESS_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:02.558Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In `BatchedMerkleTreeAccount::insert_address_into_queue`, verify that the tree type is `TreeType::AddressV2` before proceeding with address insertion. Reject state trees with `MerkleTreeMetadataError::InvalidTreeType`.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Check `tree_capacity` (2^height) against new insertions to prevent overflow in `BatchedQueueAccount`

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:14.561Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:14.561Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In `BatchedMerkleTreeAccount::insert_nullifier_into_queue`, verify tree type is `TreeType::StateV2` before allowing nullifier insertion; reject address trees

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Define tree configuration parameters in `InitStateTreeAccountsInstructionData` struct: height (u32, default 32), index (u64), and root_history_capacity (u32, default 200)

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Initialize next_index to 1 (not 0) in BatchedMerkleTreeAccount in `src/initialize_address_tree.rs`. Index 0 contains pre-initialized sentinel element.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Use two value vectors (`[ZeroCopyVecU64<[u8; 32]>; 2]`), one per batch, to store compressed account hashes in `BatchedQueueAccount`

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/queue.rs : Output queues must store compressed account hashes in value vectors (one per batch) enabling access by leaf index before tree insertion

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/merkle_tree.rs : Address tree address insertion must use the BatchedMerkleTreeAccount::insert_address_into_queue method

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Validate account ownership by Light account compression program using `check_owner` from `light-account-checks` when deserializing `BatchedQueueAccount` with `output_from_account_info`

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Store compressed account hashes in `BatchedQueueAccount` value vectors for immediate proof-by-index access before tree insertion

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Compute and store hashed pubkeys by hashing and truncating to 31 bytes for bn254 field compatibility in both queue and tree accounts

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Depend on light-compressed-account crate for compressed account types and utilities

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : When deserializing BatchedMerkleTreeAccount in client code, use `BatchedMerkleTreeAccount::state_from_bytes()` for state trees and `BatchedMerkleTreeAccount::address_from_bytes()` for address trees

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Account validation for address trees must check: (1) account ownership by Light account compression program, (2) account discriminator is `BatchMta`, and (3) tree type is `ADDRESS_MERKLE_TREE_TYPE_V2` (5)

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Define `BatchedMerkleTreeAccount` account layout in `src/merkle_tree.rs`. Include method `get_merkle_tree_account_size` to calculate account size based on input_queue_batch_size, bloom_filter_capacity, input_queue_zkp_batch_size, root_history_capacity, and height.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Initialize address tree with integrated address queue in `src/initialize_address_tree.rs`. Creates one `BatchedMerkleTreeAccount` with account layout defined in `src/merkle_tree.rs`, metadata in `src/merkle_tree_metadata.rs`, tree type `TreeType::AddressV2` (5), initial root `ADDRESS_TREE_INIT_ROOT_40`, starts at next_index 1, and discriminator `BatchMta` (8 bytes).

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : ZKP batch sizes for address trees must be 10 or 250 in `src/initialize_address_tree.rs`. Only these circuit sizes are supported for address trees.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Initialize an output queue account as `BatchedQueueAccount` with `QueueType::OutputStateV2`, temporary storage for compressed account hashes before tree insertion with immediate spending capability via proof-by-index, using discriminator b`queueacc` [113, 117, 101, 117, 101, 97, 99, 99]

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In `src/merkle_tree.rs`, implement `BatchedMerkleTreeAccount::update_tree_from_output_queue_account` method that batch appends values from output queue to state Merkle tree with ZKP verification, verifying proof of old_root + queue_values → new_root

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:58:10.392Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_INPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:10.392Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : In src/merkle_tree.rs, implement BatchedMerkleTreeAccount::update_tree_from_input_queue method for batch nullify operations on StateV2 trees. The method must verify ZKP proving correctness of: old_root + queue nullifiers → new_root, update tree root, increment tree sequence_number, increment tree nullifier_next_index by zkp_batch_size, mark ZKP batch as inserted, transition batch state to Inserted when all ZKP batches complete, and zero out bloom filter when current batch is 50% inserted.

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Implement two hash chain stores (`[ZeroCopyVecU64<[u8; 32]>; 2]`), one per batch, each with `batch_size / zkp_batch_size` hash chains storing Poseidon hashes of ZKP batches in `BatchedQueueAccount`

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/queue.rs : Output queue insertion must use BatchedQueueAccount::insert_into_current_batch method

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : BatchedMerkleTreeAccount must be of type `TreeType::StateV2` when updating tree from output queue

Applied to files:

  • sdk-libs/client/src/indexer/photon_indexer.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : State trees must initialize with zero bytes root for the specified height and have a separate BatchedQueueAccount for output operations

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Calculate overlapping roots for zeroing using: overlapping if `batch.sequence_number > current_tree.sequence_number`; compute `num_remaining_roots = batch.sequence_number - current_tree.sequence_number`; verify `num_remaining_roots < root_history.len()` and error with `CannotZeroCompleteRootHistory` (14313) if violated

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:02.558Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INSERT_ADDRESS_QUEUE.md:0-0
Timestamp: 2025-11-24T17:57:02.558Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : When attempting to reuse a batch in the `Inserted` state before its bloom filter has been zeroed by the forester, return `BatchedMerkleTreeError::BloomFilterNotZeroed` (error code 14312).

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:26.329Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/zero-copy/README.md:0-0
Timestamp: 2025-11-24T17:54:26.329Z
Learning: Do not use Light Zero Copy on 32-bit targets with length greater than u32

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:20.982Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/zero-copy-derive/README.md:0-0
Timestamp: 2025-11-24T17:54:20.982Z
Learning: Applies to program-libs/zero-copy-derive/**/*.rs : Boolean types are converted to u8 in zero-copy structs for alignment and serialization

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Error handling must use BatchedMerkleTreeError enum from errors.rs with u32 error codes in the 14301-14312 range

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:20.982Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/zero-copy-derive/README.md:0-0
Timestamp: 2025-11-24T17:54:20.982Z
Learning: Applies to program-libs/zero-copy-derive/**/*.rs : Primitive integer types are automatically converted to little-endian equivalents (u16→U16, u32→U32, u64→U64) in zero-copy structs

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:20.982Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/zero-copy-derive/README.md:0-0
Timestamp: 2025-11-24T17:54:20.982Z
Learning: Applies to program-libs/zero-copy-derive/**/*.rs : Use Option<T> for optional values in zero-copy structs; Option<u16>, Option<u32>, and Option<u64> are optimized

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:58:35.079Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/UPDATE_FROM_OUTPUT_QUEUE.md:0-0
Timestamp: 2025-11-24T17:58:35.079Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/merkle_tree.rs : Verify tree capacity constraint before tree update: `tree.next_index + zkp_batch_size <= tree_capacity`; error with `TreeIsFull` (14310) if violated

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:54:20.982Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/zero-copy-derive/README.md:0-0
Timestamp: 2025-11-24T17:54:20.982Z
Learning: Applies to program-libs/zero-copy-derive/**/*.rs : Use only supported primitive types: u8, u16, u32, u64, i8, i16, i32, i64, and bool in structs with ZeroCopy macros

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Use light-merkle-tree-reference crate as dev dependency for reference implementation of indexed Merkle trees and generating constants

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:59:36.701Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/DISCRIMINATOR.md:0-0
Timestamp: 2025-11-24T17:59:36.701Z
Learning: Applies to program-libs/account-checks/docs/**/account-checks/**/*.rs : Implement the Discriminator trait for account types, providing 8-byte LIGHT_DISCRIMINATOR constant and LIGHT_DISCRIMINATOR_SLICE reference in Rust account structures

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Use `get_output_queue_account_size` function from src/queue.rs to calculate queue account size based on output_queue_batch_size and output_queue_zkp_batch_size

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Initialize output queue value vectors (2 vectors, one per batch with capacity = batch_size each) and hash chain stores (2 vectors with capacity = batch_size / zkp_batch_size each)

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: In client code, deserialize output queues using `BatchedQueueAccount::output_from_bytes(&mut account_data)?` from the `light_batched_merkle_tree::queue` module

Applied to files:

  • sdk-libs/client/src/indexer/types.rs
🧬 Code graph analysis (1)
sdk-libs/client/src/indexer/photon_indexer.rs (4)
sdk-libs/client/src/indexer/error.rs (1)
  • missing_result (65-70)
sdk-libs/client/src/indexer/indexer_trait.rs (1)
  • get_queue_elements (192-197)
sdk-libs/photon-api/src/models/_get_queue_elements_post_request_params.rs (1)
  • new (30-37)
sdk-libs/photon-api/src/apis/default_api.rs (1)
  • get_queue_elements_post (1791-1828)
🪛 GitHub Actions: examples-tests
sdk-libs/client/src/indexer/photon_indexer.rs

[error] 5-5: unused import: light_prover_client::constants::DEFAULT_BATCH_ADDRESS_TREE_HEIGHT

🪛 GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-ctoke...
sdk-libs/client/src/indexer/photon_indexer.rs

[failure] 5-5:
unused import: light_prover_client::constants::DEFAULT_BATCH_ADDRESS_TREE_HEIGHT

🔇 Additional comments (4)
sdk-libs/client/src/indexer/types.rs (1)

112-164: LGTM! Proof reconstruction logic is sound.

The approach of storing deduplicated nodes and reconstructing proofs on-demand is a good space optimization. The algorithm correctly walks from leaf to root, finding siblings at each level.

One minor observation: the linear search via nodes.iter().position() on line 132 is O(n) per lookup. For typical batch sizes this is fine, but if you ever need to handle very large node sets, consider building a HashMap<u64, usize> index upfront. Not blocking though.

sdk-libs/client/src/indexer/photon_indexer.rs (3)

1489-1551: Clean refactoring using the unified get_queue_elements API.

Good consolidation. The fallback logic on lines 1525-1530 handles both cases well: using original proofs when available, or reconstructing from deduplicated nodes. Using DEFAULT_BATCH_ADDRESS_TREE_HEIGHT instead of a hardcoded value is the right approach.


1679-1762: Thorough transformation of state queue data.

The nested option handling and base58 decoding are correctly implemented. Each field is properly transformed with appropriate error propagation.

One observation: if you find yourself repeating this pattern of Result<Vec<[u8; 32]>, IndexerError> transformations frequently, consider a small helper like:

fn decode_hashes(hashes: &[String]) -> Result<Vec<[u8; 32]>, IndexerError> {
    hashes.iter().map(|h| Hash::from_base58(h)).collect()
}

Not blocking - the current code is clear and correct.


1764-1838: Address queue transformation looks correct.

The node extraction and proof parsing logic is well-structured. Good call including low_element_proofs for debugging/validation purposes - it allows verifying that proof reconstruction produces identical results.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
sdk-libs/client/src/indexer/types.rs (1)

47-110: Fix is_multiple_of on u64 in reconstruct_proof and consider lookup/perf tweaks

The new queue data structures line up well with the Photon/Test indexer changes, but there’s a hard compilation issue and a couple of improvement opportunities in AddressQueueData:

  1. Compilation issue: is_multiple_of on u64.
    In reconstruct_proof, the sibling position is computed with pos.is_multiple_of(2). Primitive u64 doesn’t provide this in std, and there’s no visible dependency here that would add such a method. This will either fail to compile or silently depend on an implicit extension trait. A simple parity check is enough:

    pub fn reconstruct_proof(
        &self,
        address_idx: usize,
        tree_height: u8,
    ) -> Result<Vec<[u8; 32]>, IndexerError> {
        let leaf_index = self.low_element_indices[address_idx];
        let mut proof = Vec::with_capacity(tree_height as usize);
        let mut pos = leaf_index;
    
        for level in 0..tree_height {
  •        let sibling_pos = if pos.is_multiple_of(2) {
    
  •            pos + 1
    
  •        } else {
    
  •            pos - 1
    
  •        };
    
  •        let sibling_pos = if pos % 2 == 0 {
    
  •            pos + 1
    
  •        } else {
    
  •            pos - 1
    
  •        };
         let sibling_idx = Self::encode_node_index(level, sibling_pos);
         if let Some(hash_idx) = self.nodes.iter().position(|&n| n == sibling_idx) {
             proof.push(self.node_hashes[hash_idx]);
         } else {
             return Err(IndexerError::MissingResult {
                 context: "reconstruct_proof".to_string(),
                 message: format!(
                     "Missing proof node at level {} position {} (encoded: {})",
                     level, sibling_pos, sibling_idx
                 ),
             });
         }
         pos /= 2;
     }
    
     Ok(proof)
    
    }
    
    
  1. Lookup performance (optional).
    self.nodes.iter().position on every level yields O(h * N) per proof. For large queues, re-materializing a HashMap<u64, [u8; 32]> (or even a BTreeMap) once per call would give O(h * log N) or O(h) lookups instead. Not urgent, but something to consider if this path ends up hot.

  2. Helper duplication.
    encode_node_index here mirrors the local helper in sdk-libs/program-test/src/indexer/test_indexer.rs. If you change the encoding scheme in one place (e.g., different bit layout), the other will silently diverge. It may be worth centralizing this encoding in a small shared utility to keep client and test representations in lockstep.

The overall shape of OutputQueueData/InputQueueData/StateQueueData/AddressQueueData and QueueElementsResult looks correct for the new consolidated get_queue_elements API once the is_multiple_of issue is fixed.

Also applies to: 112-171

sdk-libs/program-test/src/indexer/test_indexer.rs (1)

25-32: Fix is_multiple_of on u64 and consider avoiding unimplemented!() / deduping helpers

In the new get_queue_elements implementation, a couple of issues are worth addressing:

  1. Compilation issue: is_multiple_of is not defined on u64.
    In add_proof_to_node_map, the sibling calculation uses pos.is_multiple_of(2). Unless you’ve added a custom extension trait and imported it here, this will fail to compile (and we don’t see a num-integer/Integer dependency in this crate). A simple modulo check is sufficient and sidesteps extra dependencies.

    Apply:

    fn add_proof_to_node_map(
        proof: &[[u8; 32]],
        leaf_index: u64,
        node_map: &mut HashMap<u64, [u8; 32]>,
    ) {
        let mut pos = leaf_index;
        for (level, node_hash) in proof.iter().enumerate() {
  •        let sibling_pos = if pos.is_multiple_of(2) {
    
  •            pos + 1
    
  •        } else {
    
  •            pos - 1
    
  •        };
    
  •        let sibling_pos = if pos % 2 == 0 {
    
  •            pos + 1
    
  •        } else {
    
  •            pos - 1
    
  •        };
         let encoded = encode_node_index(level as u8, sibling_pos);
         node_map.entry(encoded).or_insert(*node_hash);
         pos /= 2;
     }
    
    }
    
    (Same pattern should be fixed in `AddressQueueData::reconstruct_proof` in `sdk-libs/client/src/indexer/types.rs`; see separate comment there.)
    
    
  1. #[cfg(not(feature = "v2"))] unimplemented!() on a trait method.
    For the test indexer, this is less dangerous than in production, but any call to get_queue_elements with v2 disabled will panic. If you expect to run tests in non‑v2 configurations, consider returning a benign stub instead (empty queues with current slot) or an IndexerError::NotImplemented to keep failures explicit rather than panicky.

  2. Helper duplication (encode_node_index).
    encode_node_index here duplicates the same (level << 56) | position encoding that already lives in sdk-libs/client/src/indexer/types.rs. If possible, factor this into a shared helper (or re-use the existing one) to avoid future drift between the test and client implementations.

Overall, the structure of the method (distinguishing address vs state trees, building deduplicated node maps, and filling QueueElementsResult) looks sound once the compilation issue is fixed.

Also applies to: 614-892

Comment on lines +1528 to +1766
async fn get_queue_elements(
&mut self,
merkle_tree_pubkey: [u8; 32],
options: super::QueueElementsV2Options,
config: Option<IndexerRpcConfig>,
) -> Result<Response<super::QueueElementsV2Result>, IndexerError> {
let config = config.unwrap_or_default();
self.retry(config.retry_config, || async {
let params = photon_api::models::GetQueueElementsV2PostRequestParams {
tree: bs58::encode(merkle_tree_pubkey).into_string(),
output_queue_start_index: options.output_queue_start_index,
output_queue_limit: options.output_queue_limit,
output_queue_zkp_batch_size: options.output_queue_zkp_batch_size,
input_queue_start_index: options.input_queue_start_index,
input_queue_limit: options.input_queue_limit,
input_queue_zkp_batch_size: options.input_queue_zkp_batch_size,
address_queue_start_index: options.address_queue_start_index,
address_queue_limit: options.address_queue_limit,
address_queue_zkp_batch_size: options.address_queue_zkp_batch_size,
};
_merkle_tree_pubkey: [u8; 32],
_options: super::QueueElementsV2Options,
_config: Option<IndexerRpcConfig>,
) -> Result<Response<super::QueueElementsResult>, IndexerError> {
#[cfg(not(feature = "v2"))]
unimplemented!();

let request = photon_api::models::GetQueueElementsV2PostRequest {
params: Box::new(params),
..Default::default()
};
#[cfg(feature = "v2")]
{
use crate::indexer::OutputQueueData;
let merkle_tree_pubkey = _merkle_tree_pubkey;
let options = _options;
let config = _config.unwrap_or_default();
self.retry(config.retry_config, || async {
// Build nested QueueRequest objects for the new API format
let output_queue = options.output_queue_limit.map(|limit| {
let mut req = photon_api::models::QueueRequest::new(limit);
req.start_index = options.output_queue_start_index;
req.zkp_batch_size = options.output_queue_zkp_batch_size;
req
});

let result = photon_api::apis::default_api::get_queue_elements_v2_post(
&self.configuration,
request,
)
.await?;
let input_queue = options.input_queue_limit.map(|limit| {
let mut req = photon_api::models::QueueRequest::new(limit);
req.start_index = options.input_queue_start_index;
req.zkp_batch_size = options.input_queue_zkp_batch_size;
req
});

let api_response = Self::extract_result_with_error_check(
"get_queue_elements_v2",
result.error,
result.result.map(|r| *r),
)?;
let address_queue = options.address_queue_limit.map(|limit| {
let mut req = photon_api::models::QueueRequest::new(limit);
req.start_index = options.address_queue_start_index;
req.zkp_batch_size = options.address_queue_zkp_batch_size;
req
});

if api_response.context.slot < config.slot {
return Err(IndexerError::IndexerNotSyncedToSlot);
}
let mut params = photon_api::models::GetQueueElementsPostRequestParams::new(
bs58::encode(merkle_tree_pubkey).into_string(),
);
params.output_queue = output_queue;
params.input_queue = input_queue;
params.address_queue = address_queue;

let state_queue = if let Some(state) = api_response.state_queue {
let node_hashes: Result<Vec<[u8; 32]>, IndexerError> = state
.node_hashes
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let initial_root = Hash::from_base58(&state.initial_root)?;
let request = photon_api::models::GetQueueElementsPostRequest {
params: Box::new(params),
..Default::default()
};

let output_queue = if let Some(output) = state.output_queue {
let account_hashes: Result<Vec<[u8; 32]>, IndexerError> = output
.account_hashes
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let old_leaves: Result<Vec<[u8; 32]>, IndexerError> =
output.leaves.iter().map(|h| Hash::from_base58(h)).collect();
let leaves_hash_chains: Result<Vec<[u8; 32]>, IndexerError> = output
.leaves_hash_chains
let result = photon_api::apis::default_api::get_queue_elements_post(
&self.configuration,
request,
)
.await?;

let api_response = Self::extract_result_with_error_check(
"get_queue_elements",
result.error,
result.result.map(|r| *r),
)?;

if api_response.context.slot < config.slot {
return Err(IndexerError::IndexerNotSyncedToSlot);
}

let state_queue = if let Some(state) = api_response.state_queue {
// Extract nodes and node_hashes from combined Node objects
let nodes: Vec<u64> = state.nodes.iter().map(|n| n.index).collect();
let node_hashes: Result<Vec<[u8; 32]>, IndexerError> = state
.nodes
.iter()
.map(|h| Hash::from_base58(h))
.map(|n| Hash::from_base58(&n.hash))
.collect();
let initial_root = Hash::from_base58(&state.initial_root)?;

Some(super::OutputQueueDataV2 {
leaf_indices: output.leaf_indices,
account_hashes: account_hashes?,
old_leaves: old_leaves?,
first_queue_index: output.first_queue_index,
next_index: output.next_index,
leaves_hash_chains: leaves_hash_chains?,
let output_queue = if let Some(output) = state.output_queue {
let account_hashes: Result<Vec<[u8; 32]>, IndexerError> = output
.account_hashes
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let old_leaves: Result<Vec<[u8; 32]>, IndexerError> =
output.leaves.iter().map(|h| Hash::from_base58(h)).collect();
let leaves_hash_chains: Result<Vec<[u8; 32]>, IndexerError> = output
.leaves_hash_chains
.iter()
.map(|h| Hash::from_base58(h))
.collect();

Some(OutputQueueData {
leaf_indices: output.leaf_indices,
account_hashes: account_hashes?,
old_leaves: old_leaves?,
first_queue_index: output.first_queue_index,
next_index: output.next_index,
leaves_hash_chains: leaves_hash_chains?,
})
} else {
None
};

let input_queue = if let Some(input) = state.input_queue {
let account_hashes: Result<Vec<[u8; 32]>, IndexerError> = input
.account_hashes
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let current_leaves: Result<Vec<[u8; 32]>, IndexerError> =
input.leaves.iter().map(|h| Hash::from_base58(h)).collect();
let tx_hashes: Result<Vec<[u8; 32]>, IndexerError> = input
.tx_hashes
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let nullifiers: Result<Vec<[u8; 32]>, IndexerError> = input
.nullifiers
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let leaves_hash_chains: Result<Vec<[u8; 32]>, IndexerError> = input
.leaves_hash_chains
.iter()
.map(|h| Hash::from_base58(h))
.collect();

Some(super::InputQueueData {
leaf_indices: input.leaf_indices,
account_hashes: account_hashes?,
current_leaves: current_leaves?,
tx_hashes: tx_hashes?,
nullifiers: nullifiers?,
first_queue_index: input.first_queue_index,
leaves_hash_chains: leaves_hash_chains?,
})
} else {
None
};

Some(super::StateQueueData {
nodes,
node_hashes: node_hashes?,
initial_root,
root_seq: state.root_seq,
output_queue,
input_queue,
})
} else {
None
};

let input_queue = if let Some(input) = state.input_queue {
let account_hashes: Result<Vec<[u8; 32]>, IndexerError> = input
.account_hashes
// Transform AddressQueueDataV2
let address_queue = if let Some(address) = api_response.address_queue {
let addresses: Result<Vec<[u8; 32]>, IndexerError> = address
.addresses
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let current_leaves: Result<Vec<[u8; 32]>, IndexerError> =
input.leaves.iter().map(|h| Hash::from_base58(h)).collect();
let tx_hashes: Result<Vec<[u8; 32]>, IndexerError> = input
.tx_hashes

let low_element_values: Result<Vec<[u8; 32]>, IndexerError> = address
.low_element_values
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let nullifiers: Result<Vec<[u8; 32]>, IndexerError> = input
.nullifiers

let low_element_next_values: Result<Vec<[u8; 32]>, IndexerError> = address
.low_element_next_values
.iter()
.map(|h| Hash::from_base58(h))
.collect();
let leaves_hash_chains: Result<Vec<[u8; 32]>, IndexerError> = input

// Extract nodes and node_hashes from combined Node objects
// Proofs are reconstructed from nodes using AddressQueueDataV2::reconstruct_proof()
let nodes: Vec<u64> = address.nodes.iter().map(|n| n.index).collect();
let node_hashes: Result<Vec<[u8; 32]>, IndexerError> = address
.nodes
.iter()
.map(|n| Hash::from_base58(&n.hash))
.collect();

let initial_root = Hash::from_base58(&address.initial_root)?;

let leaves_hash_chains: Result<Vec<[u8; 32]>, IndexerError> = address
.leaves_hash_chains
.iter()
.map(|h| Hash::from_base58(h))
.collect();

Some(super::InputQueueDataV2 {
leaf_indices: input.leaf_indices,
account_hashes: account_hashes?,
current_leaves: current_leaves?,
tx_hashes: tx_hashes?,
nullifiers: nullifiers?,
first_queue_index: input.first_queue_index,
let subtrees: Result<Vec<[u8; 32]>, IndexerError> = address
.subtrees
.iter()
.map(|h| Hash::from_base58(h))
.collect();

// Parse low_element_proofs for debugging/validation
let low_element_proofs: Result<Vec<Vec<[u8; 32]>>, IndexerError> = address
.low_element_proofs
.iter()
.map(|proof| {
proof.iter().map(|h| Hash::from_base58(h)).collect::<Result<
Vec<[u8; 32]>,
IndexerError,
>>(
)
})
.collect();

Some(super::AddressQueueData {
addresses: addresses?,
queue_indices: address.queue_indices,
low_element_values: low_element_values?,
low_element_next_values: low_element_next_values?,
low_element_indices: address.low_element_indices,
low_element_next_indices: address.low_element_next_indices,
nodes,
node_hashes: node_hashes?,
initial_root,
leaves_hash_chains: leaves_hash_chains?,
subtrees: subtrees?,
start_index: address.start_index,
root_seq: address.root_seq,
low_element_proofs: low_element_proofs?,
})
} else {
None
};

Some(super::StateQueueDataV2 {
nodes: state.nodes,
node_hashes: node_hashes?,
initial_root,
root_seq: state.root_seq,
output_queue,
input_queue,
})
} else {
None
};

// Transform AddressQueueDataV2
let address_queue = if let Some(address) = api_response.address_queue {
let addresses: Result<Vec<[u8; 32]>, IndexerError> = address
.addresses
.iter()
.map(|h| Hash::from_base58(h))
.collect();

let low_element_values: Result<Vec<[u8; 32]>, IndexerError> = address
.low_element_values
.iter()
.map(|h| Hash::from_base58(h))
.collect();

let low_element_next_values: Result<Vec<[u8; 32]>, IndexerError> = address
.low_element_next_values
.iter()
.map(|h| Hash::from_base58(h))
.collect();

let low_element_proofs: Result<Vec<Vec<[u8; 32]>>, IndexerError> = address
.low_element_proofs
.iter()
.map(|proof_vec| {
proof_vec
.iter()
.map(|h| Hash::from_base58(h))
.collect::<Result<Vec<[u8; 32]>, IndexerError>>()
})
.collect();

let node_hashes: Result<Vec<[u8; 32]>, IndexerError> = address
.node_hashes
.iter()
.map(|h| Hash::from_base58(h))
.collect();

let initial_root = Hash::from_base58(&address.initial_root)?;

Some(super::AddressQueueDataV2 {
addresses: addresses?,
low_element_values: low_element_values?,
low_element_next_values: low_element_next_values?,
low_element_indices: address.low_element_indices,
low_element_next_indices: address.low_element_next_indices,
low_element_proofs: low_element_proofs?,
nodes: address.nodes,
node_hashes: node_hashes?,
initial_root,
first_queue_index: address.start_index,
Ok(Response {
context: Context {
slot: api_response.context.slot,
},
value: super::QueueElementsResult {
state_queue,
address_queue,
},
})
} else {
None
};

Ok(Response {
context: Context {
slot: api_response.context.slot,
},
value: super::QueueElementsV2Result {
state_queue,
address_queue,
},
})
})
.await
.await
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

unimplemented!() should return a structured error; verify Photon error type compatibility

Two points to address:

  1. Non‑v2 builds currently panic.
    The #[cfg(not(feature = "v2"))] branch calls unimplemented!(), which panics rather than returning a clean error. However, the suggested IndexerError::NotImplemented variant does not exist in the enum. Use IndexerError::Unknown instead, or add a NotImplemented variant to the enum:

    #[cfg(not(feature = "v2"))]
    -    unimplemented!();
    +    return Err(IndexerError::Unknown(
    +        "get_queue_elements is only available with the `v2` feature on PhotonIndexer".to_string(),
    +    ));
  2. Verify Photon API error type compatibility.
    The generic extract_result_with_error_check::<E> method already handles different error types (confirmed by its usage in get_queue_info with a similar pattern). The GetQueueElementsPost200ResponseError from get_queue_elements_post should work seamlessly with the same approach, so no adapter is needed. If compilation succeeds, the error handling is correct.

Copy link
Contributor

@SwenSchaeferjohann SwenSchaeferjohann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@SwenSchaeferjohann SwenSchaeferjohann merged commit 73b991d into main Dec 8, 2025
36 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants