refactor: forester: add default tree / epoch#2127
Conversation
WalkthroughThis PR introduces log-based account cleanup for compressible tokens by adding a new LogSubscriber component that parses program logs to identify and remove closed accounts, while migrating shutdown channels from oneshot to broadcast to support multiple subscribers across the system. Changes
Sequence DiagramsequenceDiagram
participant Program as Registry Program
participant Logs as Solana Logs
participant WebSocket as WebSocket/Pubsub
participant LogSub as LogSubscriber
participant Tracker as CompressibleAccountTracker
Program->>Logs: emit "Program log: compress_and_close:<pubkey>"
Logs->>WebSocket: propagate log message
WebSocket->>LogSub: deliver RpcLogsResponse
LogSub->>LogSub: parse log prefix & extract pubkey
LogSub->>Tracker: remove account from tracked state
Note over LogSub,Tracker: Closed accounts cleaned up via logs<br/>instead of RPC sync calls
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Areas requiring extra attention:
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockand included by nonextask/src/create_ctoken_account.rsis excluded by none and included by none
📒 Files selected for processing (13)
forester/Cargo.toml(1 hunks)forester/src/compressible/compressor.rs(5 hunks)forester/src/compressible/config.rs(1 hunks)forester/src/compressible/mod.rs(1 hunks)forester/src/compressible/state.rs(0 hunks)forester/src/compressible/subscriber.rs(3 hunks)forester/src/epoch_manager.rs(9 hunks)forester/src/lib.rs(3 hunks)forester/src/main.rs(1 hunks)forester/tests/e2e_test.rs(1 hunks)forester/tests/test_batch_append_spent.rs(1 hunks)forester/tests/test_compressible_ctoken.rs(3 hunks)programs/registry/src/compressible/compress_and_close.rs(1 hunks)
💤 Files with no reviewable changes (1)
- forester/src/compressible/state.rs
🧰 Additional context used
📓 Path-based instructions (3)
forester/src/main.rs
📄 CodeRabbit inference engine (forester/README.md)
Required configuration must include:
--rpc-url,--ws-rpc-url,--indexer-url,--prover-url,--payer, and--derivationparameters
Files:
forester/src/main.rs
programs/**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests in programs must not depend on light-test-utils; integration tests must be located in program-tests/
Files:
programs/registry/src/compressible/compress_and_close.rs
forester/**/*e2e*.rs
📄 CodeRabbit inference engine (forester/README.md)
forester/**/*e2e*.rs: Test environment variables should useTEST_MODEto specify 'local' or 'devnet' mode (default: devnet)
Test feature flagsTEST_V1_STATE,TEST_V2_STATE,TEST_V1_ADDRESS, andTEST_V2_ADDRESSshould default totrueand control which test scenarios run
Devnet mode tests requirePHOTON_RPC_URL,PHOTON_WSS_RPC_URL,PHOTON_INDEXER_URL,PHOTON_PROVER_URL, andPHOTON_API_KEYenvironment variables
Local validator mode tests should automatically spawn a local validator, start a local prover service, and use predefined local URLs (localhost:8899 for RPC, localhost:8784 for indexer)
Tests should automatically skip minting tokens, executing transactions, and root verification for disabled test types
Files:
forester/tests/e2e_test.rs
🧠 Learnings (98)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Account closure must distribute lamports according to: Solana rent exemption → returned to user, completed epoch rent → rent recipient, partial epoch rent → user, compression incentive → forester node
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
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Accounts become compressible when they lack rent for the current epoch plus the next epoch (compressibility window).
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run batched tree transfer test using `cargo test-sbf -p compressed-token-test -- test_transfer_with_photon_and_batched_tree` and apply retry logic in CI (max 3 attempts, 5s delay) due to known flakiness
Applied to files:
forester/tests/test_batch_append_spent.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:48.449Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Account closure must distribute lamports according to: Solana rent exemption → returned to user, completed epoch rent → rent recipient, partial epoch rent → user, compression incentive → forester node
Applied to files:
forester/tests/test_batch_append_spent.rsforester/src/main.rsforester/src/lib.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export new wrapper modules in `account_compression_cpi/mod.rs` using `pub mod new_operation;` and `pub use new_operation::*;`, then import in `lib.rs`
Applied to files:
forester/src/compressible/mod.rsforester/src/lib.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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/**/mod.rs : Module declaration should be kept in `mod.rs`
Applied to files:
forester/src/compressible/mod.rsforester/src/main.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:
forester/src/compressible/mod.rsforester/src/lib.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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:
forester/src/compressible/mod.rsprograms/registry/src/compressible/compress_and_close.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 : Implement state validation methods (`validate_active`, `validate_not_inactive`) on CompressibleConfig account structure
Applied to files:
forester/src/compressible/mod.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:48.449Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Implement account compressibility states in the following order: Funded (rent for current + 1 epoch) → Compressible (lacks rent for current + 1 epoch) → Claimable (funded but past epochs unclaimed)
Applied to files:
forester/src/compressible/mod.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/epoch_manager.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 : Implement PDA derivation methods (`derive_pda`, `derive_v1_config_pda`) on CompressibleConfig for account discovery
Applied to files:
forester/src/compressible/mod.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Anchor deserialization of CompressibleConfig must use `AccountDeserialize::try_deserialize()` which automatically validates the discriminator to prevent invalid account type mismatches
Applied to files:
forester/src/compressible/mod.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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:
forester/src/compressible/mod.rsforester/src/compressible/compressor.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:
forester/src/compressible/mod.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : CompressibleConfig account state in Solana programs must validate active state using `validate_active()` method before allowing new compressible token account creation
Applied to files:
forester/src/compressible/mod.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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/**/pack_unpack.rs : Pubkey compression logic and `PackedXxx` struct generation with Pack/Unpack trait implementations should be in `pack_unpack.rs`
Applied to files:
forester/src/main.rsforester/src/compressible/compressor.rsprograms/registry/src/compressible/compress_and_close.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/**/traits.rs : Core trait implementations (`HasCompressionInfo`, `CompressAs`, `Compressible`) should be defined in `traits.rs`
Applied to files:
forester/src/main.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 : Implement default initialization for CToken V1 config in CompressibleConfig structure
Applied to files:
forester/src/main.rsforester/src/compressible/config.rsforester/src/epoch_manager.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 : Charge rollover fee when creating output compressed accounts (insertion into output queue), not on tree operations
Applied to files:
forester/src/compressible/compressor.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/epoch_manager.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/**/instructions.rs : Compress/decompress instruction handlers and context struct generation should be implemented in `instructions.rs`, with compress using PDA-only and decompress supporting full PDA + ctoken
Applied to files:
forester/src/compressible/compressor.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Create wrapper instruction module at `src/account_compression_cpi/new_operation.rs` with `NewOperationContext` struct defining required accounts
Applied to files:
forester/src/compressible/compressor.rsprograms/registry/src/compressible/compress_and_close.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run account-compression tests using `cargo test-sbf -p account-compression-test` to test core account compression program (Merkle tree management)
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/epoch_manager.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.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 : Use `check_account_balance_is_rent_exempt` function from `light-account-checks` to verify rent exemption for both queue_account and merkle_tree_account during initialization
Applied to files:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/src/compressible/subscriber.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.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: State and instruction data structures must be defined in the separate 'light-ctoken-interface' crate (program-libs/ctoken-types/) to allow SDKs to import types without pulling in program dependencies
Applied to files:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.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: Applies to programs/compressed-token/program/src/close_token_account.rs : Close token account instruction must return rent exemption to rent recipient if compressible and remaining lamports to destination account
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/compressible/subscriber.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:
forester/src/compressible/compressor.rsforester/src/compressible/subscriber.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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/compressible/compressor.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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 output queue must use BatchedMerkleTreeAccount::update_tree_from_output_queue_account method with ZKP verification
Applied to files:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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/compressible/compressor.rsforester/src/epoch_manager.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 state tree with queue_account pubkey in tree metadata and set rollover_fee to 0 (charged on queue insertion, not tree operations)
Applied to files:
forester/src/compressible/compressor.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/compressible/compressor.rsforester/src/compressible/config.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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/**/initialize_state_tree.rs : State tree initialization must create two Solana accounts: BatchedMerkleTreeAccount with integrated input queue and separate BatchedQueueAccount
Applied to files:
forester/src/compressible/compressor.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/lib.rs : In wrapper instruction handler in `lib.rs`, load account metadata, determine work units, call `check_forester()`, then call the processing function
Applied to files:
forester/src/compressible/compressor.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: Applies to programs/compressed-token/program/src/create_token_account.rs : Create token account instructions (CreateTokenAccount, CreateAssociatedCTokenAccount, CreateAssociatedTokenAccountIdempotent) require ACTIVE config validation only
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.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: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer instruction (discriminator: 3) must implement SPL-compatible transfers between decompressed accounts
Applied to files:
forester/src/compressible/compressor.rsprograms/registry/src/compressible/compress_and_close.rsforester/src/compressible/subscriber.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/compressible/compressor.rs
📚 Learning: 2025-11-24T17:53:53.971Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: forester/README.md:0-0
Timestamp: 2025-11-24T17:53:53.971Z
Learning: Applies to forester/src/**/*{auth,key,keypair}*.rs : The `FORESTER_KEYPAIR` environment variable should support both base58 format and byte array format like `[1,2,3,...]` for keypair specification
Applied to files:
forester/Cargo.toml
📚 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: Applies to sdk-tests/sdk-ctoken-test/**/Cargo.toml : Use path references in Cargo.toml dependencies pointing to `/Users/ananas/dev/light-protocol2/sdk-libs/` for light-ctoken-sdk, light-ctoken-types, light-sdk, light-sdk-types, and light-program-test
Applied to files:
forester/Cargo.toml
📚 Learning: 2025-11-24T17:53:53.971Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: forester/README.md:0-0
Timestamp: 2025-11-24T17:53:53.971Z
Learning: Applies to forester/src/**/*{transaction,batch}*.rs : Transaction V1 processing should configure `--max-concurrent-sends 50`, `--legacy-ixs-per-tx 1`, `--transaction-max-concurrent-batches 20`, `--cu-limit 1000000`, and `--enable-priority-fees false` by default
Applied to files:
forester/src/compressible/config.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 : Validate that ZKP batch sizes must be 10 or 500 (only supported circuit sizes)
Applied to files:
forester/src/compressible/config.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 batch size parameters in `InitStateTreeAccountsInstructionData` struct: input_queue_batch_size (u64, default 15,000), output_queue_batch_size (u64, default 15,000), input_queue_zkp_batch_size (u64, default 500), and output_queue_zkp_batch_size (u64, default 500)
Applied to files:
forester/src/compressible/config.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 bloom filter configuration for input queue: bloom_filter_capacity (u64, default batch_size * 8) and bloom_filter_num_iters (u64, default 3 for test and 10 for production)
Applied to files:
forester/src/compressible/config.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : When deserializing CompressibleConfig accounts, skip the 8-byte discriminator `[180, 4, 231, 26, 220, 144, 55, 168]` before deserialization in zero-copy implementations using bytemuck::pod_from_bytes
Applied to files:
forester/src/compressible/config.rsforester/src/epoch_manager.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : CompressibleConfig PDA must be derived using seeds `[b"compressible_config", version.to_le_bytes()]` with the stored bump seed for deterministic account address generation in Light Protocol
Applied to files:
forester/src/compressible/config.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T17:53:53.971Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: forester/README.md:0-0
Timestamp: 2025-11-24T17:53:53.971Z
Learning: Applies to forester/src/**/*{pool,connection,rpc}*.rs : RPC pool settings should use `--rpc-pool-size 10` (default), `--rpc-pool-connection-timeout-secs 15`, and `--rpc-pool-idle-timeout-secs 300` for optimal connection pooling
Applied to files:
forester/src/compressible/config.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 : Validate that bloom filter capacity must be divisible by 8 and must be >= batch_size * 8
Applied to files:
forester/src/compressible/config.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:
forester/src/compressible/config.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 bloom_filter_capacity is divisible by 8 in `src/initialize_address_tree.rs`. Capacity must be >= batch_size * 8.
Applied to files:
forester/src/compressible/config.rs
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run compressed token core tests using `cargo test-sbf -p compressed-token-test --test ctoken`, `--test v1`, `--test mint`, and `--test transfer2`
Applied to files:
forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run Light system program compression tests using `cargo test-sbf -p system-test -- test_with_compression` and `cargo test-sbf -p system-test --test test_re_init_cpi_account` to test compressed account operations
Applied to files:
forester/tests/test_compressible_ctoken.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: Applies to sdk-tests/sdk-ctoken-test/**/{lib,main}.rs : Clone AccountInfo structs when building CPI builder pattern account structs to avoid borrow checker issues
Applied to files:
forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-12-06T00:49:57.458Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-token-test/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:57.458Z
Learning: Applies to sdk-tests/sdk-token-test/**/*test.rs : Tests should use light-ctoken-sdk functions from sdk-libs/compressed-token-sdk for testing ctoken instructions
Applied to files:
forester/tests/test_compressible_ctoken.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/rent.rs : Implement rent calculation functions including `rent_curve_per_epoch`, `calculate_rent_and_balance`, `claimable_lamports`, and `calculate_close_lamports` in rent.rs
Applied to files:
forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `claimable_lamports` function to return None if account is compressible, otherwise return Some(amount) for completed epochs only (excluding current ongoing epoch).
Applied to files:
forester/tests/test_compressible_ctoken.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `calculate_close_lamports` function to return (u64, u64) tuple splitting lamports between rent recipient and user, with rent recipient receiving completed epochs and user receiving partial epoch remainder.
Applied to files:
forester/tests/test_compressible_ctoken.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:48.449Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Light Protocol accounts must satisfy both Solana rent exemption and Light Protocol rent requirements, plus an 11,000 lamport compression incentive during creation
Applied to files:
forester/tests/test_compressible_ctoken.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: Applies to programs/compressed-token/program/src/transfer2/*.rs : Transfer2 instruction (discriminator: 101) supports batch operations including Compress, Decompress, and CompressAndClose with multi-mint support and sum checks
Applied to files:
programs/registry/src/compressible/compress_and_close.rs
📚 Learning: 2025-11-24T18:01:54.689Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:54.689Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Close Token Account documentation must cover closing decompressed token accounts with rent distribution
Applied to files:
programs/registry/src/compressible/compress_and_close.rs
📚 Learning: 2025-12-07T03:17:42.199Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-07T03:17:42.199Z
Learning: Applies to program-libs/account-checks/**/*.rs : Use AccountInfoTrait abstraction for unified account handling across both solana-program and pinocchio SDKs
Applied to files:
forester/src/compressible/subscriber.rs
📚 Learning: 2025-11-24T17:58:50.237Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_CHECKS.md:0-0
Timestamp: 2025-11-24T17:58:50.237Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/checks.rs : Use generic `AccountInfoTrait` parameter for all account validation functions to enable compatibility with both Solana and Pinocchio runtimes
Applied to files:
forester/src/compressible/subscriber.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:
forester/src/compressible/subscriber.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:
forester/src/compressible/subscriber.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:
forester/src/epoch_manager.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/**/rollover_{state,address}_tree.rs : Trees must support rollover when reaching capacity (2^height leaves) by creating a new tree and marking the old tree as rolled over, preserving old tree roots
Applied to files:
forester/src/epoch_manager.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/epoch_manager.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:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: When forester PDA is present, `check_forester()` must validate epoch registration and eligibility, track work, and require network fee; when absent, validate that authority matches the tree's designated forester (for private trees)
Applied to files:
forester/src/epoch_manager.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 : Transition batch state to `Inserted` when all ZKP batches are complete and increment `pending_batch_index` to switch to other batch
Applied to files:
forester/src/epoch_manager.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 : Batch nullify operations must check that tree type is TreeType::StateV2 before processing, verify batch has ready ZKP batches (num_full_zkp_batches > num_inserted_zkp_batches), and reject if batch is already in Inserted state.
Applied to files:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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 : Batch address append operations must check that tree type is TreeType::AddressV2 before processing, verify tree capacity constraint (tree.next_index + zkp_batch_size <= tree_capacity), verify batch has ready ZKP batches (num_full_zkp_batches > num_inserted_zkp_batches), and reject if batch is already in Inserted state.
Applied to files:
forester/src/epoch_manager.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/error.rs : PropagateHasher errors from light-hasher module with 7xxx code range in error handling
Applied to files:
forester/src/epoch_manager.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:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `calculate_rent_and_balance` function to determine compressibility by checking if account balance covers required rent for epochs since last claim, returning (bool, u64) tuple.
Applied to files:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Accounts become compressible when they lack rent for the current epoch plus the next epoch (compressibility window).
Applied to files:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `get_last_funded_epoch` function to determine the last epoch number covered by rent payments.
Applied to files:
forester/src/epoch_manager.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : CompressibleConfig rent_sponsor PDA and compression_authority PDA must be derived separately using `get_rent_sponsor_seeds()` and `get_compression_authority_seeds()` helper methods with version-specific seeds
Applied to files:
forester/src/epoch_manager.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 : Insert Into Output Queue: Inserts a compressed account hash into the output queue's currently processing batch by calling `BatchedQueueAccount::insert_into_current_batch` with hash_chain_value and current_slot parameters, updating value vec, hash chain, and managing batch state transitions in src/queue.rs
Applied to files:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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`, insert compressed_account_hash into bloom filter (NOT the nullifier) for non-inclusion checks in subsequent transactions
Applied to files:
forester/src/epoch_manager.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`, perform non-inclusion check to ensure compressed_account_hash does not exist in any bloom filter to prevent double-spending
Applied to files:
forester/src/epoch_manager.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 : After inserting an address into the batch, check if `num_inserted_elements == batch_size`. If true, transition batch state from `Fill` to `Full`, increment `currently_processing_batch_index` to switch to the other batch, and update `pending_batch_index` to mark this batch ready for tree update.
Applied to files:
forester/src/epoch_manager.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/epoch_manager.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 : Batch must have ready ZKP batches for insertion: verify `num_full_zkp_batches > num_inserted_zkp_batches`; error with `BatchNotReady` (14301) if not ready
Applied to files:
forester/src/epoch_manager.rs
🧬 Code graph analysis (4)
forester/src/main.rs (1)
forester/src/errors.rs (1)
channel(208-212)
forester/src/lib.rs (1)
forester/src/compressible/subscriber.rs (2)
new(36-46)new(175-185)
forester/tests/test_compressible_ctoken.rs (2)
forester/src/compressible/subscriber.rs (2)
new(36-46)new(175-185)forester/src/compressible/state.rs (1)
new(59-63)
forester/src/compressible/subscriber.rs (2)
forester/src/compressible/state.rs (1)
new(59-63)forester/src/compressible/bootstrap.rs (1)
pubkey_str(54-54)
⏰ 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). (6)
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: Test program-libs-slow
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: Forester e2e test
| fn handle_log_notification(&self, response: RpcResponse<RpcLogsResponse>) { | ||
| let logs_response = response.value; | ||
|
|
||
| // Skip failed transactions | ||
| if logs_response.err.is_some() { | ||
| debug!("Skipping failed transaction {}", logs_response.signature); | ||
| return; | ||
| } | ||
|
|
||
| // Parse logs looking for compress_and_close entries | ||
| let mut removed_count = 0; | ||
| for log in &logs_response.logs { | ||
| // Look for our log prefix: "Program log: compress_and_close:<pubkey>" | ||
| // The actual log format is "Program log: compress_and_close:<pubkey>" | ||
| if let Some(pubkey_str) = log | ||
| .strip_prefix("Program log: ") | ||
| .and_then(|s| s.strip_prefix(COMPRESS_AND_CLOSE_LOG_PREFIX)) | ||
| { | ||
| match Pubkey::from_str(pubkey_str) { | ||
| Ok(pubkey) => { | ||
| if self.tracker.remove(&pubkey).is_some() { | ||
| debug!( | ||
| "Removed closed account {} from tracker (compress_and_close log)", | ||
| pubkey | ||
| ); | ||
| removed_count += 1; | ||
| } | ||
| } | ||
| Err(e) => { | ||
| error!( | ||
| "Invalid pubkey in compress_and_close log '{}': {}", | ||
| pubkey_str, e | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if removed_count > 0 { | ||
| info!( | ||
| "Removed {} closed accounts from transaction {}", | ||
| removed_count, logs_response.signature | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for the log format in the registry program source
rg -n "compress_and_close:" --type rustRepository: Lightprotocol/light-protocol
Length of output: 1734
Log parsing is robust but tightly coupled to log format.
The log parsing logic correctly:
- Skips failed transactions
- Strips the "Program log: " prefix before checking for the close prefix
- Handles invalid pubkey parsing with error logging
- Tracks removed accounts for batch logging
The log format "Program log: compress_and_close:<pubkey>" is an implicit contract with the registry program (emitted via msg!() in programs/registry/src/compressible/compress_and_close.rs). If the registry changes its log format, this will silently stop working. Consider adding a metric or periodic health check to verify the subscriber is still receiving expected events.
|
|
||
| if self.compressible_tracker.is_some() && self.config.compressible_config.is_some() { | ||
| let compression_tree_accounts = TreeAccounts { | ||
| merkle_tree: solana_sdk::pubkey::Pubkey::default(), | ||
| queue: solana_sdk::pubkey::Pubkey::default(), | ||
| tree_type: TreeType::Unknown, | ||
| is_rolledover: false, | ||
| }; | ||
| let tree_schedule = TreeForesterSchedule::new_with_schedule( | ||
| &compression_tree_accounts, | ||
| slot, | ||
| &epoch_info.forester_epoch_pda, | ||
| &epoch_info.epoch_pda, | ||
| )?; | ||
| epoch_info.trees.insert(0, tree_schedule); | ||
| debug!("Added compression tree to epoch {}", epoch_info.epoch.epoch); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Compression tree scheduling uses TreeType::Unknown as a marker.
This pattern uses TreeType::Unknown with default pubkeys to represent a synthetic "compression tree" in the schedule. While functional, this semantic overloading could confuse future maintainers who expect Unknown to mean "unrecognized type."
Consider introducing a dedicated TreeType::Compression variant or documenting this convention prominently. For now, should_skip_tree at line 2263 correctly returns false for Unknown, ensuring compression is never skipped.
🤖 Prompt for AI Agents
In forester/src/epoch_manager.rs around lines 930 to 946, the code uses
TreeType::Unknown as a marker for synthetic compression trees which overloads
the meaning of Unknown; change this by adding a dedicated TreeType::Compression
enum variant (and update any serialization/deserialization, From/Into,
Display/Debug impls and pattern matches) and replace TreeType::Unknown with
TreeType::Compression when constructing the compression_tree_accounts; also
update should_skip_tree and any match arms that rely on Unknown so semantics
remain correct, run CI/tests to ensure no other match exhaustiveness or
(de)serialization breaks.
| // Emit logs for closed accounts (used by forester to track closures) | ||
| for idx in &indices { | ||
| if let Ok(source_account) = transfer2_accounts | ||
| .packed_accounts | ||
| .get_u8(idx.source_index, "source_account") | ||
| { | ||
| msg!("compress_and_close:{}", source_account.key); | ||
| } | ||
| } |
There was a problem hiding this comment.
Critical: Logs emitted before operation completes, risking false-positive tracking.
The closure logs are emitted before the actual invoke_signed CPI call (lines 84-88). If the CPI fails for any reason (e.g., validation errors, insufficient compute, failed constraints), the forester LogSubscriber will have already received closure events for accounts that were never actually closed. This creates a dangerous inconsistency between the forester's tracked state and the actual on-chain state.
Move the logging loop to execute after the successful CPI call:
- // Emit logs for closed accounts (used by forester to track closures)
- for idx in &indices {
- if let Ok(source_account) = transfer2_accounts
- .packed_accounts
- .get_u8(idx.source_index, "source_account")
- {
- msg!("compress_and_close:{}", source_account.key);
- }
- }
-
let instruction = compress_and_close_ctoken_accounts_with_indices(
ctx.accounts.authority.key(),
authority_index,
destination_index,
&indices,
&transfer2_accounts.packed_accounts,
)?;
// Prepare signer seeds for compression_authority PDA
let version_bytes = ctx.accounts.compressible_config.version.to_le_bytes();
let compression_authority_bump = ctx.accounts.compressible_config.compression_authority_bump;
let signer_seeds = &[
b"compression_authority".as_slice(),
version_bytes.as_slice(),
&[compression_authority_bump],
];
// Execute CPI with compression_authority PDA as signer
anchor_lang::solana_program::program::invoke_signed(
&instruction,
transfer2_accounts.to_account_infos().as_slice(),
&[signer_seeds],
)?;
+
+ // Emit logs for closed accounts (used by forester to track closures)
+ for idx in &indices {
+ if let Ok(source_account) = transfer2_accounts
+ .packed_accounts
+ .get_u8(idx.source_index, "source_account")
+ {
+ msg!("compress_and_close:{}", source_account.key);
+ }
+ }
Ok(())📝 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.
| // Emit logs for closed accounts (used by forester to track closures) | |
| for idx in &indices { | |
| if let Ok(source_account) = transfer2_accounts | |
| .packed_accounts | |
| .get_u8(idx.source_index, "source_account") | |
| { | |
| msg!("compress_and_close:{}", source_account.key); | |
| } | |
| } |
🤖 Prompt for AI Agents
In programs/registry/src/compressible/compress_and_close.rs around lines 56-64
(and noting the CPI call at ~84-88), the loop that emits "compress_and_close"
logs currently runs before the invoke_signed CPI, which can produce
false-positive closure events if the CPI fails; move that entire logging loop so
it runs immediately after the invoke_signed call and only when the CPI returns
Ok, preserving the same indices and transfer2_accounts variables and scopes;
ensure no early returns or error paths execute the logging and keep the log
format unchanged so forester receives events only for actually completed
closures.
| for idx in &indices { | ||
| if let Ok(source_account) = transfer2_accounts | ||
| .packed_accounts | ||
| .get_u8(idx.source_index, "source_account") | ||
| { | ||
| msg!("compress_and_close:{}", source_account.key); | ||
| } | ||
| } |
There was a problem hiding this comment.
Silent error handling could cause missed closure tracking events.
The if let Ok(...) pattern silently skips any account that fails retrieval via get_u8. Since these logs are explicitly used by the forester to track closures (as noted in the comment), silently dropping failed retrievals means the forester could miss accounts that were actually closed if the index references were malformed or if account access failed for other reasons.
Consider whether this silent failure is acceptable for your monitoring requirements. If the forester must track all closures reliably, you should either:
- Log a warning when retrieval fails (to aid debugging), or
- Propagate the error to fail fast if an invalid index is provided
Apply this diff if you want to log retrieval failures for observability:
// Emit logs for closed accounts (used by forester to track closures)
for idx in &indices {
- if let Ok(source_account) = transfer2_accounts
+ match transfer2_accounts
.packed_accounts
.get_u8(idx.source_index, "source_account")
{
- msg!("compress_and_close:{}", source_account.key);
+ Ok(source_account) => {
+ msg!("compress_and_close:{}", source_account.key);
+ }
+ Err(e) => {
+ msg!("compress_and_close:failed_to_retrieve_account_at_index:{}", idx.source_index);
+ }
}
}📝 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.
| for idx in &indices { | |
| if let Ok(source_account) = transfer2_accounts | |
| .packed_accounts | |
| .get_u8(idx.source_index, "source_account") | |
| { | |
| msg!("compress_and_close:{}", source_account.key); | |
| } | |
| } | |
| for idx in &indices { | |
| match transfer2_accounts | |
| .packed_accounts | |
| .get_u8(idx.source_index, "source_account") | |
| { | |
| Ok(source_account) => { | |
| msg!("compress_and_close:{}", source_account.key); | |
| } | |
| Err(e) => { | |
| msg!("compress_and_close:failed_to_retrieve_account_at_index:{}", idx.source_index); | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In programs/registry/src/compressible/compress_and_close.rs around lines 57 to
64, the current if let Ok(...) silently ignores failures from
transfer2_accounts.packed_accounts.get_u8(...), which can hide missing closure
events; change the code to handle the Err branch: match on the Result and on Ok
log the source_account.key as before, and on Err call msg! to emit a warning
including the offending index and the error (or alternatively return/propagate
the error if you want fail-fast behavior); this preserves existing behavior for
successful reads while making retrieval failures observable for the forester.
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
forester/src/epoch_manager.rs (1)
2257-2265: Consider adding test coverage forTreeType::Unknownhandling.The function correctly returns
falseforUnknown, ensuring compression trees are never skipped. However, the existing tests don't cover this case. A simple addition would strengthen confidence:+ #[test] + fn test_should_skip_tree_unknown_never_skipped() { + // Even with all skip flags enabled, Unknown (compression) should never be skipped + let config = create_test_config_with_skip_flags(true, true, true, true); + assert!(!should_skip_tree(&config, &TreeType::Unknown)); + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockand included by nonextask/src/create_ctoken_account.rsis excluded by none and included by none
📒 Files selected for processing (13)
forester/Cargo.toml(1 hunks)forester/src/compressible/compressor.rs(5 hunks)forester/src/compressible/config.rs(1 hunks)forester/src/compressible/mod.rs(1 hunks)forester/src/compressible/state.rs(0 hunks)forester/src/compressible/subscriber.rs(3 hunks)forester/src/epoch_manager.rs(9 hunks)forester/src/lib.rs(3 hunks)forester/src/main.rs(1 hunks)forester/tests/e2e_test.rs(1 hunks)forester/tests/test_batch_append_spent.rs(1 hunks)forester/tests/test_compressible_ctoken.rs(3 hunks)programs/registry/src/compressible/compress_and_close.rs(1 hunks)
💤 Files with no reviewable changes (1)
- forester/src/compressible/state.rs
🧰 Additional context used
📓 Path-based instructions (3)
programs/**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests in programs must not depend on light-test-utils; integration tests must be located in program-tests/
Files:
programs/registry/src/compressible/compress_and_close.rs
forester/src/main.rs
📄 CodeRabbit inference engine (forester/README.md)
Required configuration must include:
--rpc-url,--ws-rpc-url,--indexer-url,--prover-url,--payer, and--derivationparameters
Files:
forester/src/main.rs
forester/**/*e2e*.rs
📄 CodeRabbit inference engine (forester/README.md)
forester/**/*e2e*.rs: Test environment variables should useTEST_MODEto specify 'local' or 'devnet' mode (default: devnet)
Test feature flagsTEST_V1_STATE,TEST_V2_STATE,TEST_V1_ADDRESS, andTEST_V2_ADDRESSshould default totrueand control which test scenarios run
Devnet mode tests requirePHOTON_RPC_URL,PHOTON_WSS_RPC_URL,PHOTON_INDEXER_URL,PHOTON_PROVER_URL, andPHOTON_API_KEYenvironment variables
Local validator mode tests should automatically spawn a local validator, start a local prover service, and use predefined local URLs (localhost:8899 for RPC, localhost:8784 for indexer)
Tests should automatically skip minting tokens, executing transactions, and root verification for disabled test types
Files:
forester/tests/e2e_test.rs
🧠 Learnings (98)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:54.689Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Close Token Account documentation must cover closing decompressed token accounts with rent distribution
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
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Account closure must distribute lamports according to: Solana rent exemption → returned to user, completed epoch rent → rent recipient, partial epoch rent → user, compression incentive → forester node
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
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Create wrapper instruction module at `src/account_compression_cpi/new_operation.rs` with `NewOperationContext` struct defining required accounts
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export new wrapper modules in `account_compression_cpi/mod.rs` using `pub mod new_operation;` and `pub use new_operation::*;`, then import in `lib.rs`
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/main.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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: Applies to programs/compressed-token/program/src/close_token_account.rs : Close token account instruction must return rent exemption to rent recipient if compressible and remaining lamports to destination account
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.rs
📚 Learning: 2025-11-24T18:00:48.449Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Implement account compressibility states in the following order: Funded (rent for current + 1 epoch) → Compressible (lacks rent for current + 1 epoch) → Claimable (funded but past epochs unclaimed)
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:48.449Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/SOLANA_RENT.md:0-0
Timestamp: 2025-11-24T18:00:48.449Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Account closure must distribute lamports according to: Solana rent exemption → returned to user, completed epoch rent → rent recipient, partial epoch rent → user, compression incentive → forester node
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/lib.rsforester/src/main.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Implement `process_new_operation()` function in wrapper module to handle PDA signer setup, account mapping, and CPI execution
Applied to files:
programs/registry/src/compressible/compress_and_close.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:
programs/registry/src/compressible/compress_and_close.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.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:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:21.501Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/ERRORS.md:0-0
Timestamp: 2025-11-24T18:00:21.501Z
Learning: Applies to program-libs/compressible/docs/program-libs/compressible/src/**/*.rs : InvalidState (Error Code 19002): For account creation, ensure CompressibleConfig state is `Active` (1). For other operations (claim, withdraw, compress & close), ensure config state is not `Inactive` (0). Validate config state using `config.validate_active()` for creation and `config.validate_not_inactive()` for other operations.
Applied to files:
programs/registry/src/compressible/compress_and_close.rs
📚 Learning: 2025-11-24T17:59:54.233Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/PACKED_ACCOUNTS.md:0-0
Timestamp: 2025-11-24T17:59:54.233Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/**/*.rs : Provide descriptive names in ProgramPackedAccounts error messages (e.g., 'token_mint' instead of 'account')
Applied to files:
programs/registry/src/compressible/compress_and_close.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: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer instruction (discriminator: 3) must implement SPL-compatible transfers between decompressed accounts
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/src/compressible/subscriber.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: Applies to programs/compressed-token/program/src/transfer2/*.rs : Transfer2 instruction (discriminator: 101) supports batch operations including Compress, Decompress, and CompressAndClose with multi-mint support and sum checks
Applied to files:
programs/registry/src/compressible/compress_and_close.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 : Charge rollover fee when creating output compressed accounts (insertion into output queue), not on tree operations
Applied to files:
programs/registry/src/compressible/compress_and_close.rsforester/src/compressible/compressor.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:01:54.689Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:54.689Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Close Token Account documentation must cover closing decompressed token accounts with rent distribution
Applied to files:
programs/registry/src/compressible/compress_and_close.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 : Implement default initialization for CToken V1 config in CompressibleConfig structure
Applied to files:
forester/src/compressible/config.rsforester/src/main.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T17:53:53.971Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: forester/README.md:0-0
Timestamp: 2025-11-24T17:53:53.971Z
Learning: Applies to forester/src/**/*{transaction,batch}*.rs : Transaction V1 processing should configure `--max-concurrent-sends 50`, `--legacy-ixs-per-tx 1`, `--transaction-max-concurrent-batches 20`, `--cu-limit 1000000`, and `--enable-priority-fees false` by default
Applied to files:
forester/src/compressible/config.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 bloom filter configuration for input queue: bloom_filter_capacity (u64, default batch_size * 8) and bloom_filter_num_iters (u64, default 3 for test and 10 for production)
Applied to files:
forester/src/compressible/config.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 batch size parameters in `InitStateTreeAccountsInstructionData` struct: input_queue_batch_size (u64, default 15,000), output_queue_batch_size (u64, default 15,000), input_queue_zkp_batch_size (u64, default 500), and output_queue_zkp_batch_size (u64, default 500)
Applied to files:
forester/src/compressible/config.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : CompressibleConfig PDA must be derived using seeds `[b"compressible_config", version.to_le_bytes()]` with the stored bump seed for deterministic account address generation in Light Protocol
Applied to files:
forester/src/compressible/config.rsforester/src/epoch_manager.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 : Validate that ZKP batch sizes must be 10 or 500 (only supported circuit sizes)
Applied to files:
forester/src/compressible/config.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : When deserializing CompressibleConfig accounts, skip the 8-byte discriminator `[180, 4, 231, 26, 220, 144, 55, 168]` before deserialization in zero-copy implementations using bytemuck::pod_from_bytes
Applied to files:
forester/src/compressible/config.rsforester/src/epoch_manager.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 : Validate that bloom filter capacity must be divisible by 8 and must be >= batch_size * 8
Applied to files:
forester/src/compressible/config.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:
forester/src/compressible/config.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 bloom_filter_capacity is divisible by 8 in `src/initialize_address_tree.rs`. Capacity must be >= batch_size * 8.
Applied to files:
forester/src/compressible/config.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/compressible/config.rsforester/src/compressible/compressor.rs
📚 Learning: 2025-11-24T17:53:53.971Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: forester/README.md:0-0
Timestamp: 2025-11-24T17:53:53.971Z
Learning: Applies to forester/src/**/*{pool,connection,rpc}*.rs : RPC pool settings should use `--rpc-pool-size 10` (default), `--rpc-pool-connection-timeout-secs 15`, and `--rpc-pool-idle-timeout-secs 300` for optimal connection pooling
Applied to files:
forester/src/compressible/config.rs
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run batched tree transfer test using `cargo test-sbf -p compressed-token-test -- test_transfer_with_photon_and_batched_tree` and apply retry logic in CI (max 3 attempts, 5s delay) due to known flakiness
Applied to files:
forester/tests/test_batch_append_spent.rsforester/src/epoch_manager.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/**/instructions.rs : Compress/decompress instruction handlers and context struct generation should be implemented in `instructions.rs`, with compress using PDA-only and decompress supporting full PDA + ctoken
Applied to files:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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/**/pack_unpack.rs : Pubkey compression logic and `PackedXxx` struct generation with Pack/Unpack trait implementations should be in `pack_unpack.rs`
Applied to files:
forester/src/compressible/compressor.rsforester/src/compressible/mod.rsforester/src/main.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 : Implement state validation methods (`validate_active`, `validate_not_inactive`) on CompressibleConfig account structure
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run account-compression tests using `cargo test-sbf -p account-compression-test` to test core account compression program (Merkle tree management)
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/epoch_manager.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:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/src/compressible/mod.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.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 : Use `check_account_balance_is_rent_exempt` function from `light-account-checks` to verify rent exemption for both queue_account and merkle_tree_account during initialization
Applied to files:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/src/compressible/subscriber.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:
forester/src/compressible/compressor.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: State and instruction data structures must be defined in the separate 'light-ctoken-interface' crate (program-libs/ctoken-types/) to allow SDKs to import types without pulling in program dependencies
Applied to files:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.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:
forester/src/compressible/compressor.rsforester/src/compressible/subscriber.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : CompressibleConfig account state in Solana programs must validate active state using `validate_active()` method before allowing new compressible token account creation
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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/compressible/compressor.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:
forester/src/compressible/compressor.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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 output queue must use BatchedMerkleTreeAccount::update_tree_from_output_queue_account method with ZKP verification
Applied to files:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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 state tree with queue_account pubkey in tree metadata and set rollover_fee to 0 (charged on queue insertion, not tree operations)
Applied to files:
forester/src/compressible/compressor.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/compressible/compressor.rsforester/src/epoch_manager.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:
forester/src/compressible/compressor.rsforester/src/epoch_manager.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/**/initialize_state_tree.rs : State tree initialization must create two Solana accounts: BatchedMerkleTreeAccount with integrated input queue and separate BatchedQueueAccount
Applied to files:
forester/src/compressible/compressor.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/lib.rs : In wrapper instruction handler in `lib.rs`, load account metadata, determine work units, call `check_forester()`, then call the processing function
Applied to files:
forester/src/compressible/compressor.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: Applies to programs/compressed-token/program/src/create_token_account.rs : Create token account instructions (CreateTokenAccount, CreateAssociatedCTokenAccount, CreateAssociatedTokenAccountIdempotent) require ACTIVE config validation only
Applied to files:
forester/src/compressible/compressor.rsforester/tests/test_compressible_ctoken.rsforester/src/compressible/subscriber.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/compressible/compressor.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: Applies to sdk-tests/sdk-ctoken-test/**/Cargo.toml : Use path references in Cargo.toml dependencies pointing to `/Users/ananas/dev/light-protocol2/sdk-libs/` for light-ctoken-sdk, light-ctoken-types, light-sdk, light-sdk-types, and light-program-test
Applied to files:
forester/Cargo.toml
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run compressed token core tests using `cargo test-sbf -p compressed-token-test --test ctoken`, `--test v1`, `--test mint`, and `--test transfer2`
Applied to files:
forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run Light system program compression tests using `cargo test-sbf -p system-test -- test_with_compression` and `cargo test-sbf -p system-test --test test_re_init_cpi_account` to test compressed account operations
Applied to files:
forester/tests/test_compressible_ctoken.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: Applies to sdk-tests/sdk-ctoken-test/**/{lib,main}.rs : Clone AccountInfo structs when building CPI builder pattern account structs to avoid borrow checker issues
Applied to files:
forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : Anchor deserialization of CompressibleConfig must use `AccountDeserialize::try_deserialize()` which automatically validates the discriminator to prevent invalid account type mismatches
Applied to files:
forester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.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/rent.rs : Implement rent calculation functions including `rent_curve_per_epoch`, `calculate_rent_and_balance`, `claimable_lamports`, and `calculate_close_lamports` in rent.rs
Applied to files:
forester/tests/test_compressible_ctoken.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 : Implement PDA derivation methods (`derive_pda`, `derive_v1_config_pda`) on CompressibleConfig for account discovery
Applied to files:
forester/tests/test_compressible_ctoken.rsforester/src/compressible/mod.rsforester/src/compressible/subscriber.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `claimable_lamports` function to return None if account is compressible, otherwise return Some(amount) for completed epochs only (excluding current ongoing epoch).
Applied to files:
forester/tests/test_compressible_ctoken.rsforester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `calculate_close_lamports` function to return (u64, u64) tuple splitting lamports between rent recipient and user, with rent recipient receiving completed epochs and user receiving partial epoch remainder.
Applied to files:
forester/tests/test_compressible_ctoken.rsforester/src/epoch_manager.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/**/mod.rs : Module declaration should be kept in `mod.rs`
Applied to files:
forester/src/compressible/mod.rsforester/src/main.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/**/traits.rs : Core trait implementations (`HasCompressionInfo`, `CompressAs`, `Compressible`) should be defined in `traits.rs`
Applied to files:
forester/src/main.rs
📚 Learning: 2025-12-07T03:17:42.199Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-07T03:17:42.199Z
Learning: Applies to program-libs/account-checks/**/*.rs : Use AccountInfoTrait abstraction for unified account handling across both solana-program and pinocchio SDKs
Applied to files:
forester/src/compressible/subscriber.rs
📚 Learning: 2025-11-24T17:58:50.237Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_CHECKS.md:0-0
Timestamp: 2025-11-24T17:58:50.237Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/checks.rs : Use generic `AccountInfoTrait` parameter for all account validation functions to enable compatibility with both Solana and Pinocchio runtimes
Applied to files:
forester/src/compressible/subscriber.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:
forester/src/compressible/subscriber.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:
forester/src/compressible/subscriber.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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/**/rollover_{state,address}_tree.rs : Trees must support rollover when reaching capacity (2^height leaves) by creating a new tree and marking the old tree as rolled over, preserving old tree roots
Applied to files:
forester/src/epoch_manager.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/epoch_manager.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: When forester PDA is present, `check_forester()` must validate epoch registration and eligibility, track work, and require network fee; when absent, validate that authority matches the tree's designated forester (for private trees)
Applied to files:
forester/src/epoch_manager.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 : Transition batch state to `Inserted` when all ZKP batches are complete and increment `pending_batch_index` to switch to other batch
Applied to files:
forester/src/epoch_manager.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 : Batch nullify operations must check that tree type is TreeType::StateV2 before processing, verify batch has ready ZKP batches (num_full_zkp_batches > num_inserted_zkp_batches), and reject if batch is already in Inserted state.
Applied to files:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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 : Batch address append operations must check that tree type is TreeType::AddressV2 before processing, verify tree capacity constraint (tree.next_index + zkp_batch_size <= tree_capacity), verify batch has ready ZKP batches (num_full_zkp_batches > num_inserted_zkp_batches), and reject if batch is already in Inserted state.
Applied to files:
forester/src/epoch_manager.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/error.rs : PropagateHasher errors from light-hasher module with 7xxx code range in error handling
Applied to files:
forester/src/epoch_manager.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:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `calculate_rent_and_balance` function to determine compressibility by checking if account balance covers required rent for epochs since last claim, returning (bool, u64) tuple.
Applied to files:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Accounts become compressible when they lack rent for the current epoch plus the next epoch (compressibility window).
Applied to files:
forester/src/epoch_manager.rs
📚 Learning: 2025-11-24T18:00:36.663Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/RENT.md:0-0
Timestamp: 2025-11-24T18:00:36.663Z
Learning: Applies to program-libs/compressible/docs/**/*rent*.rs : Implement `get_last_funded_epoch` function to determine the last epoch number covered by rent payments.
Applied to files:
forester/src/epoch_manager.rs
📚 Learning: 2025-12-07T18:09:57.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-12-07T18:09:57.230Z
Learning: Applies to program-libs/compressible/docs/**/*.rs : CompressibleConfig rent_sponsor PDA and compression_authority PDA must be derived separately using `get_rent_sponsor_seeds()` and `get_compression_authority_seeds()` helper methods with version-specific seeds
Applied to files:
forester/src/epoch_manager.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 : Insert Into Output Queue: Inserts a compressed account hash into the output queue's currently processing batch by calling `BatchedQueueAccount::insert_into_current_batch` with hash_chain_value and current_slot parameters, updating value vec, hash chain, and managing batch state transitions in src/queue.rs
Applied to files:
forester/src/epoch_manager.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:
forester/src/epoch_manager.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`, insert compressed_account_hash into bloom filter (NOT the nullifier) for non-inclusion checks in subsequent transactions
Applied to files:
forester/src/epoch_manager.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`, perform non-inclusion check to ensure compressed_account_hash does not exist in any bloom filter to prevent double-spending
Applied to files:
forester/src/epoch_manager.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 : After inserting an address into the batch, check if `num_inserted_elements == batch_size`. If true, transition batch state from `Fill` to `Full`, increment `currently_processing_batch_index` to switch to the other batch, and update `pending_batch_index` to mark this batch ready for tree update.
Applied to files:
forester/src/epoch_manager.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/epoch_manager.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 : Batch must have ready ZKP batches for insertion: verify `num_full_zkp_batches > num_inserted_zkp_batches`; error with `BatchNotReady` (14301) if not ready
Applied to files:
forester/src/epoch_manager.rs
🧬 Code graph analysis (5)
forester/tests/test_batch_append_spent.rs (1)
forester/src/errors.rs (1)
channel(208-212)
forester/tests/test_compressible_ctoken.rs (2)
forester/src/compressible/subscriber.rs (2)
new(36-46)new(175-185)forester/src/compressible/state.rs (1)
new(59-63)
forester/src/lib.rs (1)
forester/src/compressible/subscriber.rs (2)
new(36-46)new(175-185)
forester/src/main.rs (1)
forester/src/errors.rs (1)
channel(208-212)
forester/tests/e2e_test.rs (1)
forester/src/errors.rs (1)
channel(208-212)
⏰ 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). (2)
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
| // FIXME: Use latest active state tree after updating lookup tables | ||
| // rpc.get_latest_active_state_trees() | ||
| // .await | ||
| // .map_err(|e| anyhow::anyhow!("Failed to get state tree info: {}", e))?; | ||
| // let output_tree_info = rpc | ||
| // .get_random_state_tree_info() | ||
| // .map_err(|e| anyhow::anyhow!("Failed to get state tree info: {}", e))?; | ||
|
|
||
| let output_tree_info = TreeInfo { | ||
| tree: pubkey!("bmt1LryLZUMmF7ZtqESaw7wifBXLfXHQYoE4GAmrahU"), | ||
| queue: pubkey!("oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto"), | ||
| cpi_context: Some(pubkey!("cpi15BoVPKgEPw5o8wc2T816GE7b378nMXnhH3Xbq4y")), | ||
| tree_type: TreeType::StateV2, | ||
| next_tree_info: None, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's examine the file and surrounding context
head -n 120 forester/src/compressible/compressor.rs | tail -n 40Repository: Lightprotocol/light-protocol
Length of output: 1768
🏁 Script executed:
# Search for TreeInfo struct definition and usage patterns
rg "TreeInfo" --type rust -B 2 -A 2 | head -n 100Repository: Lightprotocol/light-protocol
Length of output: 6846
🏁 Script executed:
# Look for get_latest_active_state_trees and get_random_state_tree_info
rg "get_latest_active_state_trees|get_random_state_tree_info" --type rustRepository: Lightprotocol/light-protocol
Length of output: 2948
🏁 Script executed:
# Check for open issues or tracking related to dynamic tree lookup
git log --oneline --all | grep -i "tree\|lookup\|dynamic" | head -n 20Repository: Lightprotocol/light-protocol
Length of output: 1500
🏁 Script executed:
# Search for environment configs or test-specific markers
fd "env" -t f | grep -i config
rg "test\|TEST\|dev\|DEV" forester/src/compressible/compressor.rs | head -n 20Repository: Lightprotocol/light-protocol
Length of output: 54
🏁 Script executed:
# Search for issues or PRs related to dynamic tree lookup or lookup tables
rg "lookup table|dynamic.*tree" --type rust -i | head -n 30Repository: Lightprotocol/light-protocol
Length of output: 2632
🏁 Script executed:
# Check recent git history for this specific file
git log --oneline -20 -- forester/src/compressible/compressor.rsRepository: Lightprotocol/light-protocol
Length of output: 87
🏁 Script executed:
# Look for issue tracking or comments about this FIXME
rg "FIXME.*tree|lookup table" --type rust -B 2 -A 2Repository: Lightprotocol/light-protocol
Length of output: 4813
🏁 Script executed:
# Check if forester is test-only or production code
head -n 50 forester/Cargo.toml | tail -n 20Repository: Lightprotocol/light-protocol
Length of output: 770
🏁 Script executed:
# Check if there's a GitHub issues file or tracking
find . -name "*.md" -type f | xargs grep -l "lookup table\|forester" | head -5Repository: Lightprotocol/light-protocol
Length of output: 300
🏁 Script executed:
# Examine the full context around the FIXME to understand the blocking reason
sed -n '80,110p' forester/src/compressible/compressor.rsRepository: Lightprotocol/light-protocol
Length of output: 1368
🏁 Script executed:
# Check if get_latest_active_state_trees is actually implemented or just a stub
rg -A 10 "async fn get_latest_active_state_trees" --type rustRepository: Lightprotocol/light-protocol
Length of output: 2632
🏁 Script executed:
# Check if forester is built/deployed as production or test-only
grep -E "^\[.*test.*\]|^\[.*dev.*\]" forester/Cargo.tomlRepository: Lightprotocol/light-protocol
Length of output: 90
Hardcoded TreeInfo blocks production deployment pending lookup table infrastructure updates.
The hardcoded pubkeys will only work with this specific environment's state trees. While get_latest_active_state_trees() and get_random_state_tree_info() are implemented in the RPC client, this code remains on hardcoded values due to incomplete lookup table integration (as noted in the FIXME).
This must be resolved before deploying to any environment with different state tree addresses. Ensure there's a tracking issue for completing the lookup table infrastructure work.
| fn handle_log_notification(&self, response: RpcResponse<RpcLogsResponse>) { | ||
| let logs_response = response.value; | ||
|
|
||
| // Skip failed transactions | ||
| if logs_response.err.is_some() { | ||
| debug!("Skipping failed transaction {}", logs_response.signature); | ||
| return; | ||
| } | ||
|
|
||
| // Parse logs looking for compress_and_close entries | ||
| let mut removed_count = 0; | ||
| for log in &logs_response.logs { | ||
| // Look for our log prefix: "Program log: compress_and_close:<pubkey>" | ||
| // The actual log format is "Program log: compress_and_close:<pubkey>" | ||
| if let Some(pubkey_str) = log | ||
| .strip_prefix("Program log: ") | ||
| .and_then(|s| s.strip_prefix(COMPRESS_AND_CLOSE_LOG_PREFIX)) | ||
| { | ||
| match Pubkey::from_str(pubkey_str) { | ||
| Ok(pubkey) => { | ||
| if self.tracker.remove(&pubkey).is_some() { | ||
| debug!( | ||
| "Removed closed account {} from tracker (compress_and_close log)", | ||
| pubkey | ||
| ); | ||
| removed_count += 1; | ||
| } | ||
| } | ||
| Err(e) => { | ||
| error!( | ||
| "Invalid pubkey in compress_and_close log '{}': {}", | ||
| pubkey_str, e | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if removed_count > 0 { | ||
| info!( | ||
| "Removed {} closed accounts from transaction {}", | ||
| removed_count, logs_response.signature | ||
| ); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider trimming whitespace when parsing pubkeys from logs.
The current implementation extracts the pubkey string directly from the log without trimming whitespace. If the registry program's log format includes any trailing whitespace or newlines, Pubkey::from_str() will fail.
Consider adding .trim() to handle potential whitespace:
if let Some(pubkey_str) = log
.strip_prefix("Program log: ")
.and_then(|s| s.strip_prefix(COMPRESS_AND_CLOSE_LOG_PREFIX))
{
- match Pubkey::from_str(pubkey_str) {
+ match Pubkey::from_str(pubkey_str.trim()) {
Ok(pubkey) => {This makes the parser more robust against formatting variations.
📝 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.
| fn handle_log_notification(&self, response: RpcResponse<RpcLogsResponse>) { | |
| let logs_response = response.value; | |
| // Skip failed transactions | |
| if logs_response.err.is_some() { | |
| debug!("Skipping failed transaction {}", logs_response.signature); | |
| return; | |
| } | |
| // Parse logs looking for compress_and_close entries | |
| let mut removed_count = 0; | |
| for log in &logs_response.logs { | |
| // Look for our log prefix: "Program log: compress_and_close:<pubkey>" | |
| // The actual log format is "Program log: compress_and_close:<pubkey>" | |
| if let Some(pubkey_str) = log | |
| .strip_prefix("Program log: ") | |
| .and_then(|s| s.strip_prefix(COMPRESS_AND_CLOSE_LOG_PREFIX)) | |
| { | |
| match Pubkey::from_str(pubkey_str) { | |
| Ok(pubkey) => { | |
| if self.tracker.remove(&pubkey).is_some() { | |
| debug!( | |
| "Removed closed account {} from tracker (compress_and_close log)", | |
| pubkey | |
| ); | |
| removed_count += 1; | |
| } | |
| } | |
| Err(e) => { | |
| error!( | |
| "Invalid pubkey in compress_and_close log '{}': {}", | |
| pubkey_str, e | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| if removed_count > 0 { | |
| info!( | |
| "Removed {} closed accounts from transaction {}", | |
| removed_count, logs_response.signature | |
| ); | |
| } | |
| } | |
| } | |
| fn handle_log_notification(&self, response: RpcResponse<RpcLogsResponse>) { | |
| let logs_response = response.value; | |
| // Skip failed transactions | |
| if logs_response.err.is_some() { | |
| debug!("Skipping failed transaction {}", logs_response.signature); | |
| return; | |
| } | |
| // Parse logs looking for compress_and_close entries | |
| let mut removed_count = 0; | |
| for log in &logs_response.logs { | |
| // Look for our log prefix: "Program log: compress_and_close:<pubkey>" | |
| // The actual log format is "Program log: compress_and_close:<pubkey>" | |
| if let Some(pubkey_str) = log | |
| .strip_prefix("Program log: ") | |
| .and_then(|s| s.strip_prefix(COMPRESS_AND_CLOSE_LOG_PREFIX)) | |
| { | |
| match Pubkey::from_str(pubkey_str.trim()) { | |
| Ok(pubkey) => { | |
| if self.tracker.remove(&pubkey).is_some() { | |
| debug!( | |
| "Removed closed account {} from tracker (compress_and_close log)", | |
| pubkey | |
| ); | |
| removed_count += 1; | |
| } | |
| } | |
| Err(e) => { | |
| error!( | |
| "Invalid pubkey in compress_and_close log '{}': {}", | |
| pubkey_str, e | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| if removed_count > 0 { | |
| info!( | |
| "Removed {} closed accounts from transaction {}", | |
| removed_count, logs_response.signature | |
| ); | |
| } | |
| } |
🤖 Prompt for AI Agents
In forester/src/compressible/subscriber.rs around lines 241 to 286, the code
extracts the pubkey substring from the log and passes it directly to
Pubkey::from_str, which fails if the log contains trailing whitespace/newlines;
update the parsing to trim whitespace (e.g., call .trim() on the extracted
pubkey_str before handing it to Pubkey::from_str) so the pubkey is validated
against a trimmed string and the error branch only triggers for truly invalid
pubkeys.
|
|
||
| if self.compressible_tracker.is_some() && self.config.compressible_config.is_some() { | ||
| let compression_tree_accounts = TreeAccounts { | ||
| merkle_tree: solana_sdk::pubkey::Pubkey::default(), | ||
| queue: solana_sdk::pubkey::Pubkey::default(), | ||
| tree_type: TreeType::Unknown, | ||
| is_rolledover: false, | ||
| }; | ||
| let tree_schedule = TreeForesterSchedule::new_with_schedule( | ||
| &compression_tree_accounts, | ||
| slot, | ||
| &epoch_info.forester_epoch_pda, | ||
| &epoch_info.epoch_pda, | ||
| )?; | ||
| epoch_info.trees.insert(0, tree_schedule); | ||
| debug!("Added compression tree to epoch {}", epoch_info.epoch.epoch); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Using TreeType::Unknown as a sentinel for compression works but is implicit.
The synthetic tree with TreeType::Unknown and default pubkeys signals "run compression" rather than representing an actual tree. This is functional but relies on implicit knowledge:
should_skip_treereturnsfalseforUnknown(line 2263)dispatch_tree_processingroutesUnknowntodispatch_compression(lines 1583-1590)- The default pubkeys are never actually used
Consider adding a doc comment here explaining this pattern, or introducing a dedicated TreeType::Compression variant if the light_compressed_account crate is under your control.
🤖 Prompt for AI Agents
In forester/src/epoch_manager.rs around lines 930 to 946, the code constructs a
synthetic compression tree using TreeType::Unknown and default pubkeys which is
a sentinel value; make this explicit to avoid implicit behavior: either add a
short doc comment above this block explaining that TreeType::Unknown + default
pubkeys is intentionally used as a sentinel to trigger compression (not a real
tree), listing the dependent functions (should_skip_tree and
dispatch_tree_processing) and that pubkeys are unused, or (preferable if you can
change the crate) add a new TreeType::Compression variant in the
light_compressed_account crate and use that here and update the match sites so
dispatch_tree_processing handles Compression explicitly; implement the doc
comment if crate change is not possible.
| // Emit logs for closed accounts (used by forester to track closures) | ||
| for idx in &indices { | ||
| if let Ok(source_account) = transfer2_accounts | ||
| .packed_accounts | ||
| .get_u8(idx.source_index, "source_account") | ||
| { | ||
| msg!("compress_and_close:{}", source_account.key); | ||
| } | ||
| } |
There was a problem hiding this comment.
Logs emitted before CPI success could mislead LogSubscriber.
These logs are emitted before the invoke_signed CPI call at line 84. If the CPI fails, the logs will still have been written but the accounts won't actually be closed. The LogSubscriber listening to these logs would incorrectly remove accounts from its tracker.
Consider either:
- Moving log emission to after successful CPI completion (though this may not be possible in on-chain programs since the transaction succeeds or fails atomically), or
- Documenting that LogSubscriber should only trust logs from confirmed transactions
Also, silently ignoring get_u8 errors (via if let Ok(...)) may hide configuration issues—consider logging a warning for failed lookups.
🤖 Prompt for AI Agents
programs/registry/src/compressible/compress_and_close.rs lines 56-64: logs for
closed accounts are emitted before the CPI at line 84 and may mislead
subscribers if the CPI fails; change the code to defer emitting msg! until after
the CPI returns successfully (i.e., call invoke_signed, check its Result, and
only then iterate indices and emit the msg! per closed account), and also avoid
silently swallowing get_u8 errors—on Err from get_u8 emit a warning msg! (or
return an error if appropriate) so configuration/lookup failures are visible.
Summary by CodeRabbit
New Features
Configuration
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.