Skip to content

Conversation

@ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Nov 12, 2025

Changes:

  • regenerate accounts and add new test-validator env accounts:
    1. rent sponsor
    2. compressible config pda
    3. config counter pda
  • add compressible flag to forester start
  • add Compressor compresses and closes any compressible ctoken accounts that have been indexed and saved into CompressibleAccountTracker
  • add AccountSubscriber subscribes to account changes of the CToken program and indexes compressible ctoken accounts
  • add get_multiple_accounts to trait Rpc

Note:

  • in a different pr we should replace CompressibleAccountTracker with a DB connection

Summary by CodeRabbit

  • New Features

    • Compressible token support: discovery (bootstrap), account tracking, and automated batch compression with concurrency controls.
    • Real-time WebSocket subscriber to keep the tracker up to date.
    • Batch RPC account retrieval to fetch multiple accounts in one call.
  • Configuration

    • New --enable-compressible toggle (off by default) plus compressible WS URL, batch size, and max concurrent batches.
    • Separate shutdown channels for graceful compressible/bootstrap teardown.
  • Tests

    • New and extended end-to-end tests covering bootstrap, tracking, and compression.
  • Bug Fixes

    • Safe handling for unknown/virtual tree types to avoid runtime errors.
  • Chores

    • Added workspace dependencies to support the compressible feature.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 12, 2025

Walkthrough

Adds a compressible-token feature: new workspace deps and CLI flag; config, websocket subscriber, bootstrapper, concurrent tracker, batch compressor, epoch-manager dispatch (TreeType::Unknown), RPC batch retrieval, defensive tree handling, extra shutdown channels, and integration tests.

Changes

Cohort / File(s) Summary
Dependencies & Manifest
\forester/Cargo.toml``
Adds workspace deps: light-compressible, light-ctoken-types, light-compressed-token-sdk, light-token-client (deps + dev-deps), solana-rpc-client-api, and base64 = "0.22".
CLI
\forester/src/cli.rs``
Adds pub enable_compressible: bool StartArgs flag (env: FORESTER_ENABLE_COMPRESSIBLE).
Config Integration
\forester/src/compressible/config.rs`, `forester/src/config.rs`, `forester/tests/test_utils.rs``
New CompressibleConfig type and ForesterConfig.compressible_config: Option<...> with wiring from CLI.
Module & Types
\forester/src/compressible/mod.rs`, `forester/src/compressible/types.rs``
New compressible module with submodules; adds CompressibleAccountState and re-exports public API.
Account Tracker
\forester/src/compressible/state.rs``
CompressibleAccountTracker (DashMap) with insert/remove, queries, update_from_account, slot calculation, and async sync_accounts.
WebSocket Subscriber
\forester/src/compressible/subscriber.rs``
AccountSubscriber subscribes via WebSocket PubSub, decodes Base64 updates, updates tracker, handles shutdown.
Compressor Implementation
\forester/src/compressible/compressor.rs``
Compressor<R: Rpc> constructs/sends compress_and_close transactions (PDA derivation, PackedAccounts/index mapping), reads RPC state, submits tx, and syncs tracker.
Bootstrapper
\forester/src/compressible/bootstrap.rs``
bootstrap_compressible_accounts enumerates program accounts (v1/v2), deserializes CToken, populates tracker with pagination and shutdown-aware calls.
Epoch & Service Integration
\forester/src/epoch_manager.rs`, `forester/src/lib.rs`, `forester/src/main.rs``
Adds optional compressible_tracker into service, creates synthetic compression tree, routes TreeType::Unknown to dispatch_compression, refactors shutdown into service/compressible/bootstrap channels and spawns subscriber/bootstrap tasks.
RPC Batch Retrieval
\sdk-libs/client/src/rpc/rpc_trait.rs`, `sdk-libs/client/src/rpc/client.rs`, `sdk-libs/program-test/src/program_test/rpc.rs``
Adds get_multiple_accounts(&[Pubkey]) -> Result<Vec<Option<Account>>, RpcError> to Rpc trait and implementations.
TreeType Extension & Defensive Handling
\program-libs/compressed-account/src/lib.rs`, `sdk-libs/client/src/indexer/tree_info.rs`, `forester/src/rollover/operations.rs``
Adds TreeType::Unknown = 255 and handles Unknown in Display/From; defensive branches return zero/empty height/fullness and warn for Unknown in fullness checks.
Tests & E2E
\forester/tests/e2e_test.rs`, `forester/tests/priority_fee_test.rs`, `forester/tests/test_batch_append_spent.rs`, `forester/tests/test_compressible_ctoken.rs``
Tests updated to enable/wire compressible_config, propagate extra shutdown_compressible channel, add compressible ctoken tests, and handle TreeType::Unknown in helpers.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Main as main.rs
    participant Pipeline as run_pipeline()
    participant Subscriber as AccountSubscriber
    participant Tracker as CompressibleAccountTracker
    participant EpochMgr as EpochManager
    participant Compressor as Compressor
    participant RPC as Solana RPC

    Main->>Pipeline: run_pipeline(..., shutdown_service, shutdown_compressible, shutdown_bootstrap)
    alt compressible enabled
        Pipeline->>Subscriber: spawn AccountSubscriber::run()
        Pipeline->>EpochMgr: pass compressible_tracker

        Subscriber->>RPC: subscribe program accounts (ws)
        RPC-->>Subscriber: RpcKeyedAccount (Base64)
        Subscriber->>Tracker: update_from_account(data, lamports)

        EpochMgr->>EpochMgr: detect TreeType::Unknown
        EpochMgr->>Compressor: dispatch_compression(batch)
        Compressor->>RPC: get_multiple_accounts(addresses)
        Compressor->>RPC: send compress_and_close tx
        Compressor->>Tracker: sync_accounts(updated_pubkeys)

        Main->>Subscriber: signal shutdown_compressible
        Subscriber->>RPC: unsubscribe
    else
        Pipeline->>EpochMgr: compressible_tracker = None
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas to focus review on:

  • forester/src/epoch_manager.rs — compression dispatch, batching, concurrency, TreeType::Unknown integration.
  • forester/src/compressible/compressor.rs — PDA derivation, PackedAccounts index mapping, transaction construction and signer handling.
  • forester/src/compressible/state.rs — concurrent tracker correctness, deserialization and compressible_slot calculation.
  • forester/src/compressible/subscriber.rs — websocket lifecycle, Base64 decoding and shutdown handling.
  • Tests — timing, race conditions, additional shutdown channel wiring, and e2e stability.

Possibly related PRs

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

A websocket hum, a tracker keeps watch,
Unknown trees wait while batches dispatch,
Compressors gather, PDAs align,
Shutdowns whisper when SIGINT chimes,
Accounts close softly—compact, neat design.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: forester compressible ctoken support' accurately captures the main feature addition across the changeset—introducing compressible CToken support to the forester system.
Docstring Coverage ✅ Passed Docstring coverage is 94.74% which is sufficient. The required threshold is 70.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jorrit/feat-forester-compressible-ctoken-support

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1fa0bf and 29b1d01.

⛔ Files ignored due to path filters (18)
  • Cargo.lock is excluded by !**/*.lock and included by none
  • cli/accounts/batch_address_merkle_tree_amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx.json is excluded by none and included by none
  • cli/accounts/batched_output_queue_oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto.json is excluded by none and included by none
  • cli/accounts/batched_output_queue_oq2UkeMsJLfXt2QHzim242SUi3nvjJs8Pn7Eac9H9vg.json is excluded by none and included by none
  • cli/accounts/batched_output_queue_oq3AxjekBWgo64gpauB6QtuZNesuv19xrhaC1ZM1THQ.json is excluded by none and included by none
  • cli/accounts/batched_output_queue_oq4ypwvVGzCUMoiKKHWh4S1SgZJ9vCvKpcz6RT6A8dq.json is excluded by none and included by none
  • cli/accounts/batched_output_queue_oq5oh5ZR3yGomuQgFduNDzjtGvVWfDRGLuDVjv9a96P.json is excluded by none and included by none
  • cli/accounts/compressible_config_pda_ACXg8a7VaqecBWrSbdu73W4Pg9gsqXJ3EXAqkHyhvVXg.json is excluded by none and included by none
  • cli/accounts/config_counter_pda_8gH9tmziWsS8Wc4fnoN5ax3jsSumNYoRDuSBvmH2GMH8.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi15BoVPKgEPw5o8wc2T816GE7b378nMXnhH3Xbq4y.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi1uHzrEhBG733DoEJNgHCyRS3XmmyVNZx5fonubE4.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi2cdhkH5roePvcudTgUL8ppEBfTay1desGh8G8QxK.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi2yGapXUR3As5SjnHBAVvmApNiLsbeZpF3euWnW6B.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi3mbwMpSX8FAGMZVP85AwxqCaQMfEk9Em1v8QK9Rf.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi4yyPDc4bCgHAnsenunGA8Y77j3XEDyjgfyCKgcoc.json is excluded by none and included by none
  • cli/accounts/cpi_context_cpi5ZTjdgYpZ1Xr7B1cMLLUE81oTtJbNNAyKary2nV6.json is excluded by none and included by none
  • cli/accounts/rent_sponsor_pda_r18WwUxfG8kQ69bQPAB2jV6zGNKy3GosFGctjQoV4ti.json is excluded by none and included by none
  • program-tests/system-test/tests/test.rs is excluded by none and included by none
📒 Files selected for processing (21)
  • forester/Cargo.toml (2 hunks)
  • forester/src/cli.rs (1 hunks)
  • forester/src/compressible/compressor.rs (1 hunks)
  • forester/src/compressible/config.rs (1 hunks)
  • forester/src/compressible/mod.rs (1 hunks)
  • forester/src/compressible/state.rs (1 hunks)
  • forester/src/compressible/subscriber.rs (1 hunks)
  • forester/src/compressible/types.rs (1 hunks)
  • forester/src/config.rs (4 hunks)
  • forester/src/epoch_manager.rs (9 hunks)
  • forester/src/lib.rs (4 hunks)
  • forester/src/main.rs (2 hunks)
  • forester/tests/e2e_test.rs (6 hunks)
  • forester/tests/priority_fee_test.rs (1 hunks)
  • forester/tests/test_batch_append_spent.rs (1 hunks)
  • forester/tests/test_compressible_ctoken.rs (1 hunks)
  • forester/tests/test_utils.rs (1 hunks)
  • sdk-libs/client/src/rpc/client.rs (1 hunks)
  • sdk-libs/client/src/rpc/rpc_trait.rs (1 hunks)
  • sdk-libs/program-test/src/program_test/rpc.rs (1 hunks)
  • sdk-libs/program-test/src/test_accounts.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (41)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/config.rs
  • forester/src/lib.rs
  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/src/cli.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/main.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_utils.rs
  • forester/Cargo.toml
  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/config.rs
  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_utils.rs
  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/config.rs
  • forester/tests/priority_fee_test.rs
  • forester/src/lib.rs
  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/src/cli.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_utils.rs
  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/subscriber.rs
  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/config.rs
  • forester/src/lib.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • forester/src/compressible/types.rs
  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/Cargo.toml
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md

Applied to files:

  • forester/src/compressible/types.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/types.rs
  • sdk-libs/program-test/src/program_test/rpc.rs
  • sdk-libs/client/src/rpc/rpc_trait.rs
  • sdk-libs/client/src/rpc/client.rs
  • forester/src/compressible/subscriber.rs
  • sdk-libs/program-test/src/test_accounts.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/config.rs
  • forester/tests/priority_fee_test.rs
  • forester/src/lib.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_utils.rs
  • forester/Cargo.toml
  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • sdk-libs/program-test/src/program_test/rpc.rs
  • sdk-libs/client/src/rpc/rpc_trait.rs
  • sdk-libs/client/src/rpc/client.rs
  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/compressible/state.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_utils.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/test_account_info.rs : Use the mock AccountInfo implementation under the test-only feature for unit tests

Applied to files:

  • sdk-libs/program-test/src/program_test/rpc.rs
  • sdk-libs/program-test/src/test_accounts.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • sdk-libs/program-test/src/program_test/rpc.rs
  • sdk-libs/client/src/rpc/client.rs
  • forester/src/compressible/subscriber.rs
  • sdk-libs/program-test/src/test_accounts.rs
  • forester/tests/e2e_test.rs
  • forester/Cargo.toml
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/!(account_info)/**/*.rs : Use AccountInfoTrait for runtime-agnostic account handling; avoid direct solana-program or pinocchio AccountInfo in general logic

Applied to files:

  • sdk-libs/program-test/src/program_test/rpc.rs
  • sdk-libs/client/src/rpc/rpc_trait.rs
  • sdk-libs/client/src/rpc/client.rs
  • forester/src/compressible/subscriber.rs
  • sdk-libs/program-test/src/test_accounts.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling

Applied to files:

  • sdk-libs/program-test/src/program_test/rpc.rs
  • sdk-libs/client/src/rpc/rpc_trait.rs
  • sdk-libs/client/src/rpc/client.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers (derive_pda, derive_v1_config_pda) in src/config.rs for CompressibleConfig

Applied to files:

  • forester/src/compressible/config.rs
  • forester/src/lib.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_utils.rs
  • forester/src/config.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/account_info_trait.rs : Ensure the crate compiles with no features enabled by keeping trait definitions free of SDK-specific dependencies

Applied to files:

  • sdk-libs/client/src/rpc/rpc_trait.rs
  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/epoch_manager.rs
  • forester/Cargo.toml
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/packed_accounts.rs : For dynamic account sets, use PackedAccounts for index-based access with bounds checks instead of manual indexing

Applied to files:

  • sdk-libs/client/src/rpc/rpc_trait.rs
  • sdk-libs/client/src/rpc/client.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/error.rs : Define error types with numeric codes in the 19xxx range and propagate hasher errors in the 7xxx range; include ProgramError conversions (Anchor, Pinocchio, Solana) in src/error.rs

Applied to files:

  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/src/lib.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/mod.rs
  • forester/src/epoch_manager.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/checks.rs : Expose and maintain account validation helpers (check_owner, check_program, check_mut/non_mut, check_signer, check_discriminator, set_discriminator, check_pda_seeds, check_account_balance_is_rent_exempt, account_info_init) in checks.rs

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : On account initialization, call account_info_init to set the 8-byte discriminator

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/**/Cargo.toml : Define features solana, pinocchio, and test-only in Cargo.toml; default build should enable none

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
  • forester/Cargo.toml
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Return AccountError variants (codes 12006–12021) and rely on automatic ProgramError conversions; avoid returning raw ProgramError directly

Applied to files:

  • sdk-libs/program-test/src/test_accounts.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Each new operation module must define an Anchor context struct (e.g., NewOperationContext) with required accounts and a process_<operation> function that prepares signer seeds, maps accounts to the target program, and executes the CPI.

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md

Applied to files:

  • forester/tests/e2e_test.rs
🧬 Code graph analysis (12)
sdk-libs/program-test/src/program_test/rpc.rs (2)
sdk-libs/client/src/rpc/client.rs (1)
  • get_multiple_accounts (517-527)
sdk-libs/client/src/rpc/rpc_trait.rs (1)
  • get_multiple_accounts (107-110)
forester/src/compressible/config.rs (2)
forester/src/compressible/compressor.rs (1)
  • new (38-52)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
sdk-libs/client/src/rpc/rpc_trait.rs (2)
sdk-libs/client/src/rpc/client.rs (1)
  • get_multiple_accounts (517-527)
sdk-libs/program-test/src/program_test/rpc.rs (1)
  • get_multiple_accounts (73-81)
sdk-libs/client/src/rpc/client.rs (2)
sdk-libs/client/src/rpc/rpc_trait.rs (1)
  • get_multiple_accounts (107-110)
sdk-libs/program-test/src/program_test/rpc.rs (1)
  • get_multiple_accounts (73-81)
forester/src/lib.rs (5)
forester/src/compressible/compressor.rs (1)
  • new (38-52)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/compressible/state.rs (1)
  • new (23-27)
forester/src/epoch_manager.rs (2)
  • new (137-190)
  • run_service (2043-2176)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/compressible/subscriber.rs (5)
forester/src/compressible/compressor.rs (1)
  • new (38-52)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/compressible/state.rs (1)
  • new (23-27)
forester/src/epoch_manager.rs (2)
  • new (137-190)
  • run (192-239)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
forester/src/compressible/compressor.rs (4)
programs/registry/src/utils.rs (1)
  • get_forester_epoch_pda_from_authority (13-16)
programs/registry/src/epoch/register_epoch.rs (1)
  • get_eligible_forester_index (63-79)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
sdk-libs/sdk/src/instruction/pack_accounts.rs (1)
  • packed_accounts (348-351)
forester/tests/e2e_test.rs (3)
forester/src/epoch_manager.rs (10)
  • rpc (453-454)
  • rpc (496-497)
  • rpc (708-709)
  • rpc (748-749)
  • rpc (763-764)
  • rpc (813-814)
  • rpc (872-873)
  • rpc (894-895)
  • rpc (1874-1875)
  • new (137-190)
forester/src/compressible/compressor.rs (1)
  • new (38-52)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/compressible/state.rs (3)
forester/src/compressible/compressor.rs (2)
  • new (38-52)
  • rpc (162-163)
forester/src/epoch_manager.rs (10)
  • new (137-190)
  • rpc (453-454)
  • rpc (496-497)
  • rpc (708-709)
  • rpc (748-749)
  • rpc (763-764)
  • rpc (813-814)
  • rpc (872-873)
  • rpc (894-895)
  • rpc (1874-1875)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/epoch_manager.rs (4)
forester/src/compressible/compressor.rs (1)
  • new (38-52)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/compressible/state.rs (1)
  • new (23-27)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/config.rs (1)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/tests/test_compressible_ctoken.rs (3)
sdk-libs/client/src/local_test_validator.rs (1)
  • spawn_validator (28-71)
programs/registry/src/sdk.rs (3)
  • create_finalize_registration_instruction (240-258)
  • create_register_forester_epoch_pda_instruction (214-238)
  • create_register_forester_instruction (146-172)
programs/registry/src/utils.rs (2)
  • get_forester_pda (34-36)
  • get_protocol_config_pda_address (5-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
  • GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
  • GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
  • GitHub Check: Forester e2e test
  • GitHub Check: system-programs (token test, ["cargo-test-sbf -p sdk-token-test"])
  • GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
  • GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
  • GitHub Check: system-programs (anchor & pinocchio, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -p sdk...
  • GitHub Check: system-programs (native, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v1-native-t...
  • GitHub Check: stateless-js-v2
  • GitHub Check: cli-v1
  • GitHub Check: stateless-js-v1
  • GitHub Check: cli-v2
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Test program-libs-slow
  • GitHub Check: lint
🔇 Additional comments (9)
forester/Cargo.toml (3)

80-80: ---

light-token-client is properly integrated for compression testing.

Verification confirms the dependency is actively used in both forester/tests/e2e_test.rs and forester/tests/test_compressible_ctoken.rs to test compression workflows. No unnecessary dev-time overhead—the import is justified and required.


38-38: Clarify why base64 is pinned instead of using workspace management across all dependencies.

Your observation is valid: base64 exhibits inconsistent dependency management across the codebase. I found that:

  • forester/Cargo.toml (line 38): base64 = "0.22" (direct pinned)
  • sdk-libs/client/Cargo.toml: base64 = { workspace = true } (workspace managed)
  • sdk-libs/program-test/Cargo.toml: base64 = "0.22" (direct pinned)

Additionally, serde_json = "1.0" (line 40) follows the same direct-pinning pattern, suggesting this may be deliberate across multiple crates. The lines 31–37 using { workspace = true } reference workspace members (local packages like light-compressible, light-ctoken-types), not external dependencies.

Align base64 (and serde_json) versioning consistently across forester, sdk-libs/program-test, and other affected crates—either all pinned or all workspace-managed. If workspace-managed, ensure the central workspace.dependencies definition exists to avoid future configuration issues.


31-35: Feature configuration is correct; no changes needed.

The new dependencies are properly configured. light-compressible automatically enables its default features ["pinocchio", "solana"], which is appropriate for forester's Solana client use case. The other crates—light-ctoken-types, light-zero-copy, and light-compressed-token-sdk—intentionally have empty defaults, a design pattern also used in other SDK consumers like sdk-libs/token-client. Since forester is a CLI binary (not an Anchor program), it doesn't require the "anchor" or other special-purpose features that those crates define. The dependency graph is already unified across your project, so no explicit feature flags are needed here.

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

1-41: LGTM! Generated test account utilities.

This generated file provides deterministic registered program PDA account states for tests. The structure is clean, and using u64::MAX for rent_epoch is appropriate for rent-exempt accounts in tests.

forester/tests/priority_fee_test.rs (1)

85-85: LGTM! Test config updated for new field.

The addition of compressible_ws_url: None correctly extends the StartArgs initialization to accommodate the new compressible feature without affecting this priority fee test.

forester/tests/test_batch_append_spent.rs (1)

326-334: LGTM! Compressible shutdown channel wired correctly.

The new oneshot channel for compressible shutdown follows the existing pattern and correctly integrates with the expanded run_pipeline signature. The unused sender is expected in this test context.

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

106-110: LGTM! Batch account retrieval method added to trait.

The new get_multiple_accounts method signature is well-designed, using Vec<Option<Account>> to correctly handle cases where some accounts may not exist. The placement after get_account is logical.

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

73-81: LGTM! Test implementation correctly maps individual account retrievals.

The implementation appropriately maps each address to a get_account call and collects the results. Sequential calls are acceptable in the test context.

forester/tests/test_utils.rs (1)

128-128: LGTM! Test config extended with compressible field.

The addition of compressible_config: None correctly extends the test configuration helper to accommodate the new optional compressible feature.

@ananas-block ananas-block force-pushed the jorrit/feat-forester-compressible-ctoken-support branch from c452aad to a984ff4 Compare November 13, 2025 00:56
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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)

1169-1207: Unknown tree path never runs compression

For TreeType::Unknown we bail out before ever invoking dispatch_tree_processing, so dispatch_compression is unreachable and no compressible account is ever processed. We need to route this branch through the dispatcher and keep the accounting consistent. Something along these lines fixes it:

-                    TreeType::Unknown => {
-                        warn!(
-                            "TreeType::Unknown not supported for light slot processing. \
-                            Compression is handled separately via dispatch_compression()"
-                        );
-                        Ok(())
-                    }
+                    TreeType::Unknown => {
+                        let processing_start_time = Instant::now();
+                        let processed = self
+                            .dispatch_tree_processing(
+                                epoch_info,
+                                epoch_pda,
+                                &tree_schedule.tree_accounts,
+                                &light_slot_details,
+                                estimated_slot,
+                                None,
+                            )
+                            .await?;
+                        if processed > 0 {
+                            self.update_metrics_and_counts(
+                                epoch_info.epoch,
+                                processed,
+                                processing_start_time.elapsed(),
+                            )
+                            .await;
+                            push_metrics(&self.config.external_services.pushgateway_url).await?;
+                        }
+                        Ok(())
+                    }

Without this change the new compression feature is dead on arrival: the synthetic queue spins forever and accounts never close.

♻️ Duplicate comments (1)
forester/src/compressible/compressor.rs (1)

27-44: Registered authority must back the registry context

CompressAndCloseContext.authority has to be the same key that registered the epoch (i.e., ForesterConfig.derivation_pubkey). With the current code we still inject the fee payer instead, so any deployment where payer ≠ derivation immediately trips the registry’s forester checks and every compression batch fails. Please thread the registered authority into Compressor and store it, then build the context with that value (and pass it from dispatch_compression). Example patch:

 pub struct Compressor<R: Rpc> {
     rpc_pool: Arc<SolanaRpcPool<R>>,
     tracker: Arc<CompressibleAccountTracker>,
     payer_keypair: Keypair,
+    authority_pubkey: Pubkey,
 }
 
 impl<R: Rpc> Compressor<R> {
     pub fn new(
         rpc_pool: Arc<SolanaRpcPool<R>>,
         tracker: Arc<CompressibleAccountTracker>,
         payer_keypair: Keypair,
+        authority_pubkey: Pubkey,
     ) -> Self {
         Self {
             rpc_pool,
             tracker,
             payer_keypair,
+            authority_pubkey,
         }
     }
@@
-        let registry_accounts = CompressAndCloseContext {
-            authority: self.payer_keypair.pubkey(),
+        let registry_accounts = CompressAndCloseContext {
+            authority: self.authority_pubkey,
             registered_forester_pda,
             compression_authority,
             compressible_config,
         };

Don’t forget to pass self.config.derivation_pubkey when constructing Compressor in dispatch_compression.

Also applies to: 167-175

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29b1d01 and a984ff4.

⛔ Files ignored due to path filters (3)
  • .coderabbit.yaml is excluded by none and included by none
  • .github/workflows/forester-tests.yml is excluded by none and included by none
  • Cargo.lock is excluded by !**/*.lock and included by none
📒 Files selected for processing (14)
  • forester/Cargo.toml (2 hunks)
  • forester/src/cli.rs (1 hunks)
  • forester/src/compressible/compressor.rs (1 hunks)
  • forester/src/config.rs (4 hunks)
  • forester/src/epoch_manager.rs (12 hunks)
  • forester/src/lib.rs (5 hunks)
  • forester/src/main.rs (2 hunks)
  • forester/src/rollover/operations.rs (2 hunks)
  • forester/tests/e2e_test.rs (9 hunks)
  • forester/tests/priority_fee_test.rs (1 hunks)
  • forester/tests/test_batch_append_spent.rs (1 hunks)
  • forester/tests/test_compressible_ctoken.rs (1 hunks)
  • program-libs/compressed-account/src/lib.rs (3 hunks)
  • sdk-libs/client/src/indexer/tree_info.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (34)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • program-libs/compressed-account/src/lib.rs
  • forester/tests/priority_fee_test.rs
  • forester/src/cli.rs
  • forester/src/config.rs
  • forester/src/main.rs
  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/Cargo.toml
  • forester/tests/e2e_test.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/tests/priority_fee_test.rs
  • forester/src/cli.rs
  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers (derive_pda, derive_v1_config_pda) in src/config.rs for CompressibleConfig

Applied to files:

  • forester/tests/priority_fee_test.rs
  • forester/src/config.rs
  • forester/src/compressible/compressor.rs
  • forester/Cargo.toml
  • forester/tests/e2e_test.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig

Applied to files:

  • forester/tests/priority_fee_test.rs
  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
  • forester/Cargo.toml
  • forester/tests/e2e_test.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/config.rs
  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/rollover/operations.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/Cargo.toml
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Each new operation module must define an Anchor context struct (e.g., NewOperationContext) with required accounts and a process_<operation> function that prepares signer seeds, maps accounts to the target program, and executes the CPI.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-15T03:46:43.242Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-token-test/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:43.242Z
Learning: Applies to sdk-tests/sdk-token-test/**/tests/**/*.rs : Every test should only contain functional integration tests

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Apply forester eligibility rules: with a forester PDA, validate epoch registration, eligibility, track work, and require network fee; without a forester PDA, ensure authority matches the tree’s designated forester.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/src/rollover/operations.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/**/Cargo.toml : Define features solana, pinocchio, and test-only in Cargo.toml; default build should enable none

Applied to files:

  • forester/Cargo.toml
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • forester/Cargo.toml
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/account_info_trait.rs : Ensure the crate compiles with no features enabled by keeping trait definitions free of SDK-specific dependencies

Applied to files:

  • forester/Cargo.toml
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/error.rs : Define error types with numeric codes in the 19xxx range and propagate hasher errors in the 7xxx range; include ProgramError conversions (Anchor, Pinocchio, Solana) in src/error.rs

Applied to files:

  • forester/src/lib.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Return AccountError variants (codes 12006–12021) and rely on automatic ProgramError conversions; avoid returning raw ProgramError directly

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • forester/src/epoch_manager.rs
🧬 Code graph analysis (6)
forester/src/config.rs (2)
forester/src/epoch_manager.rs (1)
  • new (137-190)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/tests/test_compressible_ctoken.rs (5)
sdk-libs/client/src/local_test_validator.rs (1)
  • spawn_validator (28-71)
programs/registry/src/sdk.rs (3)
  • create_finalize_registration_instruction (240-258)
  • create_register_forester_epoch_pda_instruction (214-238)
  • create_register_forester_instruction (146-172)
programs/registry/src/utils.rs (3)
  • get_forester_pda (34-36)
  • get_protocol_config_pda_address (5-7)
  • get_forester_epoch_pda_from_authority (13-16)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
forester/src/compressible/state.rs (2)
  • new (23-27)
  • len (92-94)
forester/src/compressible/compressor.rs (2)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
sdk-libs/sdk/src/instruction/pack_accounts.rs (1)
  • packed_accounts (348-351)
forester/tests/e2e_test.rs (3)
forester/src/epoch_manager.rs (10)
  • rpc (465-466)
  • rpc (508-509)
  • rpc (720-721)
  • rpc (760-761)
  • rpc (775-776)
  • rpc (825-826)
  • rpc (884-885)
  • rpc (906-907)
  • rpc (1925-1926)
  • new (137-190)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/lib.rs (5)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
forester/src/epoch_manager.rs (2)
  • new (137-190)
  • run_service (2095-2228)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/compressible/state.rs (1)
  • new (23-27)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/epoch_manager.rs (5)
forester/src/slot_tracker.rs (2)
  • run (65-76)
  • new (25-35)
forester/src/compressible/state.rs (3)
  • default (163-165)
  • len (92-94)
  • new (23-27)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
forester/src/compressible/config.rs (1)
  • new (17-22)
programs/registry/src/utils.rs (1)
  • get_forester_epoch_pda_from_authority (13-16)
⏰ 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). (5)
  • GitHub Check: stateless-js-v1
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Forester e2e test
🔇 Additional comments (2)
forester/Cargo.toml (2)

17-17: Approve: Existing workspace dependency patterns are maintained.

The existing dependencies with explicit features (e.g., light-compressed-account = { workspace = true, features = ["std"] } on line 17, light-sdk = { workspace = true, features = ["anchor"] } on line 29) follow a clear pattern. The new compressible-token dependencies align with this pattern, using workspace references where appropriate. Once the base64 pin is resolved and feature flags are verified, this section will be solid.

Also applies to: 29-30


31-37: Sync base64 to use workspace dependency like sdk-libs/client does.

Line 37 pins base64 = "0.22" with your own TODO comment # make workspace dep. Since sdk-libs/client/Cargo.toml already uses base64 = { workspace = true } successfully, align forester by changing line 37 to match that pattern. This eliminates the inline version pin and keeps dependencies consistent across the monorepo.

Copy link
Contributor

Choose a reason for hiding this comment

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

I cant see the difference?

Copy link
Contributor Author

@ananas-block ananas-block Nov 13, 2025

Choose a reason for hiding this comment

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

I think the length of the cpi context account changed -> additional bytes field in tree and queue metadata.

Comment on lines 71 to 77
let last_funded_epoch = compressible_ext
.get_last_funded_epoch(
COMPRESSIBLE_TOKEN_ACCOUNT_SIZE,
state.lamports,
COMPRESSIBLE_TOKEN_RENT_EXEMPTION,
)
.unwrap_or(0);
Copy link
Contributor

Choose a reason for hiding this comment

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

if the unwrap returns an error this will return epoch = 0 and try to compress, no? should we handle this explicitly

Comment on lines +108 to +110
// Deserialize CToken using borsh
let ctoken = CToken::try_from_slice(account_data)
.map_err(|e| anyhow::anyhow!("Failed to deserialize CToken with borsh: {:?}", e))?;
Copy link
Contributor

Choose a reason for hiding this comment

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

can we be certain that account will only ever be of type CToken?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We currently filter by account size.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
forester/src/compressible/subscriber.rs (1)

130-144: Propagate tracker update failures instead of just logging

If update_from_account fails we only log and carry on, silently dropping that account from compression. That was already flagged earlier and it’s still unresolved. Let’s bubble the error up so the caller can restart or alert—otherwise a single bad decode leaves the system in a degraded state.

-    async fn handle_account_update(&self, response: RpcResponse<RpcKeyedAccount>) {
+    async fn handle_account_update(&self, response: RpcResponse<RpcKeyedAccount>) -> Result<()> {
         // Parse pubkey
         let pubkey = match Pubkey::from_str(&response.value.pubkey) {
             Ok(pk) => pk,
             Err(e) => {
                 error!("Invalid pubkey {}: {}", response.value.pubkey, e);
-                return;
+                return Err(anyhow::anyhow!("invalid pubkey {}: {}", response.value.pubkey, e));
             }
         };
@@
                         Ok(decoded) => decoded,
                         Err(e) => {
                             error!("Failed to decode base64 for {}: {}", pubkey, e);
-                            return;
+                            return Err(anyhow::anyhow!("failed to decode base64 for {}: {}", pubkey, e));
                         }
                     }
                 }
                 _ => {
                     error!("Unexpected encoding for account {}", pubkey);
-                    return;
+                    return Err(anyhow::anyhow!("unexpected encoding for account {}", pubkey));
                 }
             },
             _ => {
                 error!("Unexpected account data format for {}", pubkey);
-                return;
+                return Err(anyhow::anyhow!("unexpected account data format for {}", pubkey));
             }
         };
 
         // Update tracker
-        match self.tracker.update_from_account(
-            pubkey,
-            &account_data,
-            response.value.account.lamports,
-        ) {
-            Ok(()) => {
-                debug!(
-                    "Updated account {} at slot {}",
-                    pubkey, response.context.slot
-                );
-            }
-            Err(e) => {
-                error!("Failed to update tracker for {}: {}", pubkey, e);
-            }
-        }
+        self.tracker
+            .update_from_account(pubkey, &account_data, response.value.account.lamports)
+            .map_err(|e| anyhow::anyhow!("failed to update tracker for {}: {}", pubkey, e))?;
+
+        debug!(
+            "Updated account {} at slot {}",
+            pubkey, response.context.slot
+        );
+        Ok(())
     }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a984ff4 and 0ea0d21.

📒 Files selected for processing (1)
  • forester/src/compressible/subscriber.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/!(account_info)/**/*.rs : Use AccountInfoTrait for runtime-agnostic account handling; avoid direct solana-program or pinocchio AccountInfo in general logic

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/src/compressible/subscriber.rs
🧬 Code graph analysis (1)
forester/src/compressible/subscriber.rs (5)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
forester/src/compressible/config.rs (1)
  • new (17-22)
forester/src/compressible/state.rs (1)
  • new (23-27)
forester/src/epoch_manager.rs (2)
  • new (137-190)
  • run (192-251)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
⏰ 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). (7)
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • 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: Forester e2e test
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test batched-merkle-tree-simulate

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

♻️ Duplicate comments (1)
forester/src/compressible/types.rs (1)

4-14: Document all fields on CompressibleAccountState

The struct-level and pubkey / compressible_slot docs are clear, but account and lamports are still undocumented. Adding short field docs will make downstream usage (especially in tests and tooling) easier to reason about.

For example:

 pub struct CompressibleAccountState {
     /// Account public key
     pub pubkey: Pubkey,
+    /// The decoded CToken account data
     pub account: CToken,
+    /// Current lamport balance of the CToken account
     pub lamports: u64,
     /// The slot at which this account becomes compressible (last_funded_epoch * SLOTS_PER_EPOCH)
     /// Accounts are ready to compress when current_slot > compressible_slot
     pub compressible_slot: u64,
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ea0d21 and c0000a1.

📒 Files selected for processing (9)
  • forester/src/compressible/bootstrap.rs (1 hunks)
  • forester/src/compressible/mod.rs (1 hunks)
  • forester/src/compressible/state.rs (1 hunks)
  • forester/src/compressible/types.rs (1 hunks)
  • forester/src/lib.rs (5 hunks)
  • forester/src/main.rs (2 hunks)
  • forester/tests/e2e_test.rs (9 hunks)
  • forester/tests/test_batch_append_spent.rs (1 hunks)
  • forester/tests/test_compressible_ctoken.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/tests/test_batch_append_spent.rs
  • forester/src/compressible/types.rs
  • forester/src/lib.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/src/main.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/lib.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/lib.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/lib.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/lib.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:43.242Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-token-test/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:43.242Z
Learning: Applies to sdk-tests/sdk-token-test/**/tests/**/*.rs : Every test should only contain functional integration tests

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Each new operation module must define an Anchor context struct (e.g., NewOperationContext) with required accounts and a process_<operation> function that prepares signer seeds, maps accounts to the target program, and executes the CPI.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/lib.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • forester/tests/test_compressible_ctoken.rs
  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md

Applied to files:

  • forester/src/compressible/types.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/docs/{CLAUDE.md,ACCOUNT_INFO_TRAIT.md,ACCOUNT_CHECKS.md,ACCOUNT_ITERATOR.md,ERRORS.md,DISCRIMINATOR.md,PACKED_ACCOUNTS.md} : Keep component documentation up to date in the corresponding docs/*.md files listed

Applied to files:

  • forester/src/compressible/types.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/src/compressible/types.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/src/lib.rs
  • forester/src/compressible/state.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/error.rs : Define error types with numeric codes in the 19xxx range and propagate hasher errors in the 7xxx range; include ProgramError conversions (Anchor, Pinocchio, Solana) in src/error.rs

Applied to files:

  • forester/src/lib.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers (derive_pda, derive_v1_config_pda) in src/config.rs for CompressibleConfig

Applied to files:

  • forester/src/lib.rs
  • forester/src/compressible/mod.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Apply forester eligibility rules: with a forester PDA, validate epoch registration, eligibility, track work, and require network fee; without a forester PDA, ensure authority matches the tree’s designated forester.

Applied to files:

  • forester/tests/e2e_test.rs
🧬 Code graph analysis (6)
forester/tests/test_compressible_ctoken.rs (7)
sdk-libs/client/src/local_test_validator.rs (1)
  • spawn_validator (28-71)
programs/registry/src/sdk.rs (3)
  • create_finalize_registration_instruction (240-258)
  • create_register_forester_epoch_pda_instruction (214-238)
  • create_register_forester_instruction (146-172)
programs/registry/src/utils.rs (3)
  • get_forester_pda (34-36)
  • get_protocol_config_pda_address (5-7)
  • get_forester_epoch_pda_from_authority (13-16)
forester/src/compressible/state.rs (3)
  • new (52-56)
  • default (180-182)
  • len (98-100)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
sdk-libs/client/src/rpc/rpc_trait.rs (3)
  • new (34-42)
  • new (76-78)
  • local (53-61)
forester/src/compressible/bootstrap.rs (1)
  • bootstrap_compressible_accounts (21-37)
forester/src/compressible/bootstrap.rs (1)
forester/src/compressible/state.rs (1)
  • new (52-56)
forester/src/lib.rs (4)
forester/src/compressible/state.rs (1)
  • new (52-56)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/epoch_manager.rs (2)
  • new (137-190)
  • run_service (2095-2228)
forester/src/compressible/bootstrap.rs (1)
  • bootstrap_compressible_accounts (21-37)
forester/src/compressible/state.rs (3)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/compressible/compressor.rs (1)
  • new (35-45)
forester/src/epoch_manager.rs (10)
  • new (137-190)
  • rpc (465-466)
  • rpc (508-509)
  • rpc (720-721)
  • rpc (760-761)
  • rpc (775-776)
  • rpc (825-826)
  • rpc (884-885)
  • rpc (906-907)
  • rpc (1925-1926)
forester/src/compressible/mod.rs (1)
forester/src/compressible/bootstrap.rs (1)
  • bootstrap_compressible_accounts (21-37)
forester/tests/e2e_test.rs (4)
forester/src/epoch_manager.rs (10)
  • rpc (465-466)
  • rpc (508-509)
  • rpc (720-721)
  • rpc (760-761)
  • rpc (775-776)
  • rpc (825-826)
  • rpc (884-885)
  • rpc (906-907)
  • rpc (1925-1926)
  • new (137-190)
forester/tests/legacy/batched_state_async_indexer_test.rs (1)
  • setup_forester_pipeline (277-298)
forester/tests/legacy/address_v2_test.rs (1)
  • setup_forester_pipeline (168-187)
program-libs/compressed-account/src/lib.rs (5)
  • from (86-111)
  • from (116-118)
  • from (123-125)
  • from (153-162)
  • from (209-218)
⏰ 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: Forester e2e test
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test batched-merkle-tree-simulate
🔇 Additional comments (13)
forester/tests/test_batch_append_spent.rs (1)

324-343: Test wiring for compressible shutdown looks correct

The test’s run_forester helper now correctly mirrors the new run_pipeline signature: it passes a dedicated compressible shutdown receiver and sends both service and compressible shutdown signals before joining. Using let _ = ...send(()) is appropriate here to avoid teardown panics if the receiver has already completed.

forester/src/lib.rs (1)

4-5: Compressible tracker integration and shutdown wiring look coherent

A few things done well here:

  • Module surface: Exporting compressible and slot_tracker from lib.rs matches how other subsystems are exposed and makes the new types (like CompressibleAccountTracker and CompressibleAccountState) available to callers in a consistent way.

  • TreeType::Unknown handling: Treating TreeType::Unknown as a no-op in run_queue_info is appropriate for a virtual “compression-only” tree; this avoids spurious queue lookups or panics when new tree types are introduced.

  • Lifecycle of the compressible tracker:

    • The tracker is created only when config.compressible_config is present and a compressible shutdown receiver is provided, which avoids dangling tasks when the caller hasn’t wired shutdown correctly.
    • The WebSocket AccountSubscriber and HTTP bootstrap (bootstrap_compressible_accounts) both share the same Arc<CompressibleAccountTracker>, and their shutdown is cleanly coordinated via the dedicated oneshot receivers.
    • Passing compressible_tracker: Option<Arc<...>> down into run_service keeps compression optional and makes it explicit in the EpochManager constructor.

Overall, the design keeps the compressible feature opt‑in while integrating cleanly with the existing pipeline and shutdown model.

Also applies to: 18-19, 149-151, 157-265, 267-278

forester/tests/test_compressible_ctoken.rs (2)

263-337: Compression flow and tracker post-conditions look sound overall

The rest of the compression test wiring is coherent:

  • get_ready_to_compress(current_slot) correctly targets only the 0-epoch account.
  • registered_forester_pda is derived via get_forester_epoch_pda_from_authority, consistent with registry SDK patterns.
  • The loop polling get_account(token_account_pubkey_2) with a 30s timeout is a good defensive pattern, and verifying tracker.len() == 1 afterwards asserts correct tracker cleanup.

Once the subscriber timing concerns are addressed, this test should provide strong coverage of the end-to-end compressible flow.


339-417: Bootstrap integration test structure looks robust

The localhost bootstrap test sets up accounts, then waits (with a 60s timeout) until tracker.len() >= expected_count and validates mint, lamports, and presence of the Compressible extension, as well as compressible_slot < u64::MAX. This matches the intended semantics of the tracker and bootstrap logic and uses timeouts appropriately.

forester/src/compressible/state.rs (3)

179-183: Default impl delegating to new is idiomatic

Implementing Default by calling Self::new() is idiomatic and keeps tracker construction consistent wherever Default is used.


15-42: Verification complete: Constants and epoch calculations align with on-chain Light Protocol definitions

All three constants have been verified:

  • COMPRESSIBLE_TOKEN_ACCOUNT_SIZE: Correctly computed as BASE_TOKEN_ACCOUNT_SIZE + CompressionInfo::LEN + EXTENSION_METADATA (ctoken-types/src/constants.rs)
  • COMPRESSIBLE_TOKEN_RENT_EXEMPTION: 2,700,480 lamports (ctoken-types/src/constants.rs:22)
  • SLOTS_PER_EPOCH: 6,300 slots (≈1.75h) per Light Protocol (compressible/src/rent/config.rs:11)

The forester code correctly imports light_compressible::rent::SLOTS_PER_EPOCH with no local redefinitions or hardcoded Solana epoch values (432,000). The documentation distinguishes Solana's 432,000-slot mainnet epoch for reference—this is intentional and does not conflict with Light Protocol's optimized 6,300-slot epoch.

The calculate_compressible_slot() function properly chains the Compressible extension's get_last_funded_epoch() call through Light Protocol's epoch boundary, aligning precisely with the rent calculation model. The original review comment's analysis stands.


107-142: Verification confirms all safety assumptions hold—code is appropriate and correct.

Your review comment accurately reflects the design. The verification confirms:

  1. CToken Borsh layout is stable: The custom BorshDeserialize impl at program-libs/ctoken-types/src/state/ctoken/borsh.rs:62 hardcodes the field layout (mint → owner → amount → delegate → state → is_native → delegated_amount → close_authority → extensions), matching the COMPRESSIBLE_TOKEN_ACCOUNT_SIZE constant (260 bytes) defined in program-libs/ctoken-types/src/constants.rs.

  2. Filtering is bulletproof: Both subscriber.rs (lines 48–53) and bootstrap.rs filter accounts by COMPRESSED_TOKEN_PROGRAM_ID and COMPRESSIBLE_TOKEN_ACCOUNT_SIZE before deserialization. Bootstrap additionally validates the Compressible extension presence (lines 111–117), providing defense-in-depth.

  3. No schema mismatch risk: Because accounts come through this narrow, validated pipeline, the custom Borsh layout is guaranteed to align with on-chain CToken accounts. Any future schema changes would need coordinated updates across ctoken-types and the size constant.

The off-chain mirror pattern is well-founded here.

forester/src/compressible/mod.rs (1)

1-13: Module wiring and re-exports are clean and match project conventions

The compressible module neatly exposes:

  • Submodules for bootstrap/compressor/config/state/subscriber/types.
  • A focused public surface via pub use for the main types and functions used by tests and run_pipeline.

This mirrors patterns used elsewhere in the codebase (e.g., registry account_compression_cpi) and makes the compressible feature easy to import as forester::compressible::*.

forester/tests/e2e_test.rs (5)

423-425: Updated setup_forester_pipeline signature and run_pipeline wiring are consistent

The new setup_forester_pipeline signature:

(
    JoinHandle<anyhow::Result<()>>,
    oneshot::Sender<()>,
    oneshot::Sender<()>, // shutdown_compressible_sender
    mpsc::Receiver<WorkReport>,
)

and the call to run_pipeline:

run_pipeline::<LightClient>(
    Arc::from(config.clone()),
    None,
    None,
    shutdown_receiver,
    Some(shutdown_compressible_receiver),
    None, // shutdown_bootstrap
    work_report_sender,
)

match the extended pipeline API, cleanly threading the compressible shutdown channel while keeping the existing work-report flow intact. Ignoring the shutdown_compressible_sender in this test is acceptable since the main shutdown signal should tear down all subsystems.

If you later want to exercise a graceful compressible shutdown in tests, you can send on shutdown_compressible_sender and assert that compression tasks stop as expected.

Also applies to: 726-753


254-257: CompressibleConfig wiring verified—fields and types match correctly

The struct definition in forester/src/compressible/config.rs confirms both fields are wired correctly:

  • ws_url: String receives get_ws_rpc_url()
  • batch_size: usize receives 10 (matching the struct's default) ✓

Field names and types align with the test instantiation exactly. The configuration integrates cleanly into the e2e harness using existing RPC helpers, maintaining consistency across subsystems.


629-631: Explicitly rejecting TreeType::Unknown for Merkle state/root checks is correct

Adding explicit TreeType::Unknown branches that panic! in get_initial_merkle_tree_state (lines 629-631) and verify_root_changed (lines 703-705) is the right approach. TreeType::Unknown is reserved for compression trees throughout the codebase (a virtual tree type used in epoch_manager.rs and lib.rs for compression handling), and these trees don't expose Merkle state the same way regular state/address trees do. Failing fast with clear messages prevents subtle test misbehavior and maintains type safety.


389-406: Use derived compressed mint address, not arbitrary Pubkey::new_unique()

The mint for compressible token accounts must be derived via create_compressed_mint::derive_compressed_mint_address() to match the compressed mint PDA scheme. The code comment at line 39 of create_token_account.rs explicitly notes the mint is "only used for pubkey not checked," meaning the instruction accepts any arbitrary pubkey without validation. While this won't cause immediate failure, it creates accounts with invalid mint references that violate on-chain invariants.

At lines 394 and 431 in forester/tests/e2e_test.rs, pass a properly derived mint instead:

let mint_seed = Keypair::new();
let address_tree = rpc.get_address_tree_v2().tree;
let mint = Pubkey::from(create_compressed_mint::derive_compressed_mint_address(
    &mint_seed.pubkey(),
    &address_tree,
));

This matches the pattern established in test_compressible_ctoken.rs (lines 222–225, 374–377) and ensures the compressible account's mint is a valid compressed mint PDA, preventing failures during compression/decompression operations.

⛔ Skipped due to learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/MINT_ACTION.md : Document Mint operations and compressed mint management (9 actions) in instructions/MINT_ACTION.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

389-406: Preserve both account references and add timeout-based polling for reliable verification

The test creates two compressible accounts but loses the first one due to variable shadowing:

  • Line 392: let compressible_account = ... (bootstrap account)
  • Line 432: let compressible_account = ... (overwrites reference to first)

The final verification (line 514) checks only the second account with a single get_account() call, missing the bootstrap path and relying on unreliable single-shot checks.

Fix:

  • Rename first to bootstrap_account, second to subscriber_account (lines 392, 432)
  • Replace single-shot check with timeout polling loop, matching the pattern already used elsewhere in this file (lines 760–800: while + timeout() + match)
  • Poll both accounts until each shows None or lamports == 0, or timeout after 30–60s

This mirrors how accounts are actually garbage-collected on-chain: asynchronously across slots, not instantly.

⛔ Skipped due to learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/{ACCOUNT_INFO_TRAIT.md,ACCOUNT_CHECKS.md,ACCOUNT_ITERATOR.md,DISCRIMINATOR.md,ERRORS.md,PACKED_ACCOUNTS.md} : Code examples should demonstrate both Solana and Pinocchio usage where applicable
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
forester/src/epoch_manager.rs (1)

1644-1754: Critical: Authority mismatch in Compressor instantiation (duplicate of existing issue).

At lines 1674-1678, Compressor::new is called without passing authority_pubkey. However, as flagged in the past review comment on compressor.rs, the Compressor struct needs to store and use the registered authority (from ForesterConfig.derivation_pubkey) for epoch PDA derivation, not the payer_keypair.pubkey().

While this code correctly derives registered_forester_pda using self.config.derivation_pubkey at lines 1681-1685, the Compressor internally will derive epoch PDAs using payer_keypair.pubkey() in its compress_batch method, causing a mismatch when payer != authority.

This is already documented in the past review comment for compressor.rs but directly impacts this dispatch logic.

Based on learnings

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0000a1 and 32f75df.

📒 Files selected for processing (5)
  • forester/src/compressible/compressor.rs (1 hunks)
  • forester/src/compressible/config.rs (1 hunks)
  • forester/src/compressible/subscriber.rs (1 hunks)
  • forester/src/epoch_manager.rs (12 hunks)
  • forester/tests/e2e_test.rs (9 hunks)
🧰 Additional context used
🧠 Learnings (36)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Read this file and all referenced Markdown files in full before working on the compressed-token program
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
  • forester/src/compressible/config.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/config.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
  • forester/src/compressible/config.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/!(account_info)/**/*.rs : Use AccountInfoTrait for runtime-agnostic account handling; avoid direct solana-program or pinocchio AccountInfo in general logic

Applied to files:

  • forester/src/compressible/subscriber.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/src/compressible/subscriber.rs
  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Each new operation module must define an Anchor context struct (e.g., NewOperationContext) with required accounts and a process_<operation> function that prepares signer seeds, maps accounts to the target program, and executes the CPI.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers (derive_pda, derive_v1_config_pda) in src/config.rs for CompressibleConfig

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
  • forester/src/compressible/config.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Apply forester eligibility rules: with a forester PDA, validate epoch registration, eligibility, track work, and require network fee; without a forester PDA, ensure authority matches the tree’s designated forester.

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/src/compressible/compressor.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)

Applied to files:

  • forester/src/compressible/compressor.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
  • forester/src/compressible/config.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/error.rs : Define error types with numeric codes in the 19xxx range and propagate hasher errors in the 7xxx range; include ProgramError conversions (Anchor, Pinocchio, Solana) in src/error.rs

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/account_info_trait.rs : Ensure the crate compiles with no features enabled by keeping trait definitions free of SDK-specific dependencies

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Return AccountError variants (codes 12006–12021) and rely on automatic ProgramError conversions; avoid returning raw ProgramError directly

Applied to files:

  • forester/src/epoch_manager.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Instruction handlers must compute work_units by operation type: batch operations use account.queue_batches.batch_size; single operations use DEFAULT_WORK_V1; custom operations compute based on complexity.

Applied to files:

  • forester/src/compressible/config.rs
🧬 Code graph analysis (5)
forester/src/compressible/subscriber.rs (4)
forester/src/epoch_manager.rs (2)
  • new (137-190)
  • run (192-251)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/src/compressible/config.rs (1)
  • new (24-30)
forester/src/compressible/state.rs (1)
  • new (52-56)
forester/src/compressible/compressor.rs (2)
forester/src/compressible/state.rs (3)
  • new (52-56)
  • default (180-182)
  • len (98-100)
sdk-libs/sdk/src/instruction/pack_accounts.rs (1)
  • packed_accounts (348-351)
forester/tests/e2e_test.rs (5)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/src/compressible/config.rs (1)
  • new (24-30)
forester/src/compressible/state.rs (1)
  • new (52-56)
forester/tests/legacy/batched_state_async_indexer_test.rs (1)
  • setup_forester_pipeline (277-298)
forester/tests/legacy/address_v2_test.rs (1)
  • setup_forester_pipeline (168-187)
forester/src/epoch_manager.rs (6)
forester/src/compressible/subscriber.rs (2)
  • run (39-100)
  • new (27-37)
program-libs/batched-merkle-tree/src/merkle_tree.rs (6)
  • Self (123-123)
  • Self (138-138)
  • Self (150-150)
  • Self (166-166)
  • Self (177-177)
  • pubkey (939-941)
forester/src/compressible/state.rs (3)
  • default (180-182)
  • len (98-100)
  • new (52-56)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/src/compressible/config.rs (1)
  • new (24-30)
programs/registry/src/utils.rs (1)
  • get_forester_epoch_pda_from_authority (13-16)
forester/src/compressible/config.rs (3)
forester/src/epoch_manager.rs (1)
  • new (137-190)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/compressible/state.rs (1)
  • new (52-56)
⏰ 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-fast
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: Forester e2e test

@ananas-block ananas-block force-pushed the jorrit/feat-forester-compressible-ctoken-support branch from 740a3ce to 01f0f96 Compare November 13, 2025 23:23
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32f75df and 740a3ce.

📒 Files selected for processing (2)
  • forester/src/compressible/bootstrap.rs (1 hunks)
  • forester/src/compressible/state.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (27)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Read this file and all referenced Markdown files in full before working on the compressed-token program
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Each new operation module must define an Anchor context struct (e.g., NewOperationContext) with required accounts and a process_<operation> function that prepares signer seeds, maps accounts to the target program, and executes the CPI.

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-11T21:59:52.712Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/ERRORS.md : ERRORS.md must document error types with numeric codes in the 12006–12021 range, common causes, resolution strategies, and conversion mappings for Solana and Pinocchio

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-11T21:59:52.712Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/{ACCOUNT_INFO_TRAIT.md,ACCOUNT_CHECKS.md,ACCOUNT_ITERATOR.md,DISCRIMINATOR.md,ERRORS.md,PACKED_ACCOUNTS.md} : Code examples should demonstrate both Solana and Pinocchio usage where applicable

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/packed_accounts.rs : For dynamic account sets, use PackedAccounts for index-based access with bounds checks instead of manual indexing

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/!(account_info)/**/*.rs : Use AccountInfoTrait for runtime-agnostic account handling; avoid direct solana-program or pinocchio AccountInfo in general logic

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md

Applied to files:

  • forester/src/compressible/state.rs
🧬 Code graph analysis (2)
forester/src/compressible/bootstrap.rs (2)
forester/src/compressible/state.rs (1)
  • new (52-56)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
forester/src/compressible/state.rs (3)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/epoch_manager.rs (10)
  • new (137-190)
  • rpc (465-466)
  • rpc (508-509)
  • rpc (720-721)
  • rpc (760-761)
  • rpc (775-776)
  • rpc (825-826)
  • rpc (884-885)
  • rpc (906-907)
  • rpc (1953-1954)
⏰ 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). (7)
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Test program-libs-fast
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
  • GitHub Check: Forester e2e test
🔇 Additional comments (10)
forester/src/compressible/bootstrap.rs (4)

56-147: LGTM!

The process_account function has solid error handling throughout. Each potential failure (missing fields, parse errors, deserialization failures, missing extension) is logged at debug level and returns Ok(false) to skip the account without failing the entire bootstrap. The final delegation to tracker.update_from_account correctly handles the compressible slot calculation.


149-194: LGTM!

The send_rpc_request function properly handles all edge cases: shutdown requests via tokio::select!, HTTP errors, JSON parsing failures, and RPC-level errors. Error logging includes helpful context at each failure point.


196-317: LGTM!

The V2 API implementation correctly uses paginationKey for pagination (lines 228, 294), implements graceful shutdown handling, and includes thoughtful response format flexibility (lines 255-267) to accommodate different RPC provider response structures. The 100ms inter-request delay helps mitigate rate limiting.


319-384: LGTM!

The standard API implementation is straightforward and appropriate for localhost/test validator usage. It correctly fetches all accounts in a single request and reuses the same process_account logic for consistency.

forester/src/compressible/state.rs (6)

44-67: LGTM!

The tracker structure correctly uses Arc<DashMap<...>> for thread-safe concurrent access, and the basic operations (new, insert, remove) are straightforward wrappers with appropriate semantics.


68-95: LGTM with awareness of allocation pattern.

Both query methods iterate and clone entries into a Vec. As previously noted in past reviews, this is acceptable for current test and small-scale usage. The filtering logic correctly identifies compressible accounts (line 75-78) and ready-to-compress accounts (line 91).


107-142: LGTM!

The update_from_account method properly deserializes the CToken data (with error handling), recalculates the compressible slot based on current lamports, and logs detailed state for debugging. The error propagation via Result is appropriate.


144-211: LGTM! All previous concerns addressed.

The sync_accounts implementation now properly handles all edge cases that were raised in previous reviews:

  1. Closed accounts (lines 156-161): Accounts with lamports == 0 are removed from tracking
  2. Deserialization validation (lines 164-174): Account data is re-deserialized and invalid accounts are removed
  3. Extension validation (lines 176-189): The Compressible extension is verified to still exist before updating state

The batch RPC fetch via get_multiple_accounts is efficient, and the per-account processing correctly updates or removes entries based on current on-chain state.


214-218: LGTM!

Standard Default implementation that delegates to new().


27-34: The review comment is based on an incorrect assumption about error behavior and should be disregarded.

Verification shows that the underlying get_last_funded_epoch function returns a bare u64, not Result. The implementation uses only infallible operations: get_available_rent_balance(), arithmetic, and saturating_sub() to prevent panics.

The wrapper at compression_info.rs:146 converts this infallible u64 into Ok(u64) for type matching, but the method always wraps the result in Ok(...) and never propagates errors. Consequently, the .unwrap_or(0) at line 34 of forester/src/compressible/state.rs will always succeed—the fallback to 0 will never execute because the unwrap() never fails.

No error handling issue exists here. The code is correct as written.

Likely an incorrect or invalid review comment.

@ananas-block ananas-block force-pushed the jorrit/feat-forester-compressible-ctoken-support branch from 01f0f96 to 02e6b82 Compare November 13, 2025 23:31
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
forester/src/compressible/state.rs (1)

15-41: Handle get_last_funded_epoch errors explicitly instead of defaulting to epoch 0

Right now, any error from compressible_ext.get_last_funded_epoch is mapped to last_funded_epoch = 0 via unwrap_or(0). That makes the derived compressible_slot equal to 0 * SLOTS_PER_EPOCH, so any current slot > 0 will treat the account as immediately compressible—even if the underlying rent calculation failed due to inconsistent lamports/config.

Given the rent semantics in light_compressible::rent and the importance of respecting the rent curve for compressible accounts, it would be safer to distinguish “cannot compute last funded epoch” from “funded up to epoch 0`. For example:

  • On error, log and return u64::MAX (never compressible), or
  • Propagate an error up into the tracker and avoid inserting/updating that account.

That avoids accidentally compressing accounts whose rent state is invalid or misconfigured. Based on learnings

-        let last_funded_epoch = compressible_ext
-            .get_last_funded_epoch(
-                COMPRESSIBLE_TOKEN_ACCOUNT_SIZE,
-                lamports,
-                COMPRESSIBLE_TOKEN_RENT_EXEMPTION,
-            )
-            .unwrap_or(0);
+        let last_funded_epoch = match compressible_ext.get_last_funded_epoch(
+            COMPRESSIBLE_TOKEN_ACCOUNT_SIZE,
+            lamports,
+            COMPRESSIBLE_TOKEN_RENT_EXEMPTION,
+        ) {
+            Ok(epoch) => epoch,
+            Err(e) => {
+                tracing::debug!(
+                    "Failed to compute last_funded_epoch for account (lamports={}): {:?}; \
+                     treating as non-compressible",
+                    lamports,
+                    e
+                );
+                return u64::MAX;
+            }
+        };
forester/src/compressible/bootstrap.rs (2)

17-37: Non‑localhost forcing getProgramAccountsV2 without fallback makes bootstrap fragile

bootstrap_compressible_accounts currently routes every non‑localhost RPC URL through getProgramAccountsV2, with no fallback to the standard getProgramAccounts path if the RPC node doesn’t support the V2 method. That means pointing forester at a vanilla Solana RPC (or any non‑Helius enhanced provider) will cause bootstrap to fail instead of gracefully degrading.

Given the earlier discussion around provider differences, I’d strongly recommend either:

  • Making the V2 vs standard method selection explicit in config (e.g., a use_v2_api flag or provider type), or
  • Detecting “method not found”/similar RPC errors from the V2 request, logging a warning, and retrying bootstrap via bootstrap_with_standard_api.

That keeps compressible support from being silently coupled to one specific provider type.


179-300: V2 bootstrap loop looks correct; consider tuning PAGE_SIZE via config

The V2 bootstrap loop correctly:

  • Builds a getProgramAccountsV2 payload with paginationKey support.
  • Accepts multiple result shapes (accounts, array result, or value).
  • Uses process_account for validation and tracker updates.
  • Advances the cursor from paginationKey and sleeps briefly between pages.

The only remaining nit is PAGE_SIZE = 10_000; on some providers this may be aggressive for free tiers or tighter rate limits. If this is intended to be provider‑agnostic, making the page size configurable (or lowering the default into the 1k–5k range) would give you safer defaults without changing behavior for tests.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 740a3ce and 02e6b82.

📒 Files selected for processing (3)
  • forester/src/compressible/bootstrap.rs (1 hunks)
  • forester/src/compressible/state.rs (1 hunks)
  • forester/tests/e2e_test.rs (9 hunks)
🧰 Additional context used
🧠 Learnings (35)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Read this file and all referenced Markdown files in full before working on the compressed-token program
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/!(account_info)/**/*.rs : Use AccountInfoTrait for runtime-agnostic account handling; avoid direct solana-program or pinocchio AccountInfo in general logic

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:52.712Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/ERRORS.md : ERRORS.md must document error types with numeric codes in the 12006–12021 range, common causes, resolution strategies, and conversion mappings for Solana and Pinocchio

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-11T21:59:52.712Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/{ACCOUNT_INFO_TRAIT.md,ACCOUNT_CHECKS.md,ACCOUNT_ITERATOR.md,DISCRIMINATOR.md,ERRORS.md,PACKED_ACCOUNTS.md} : Code examples should demonstrate both Solana and Pinocchio usage where applicable

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers (derive_pda, derive_v1_config_pda) in src/config.rs for CompressibleConfig

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • forester/tests/e2e_test.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Apply forester eligibility rules: with a forester PDA, validate epoch registration, eligibility, track work, and require network fee; without a forester PDA, ensure authority matches the tree’s designated forester.

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/packed_accounts.rs : For dynamic account sets, use PackedAccounts for index-based access with bounds checks instead of manual indexing

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)

Applied to files:

  • forester/src/compressible/state.rs
🧬 Code graph analysis (3)
forester/src/compressible/bootstrap.rs (2)
forester/src/compressible/state.rs (1)
  • new (52-56)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
forester/tests/e2e_test.rs (6)
forester/tests/test_utils.rs (3)
  • rpc (344-344)
  • get_active_phase_start_slot (319-327)
  • wait_for_slot (330-339)
forester/src/compressible/state.rs (1)
  • new (52-56)
forester/src/compressible/config.rs (1)
  • new (24-30)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/tests/legacy/batched_state_async_indexer_test.rs (3)
  • setup_forester_pipeline (277-298)
  • get_active_phase_start_slot (610-618)
  • wait_for_slot (300-309)
program-libs/compressed-account/src/lib.rs (5)
  • from (86-111)
  • from (116-118)
  • from (123-125)
  • from (153-162)
  • from (209-218)
forester/src/compressible/state.rs (3)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/src/epoch_manager.rs (10)
  • new (137-190)
  • rpc (465-466)
  • rpc (508-509)
  • rpc (720-721)
  • rpc (760-761)
  • rpc (775-776)
  • rpc (825-826)
  • rpc (884-885)
  • rpc (906-907)
  • rpc (1953-1954)
⏰ 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: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: Test batched-merkle-tree-simulate
🔇 Additional comments (7)
forester/src/compressible/state.rs (2)

44-105: Tracker structure and basic queries look solid

The CompressibleAccountTracker API (insert/remove, get_ready_to_compress, len, is_empty) over an Arc<DashMap<Pubkey, CompressibleAccountState>> is straightforward and thread‑safe, and the extension checks in get_compressible_accounts avoid accidentally exposing non‑compressible accounts. This is a good minimal abstraction for now, especially given the planned move to a DB backend.


107-211: update_from_account + sync_accounts robustness is in good shape

Deserializing CToken via Borsh, recomputing compressible_slot, and storing the full account snapshot in update_from_account is clean. In sync_accounts, you:

  • Drop closed accounts (lamports == 0).
  • Re-deserialize on each refresh and remove entries that fail to deserialize.
  • Remove entries whose CToken no longer carries the Compressible extension.
  • Only then update state.account, state.lamports, and state.compressible_slot.

That gives you a resilient reconciliation loop against on-chain reality and prevents the tracker from holding stale or non‑compressible entries. Nice work tightening this up.

forester/src/compressible/bootstrap.rs (2)

133-177: RPC wrapper + shutdown behavior is clean

send_rpc_request nicely centralizes the JSON‑RPC POST, status/error handling, and shutdown-aware cancellation via tokio::select!, and it normalizes the response to the result payload. This keeps both bootstrap paths simple and gives you a single place to improve logging or backoff in the future.


302-367: Standard getProgramAccounts bootstrap path is straightforward and aligned with V2

The localhost standard‑API path mirrors the V2 path cleanly: same filters, encoding, and process_account usage, just without pagination. This keeps local/test‑validator behavior simple while still enforcing the same Compressible extension checks.

forester/tests/e2e_test.rs (3)

205-259: Compressible config wiring in ForesterConfig looks good

Initializing compressible_config in the E2E test with a concrete ws_url, batch_size, and max_concurrent_batches ensures the new compressible pipeline is exercised under test rather than left unused. This is a good way to validate the end‑to‑end wiring for the new feature.


424-431: Additional shutdown channels and pipeline wiring are appropriate

Extending setup_forester_pipeline and the run_pipeline invocation to include separate shutdown channels for the compressible worker and the bootstrap task is a good separation of concerns. The final test section cleanly signals shutdown_bootstrap_sender, shutdown_compressible_sender, and then the main shutdown_sender, ensuring all long‑running tasks are asked to stop before awaiting the service handle.

Also applies to: 739-770


642-645: Explicit panics for TreeType::Unknown provide clear guardrails

Adding TreeType::Unknown arms that panic! in both get_initial_merkle_tree_state and verify_root_changed makes the unsupported nature of compression trees in these utilities explicit. That’s preferable to silently doing the wrong thing if an Unknown tree type ever leaks into these E2E helpers.

Also applies to: 716-718

@ananas-block ananas-block force-pushed the jorrit/feat-forester-compressible-ctoken-support branch from 02e6b82 to 026cf52 Compare November 13, 2025 23:56
@ananas-block ananas-block force-pushed the jorrit/feat-forester-compressible-ctoken-support branch from 026cf52 to 6bd0459 Compare November 14, 2025 00:01
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
forester/tests/e2e_test.rs (1)

733-735: Same pattern as Line 660 - defensive panic for Unknown tree type.

This follows the same defensive programming pattern as get_initial_merkle_tree_state. The same type-safety considerations apply.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32f75df and 6bd0459.

📒 Files selected for processing (3)
  • forester/src/compressible/bootstrap.rs (1 hunks)
  • forester/src/compressible/state.rs (1 hunks)
  • forester/tests/e2e_test.rs (9 hunks)
🧰 Additional context used
🧠 Learnings (38)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Ensure serialization compatibility across Anchor, Pinocchio, and Borsh for core account types used by dependent programs

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Maintain CompressibleConfig account structure with Anchor/Borsh/Pod (Pinocchio/Pod) serialization and related state validation methods (validate_active, validate_not_inactive) in src/config.rs

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Load accounts according to type before check_forester: batched via BatchedMerkleTreeAccount::type_from_account_info(); regular via ctx.accounts.account.load()?.metadata; use custom deserialization when required.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Provide SDK-specific AccountInfoTrait implementations in account_info/{solana.rs,pinocchio.rs,test_account_info.rs}

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Document the CompressibleConfig account structure and methods in docs/CONFIG_ACCOUNT.md

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Each new operation module must define an Anchor context struct (e.g., NewOperationContext) with required accounts and a process_<operation> function that prepares signer seeds, maps accounts to the target program, and executes the CPI.

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:52.712Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/ERRORS.md : ERRORS.md must document error types with numeric codes in the 12006–12021 range, common causes, resolution strategies, and conversion mappings for Solana and Pinocchio

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-11T21:59:52.712Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.712Z
Learning: Applies to program-libs/account-checks/docs/**/{ACCOUNT_INFO_TRAIT.md,ACCOUNT_CHECKS.md,ACCOUNT_ITERATOR.md,DISCRIMINATOR.md,ERRORS.md,PACKED_ACCOUNTS.md} : Code examples should demonstrate both Solana and Pinocchio usage where applicable

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/lib.rs : Wrapper instruction handlers must: (1) load the target account metadata; (2) call check_forester with correct authority, target, forester PDA (optional), and computed work_units; (3) delegate via a CPI using a PDA signer.

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: When working with ctoken accounts that have the Compressible extension, consult the rent system documentation (RENT.md, CONFIG_ACCOUNT.md, SOLANA_RENT.md) to follow rent authority, compression, and lamport distribution rules

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Validate account type with 8-byte discriminators using check_discriminator before deserialization

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : On account initialization, call account_info_init to set the 8-byte discriminator

Applied to files:

  • forester/src/compressible/bootstrap.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/src/compressible/bootstrap.rs
  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement and maintain rent calculation algorithms (rent_curve_per_epoch, calculate_rent_and_balance, claimable_lamports, calculate_close_lamports) in src/rent.rs

Applied to files:

  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures

Applied to files:

  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/packed_accounts.rs : For dynamic account sets, use PackedAccounts for index-based access with bounds checks instead of manual indexing

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.222Z
Learning: Applies to program-libs/account-checks/src/!(account_info)/**/*.rs : Use AccountInfoTrait for runtime-agnostic account handling; avoid direct solana-program or pinocchio AccountInfo in general logic

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : Compress & Close operations (via registry) must validate that the config state is not INACTIVE (active or deprecated allowed)

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md

Applied to files:

  • forester/src/compressible/state.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide default initialization for the CToken V1 config in CompressibleConfig

Applied to files:

  • forester/src/compressible/state.rs
  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • forester/tests/e2e_test.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:19.426Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers (derive_pda, derive_v1_config_pda) in src/config.rs for CompressibleConfig

Applied to files:

  • forester/tests/e2e_test.rs
🧬 Code graph analysis (3)
forester/src/compressible/bootstrap.rs (1)
forester/src/compressible/state.rs (1)
  • new (59-63)
forester/src/compressible/state.rs (3)
forester/src/compressible/subscriber.rs (1)
  • new (27-37)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/src/epoch_manager.rs (10)
  • new (137-190)
  • rpc (465-466)
  • rpc (508-509)
  • rpc (720-721)
  • rpc (760-761)
  • rpc (775-776)
  • rpc (825-826)
  • rpc (884-885)
  • rpc (906-907)
  • rpc (1953-1954)
forester/tests/e2e_test.rs (5)
forester/src/compressible/config.rs (1)
  • new (24-30)
forester/src/compressible/compressor.rs (1)
  • new (45-55)
forester/tests/legacy/batched_state_async_indexer_test.rs (1)
  • setup_forester_pipeline (277-298)
forester/tests/legacy/address_v2_test.rs (1)
  • setup_forester_pipeline (168-187)
program-libs/compressed-account/src/lib.rs (5)
  • from (86-111)
  • from (116-118)
  • from (123-125)
  • from (153-162)
  • from (209-218)
⏰ 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: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
  • GitHub Check: Test batched-merkle-tree-simulate
🔇 Additional comments (7)
forester/tests/e2e_test.rs (7)

38-50: LGTM! Imports align with compressible token test requirements.

The imports for TokenDataVersion and create_compressible_token_account are used appropriately throughout the test for creating and configuring compressible token accounts.


254-258: LGTM! Compressible config properly initialized.

The compressible_config is correctly added to ForesterConfig with explicit batch size and concurrency limits. The hardcoded values (batch_size: 10, max_concurrent_batches: 10) are reasonable for test scenarios.


390-409: LGTM! Bootstrap compressible account properly configured.

The first compressible account is correctly created with 0 prepaid epochs, making it immediately eligible for compression by the bootstrapping process. Clear naming (compressible_account_bootstrap) distinguishes it from the subscriber account created later.


427-433: LGTM! Pipeline setup correctly captures new shutdown channels.

The destructuring properly captures the two additional shutdown channels (shutdown_compressible_sender and shutdown_bootstrap_sender) added for the new compressible token services.


438-457: LGTM! Subscriber compressible account created at the right time.

The second compressible account is intentionally created after the forester pipeline starts, allowing the test to verify that the subscriber properly detects and processes newly created compressible accounts.


548-551: LGTM! Graceful shutdown handling for optional services.

The shutdown logic correctly uses let _ = for bootstrap and compressible services that may have already completed, while keeping strict error handling for the main pipeline shutdown.


756-787: LGTM! Pipeline setup properly wired with new shutdown channels.

The function signature correctly adds two new shutdown channels for compressible and bootstrap services. The channels are properly created, passed to run_pipeline, and returned to the caller.

Comment on lines +39 to +44
/// Process a single account from RPC response
/// Returns Ok(true) if account was inserted, Ok(false) if skipped, Err on critical failure
fn process_account(
account_value: &serde_json::Value,
tracker: &CompressibleAccountTracker,
) -> Result<bool> {
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Documentation inaccuracy about error returns.

The comment states Returns Ok(true) if account was inserted, Ok(false) if skipped, Err on critical failure, but examining the implementation reveals that most validation failures (pubkey parsing, data extraction, deserialization, missing extension) return Ok(false), while only tracker.update_from_account failures at line 132 propagate Err. This mixed strategy is confusing—either all failures should return Ok(false) (making the function infallible from the caller's perspective), or critical failures like deserialization should return Err.

Consider aligning the implementation with the doc or updating the doc to clarify that only tracker insertion failures return Err.

🤖 Prompt for AI Agents
In forester/src/compressible/bootstrap.rs around lines 39 to 44, the function
docstring is inaccurate: it claims the function returns Err on critical
failures, but the implementation treats most validation/deserialization failures
as Ok(false) and only returns Err from tracker.update_from_account; update the
comment to reflect that behavior (e.g., "Returns Ok(true) if account was
inserted, Ok(false) if skipped or invalid, Err only if
tracker.update_from_account fails") or alternatively change the implementation
to propagate deserialization/validation errors as Err—pick one approach and make
the doc and code consistent, ensuring the chosen semantics are clearly
documented in the comment.

Comment on lines +15 to +49
/// Calculate the slot at which an account becomes compressible
/// Returns the last funded slot; accounts are compressible when current_slot > this value
fn calculate_compressible_slot(account: &CToken, lamports: u64) -> Result<u64> {
use light_compressible::rent::SLOTS_PER_EPOCH;

// Find the Compressible extension
let compressible_ext = account
.extensions
.as_ref()
.and_then(|exts| {
exts.iter().find_map(|ext| match ext {
ExtensionStruct::Compressible(comp) => Some(comp),
_ => None,
})
})
.ok_or_else(|| anyhow::anyhow!("Account missing Compressible extension"))?;

// Calculate last funded epoch
let last_funded_epoch = compressible_ext
.get_last_funded_epoch(
COMPRESSIBLE_TOKEN_ACCOUNT_SIZE,
lamports,
COMPRESSIBLE_TOKEN_RENT_EXEMPTION,
)
.map_err(|e| {
anyhow::anyhow!(
"Failed to calculate last funded epoch for account with {} lamports: {:?}",
lamports,
e
)
})?;

// Convert to slot
Ok(last_funded_epoch * SLOTS_PER_EPOCH)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Clarify epoch-to-slot conversion semantics for compressibility check.

The function calculates compressible_slot = last_funded_epoch * SLOTS_PER_EPOCH and the comment states "accounts are compressible when current_slot > this value." However, this creates potential ambiguity:

  • If get_last_funded_epoch returns the last epoch during which the account is funded (e.g., epoch 5), then slots [5 * SLOTS_PER_EPOCH, 6 * SLOTS_PER_EPOCH) are still funded, and the account should only become compressible at (last_funded_epoch + 1) * SLOTS_PER_EPOCH.
  • The current implementation would incorrectly mark accounts as compressible during their last funded epoch.

Verify the semantics of get_last_funded_epoch and adjust the calculation if needed:

-    // Convert to slot
-    Ok(last_funded_epoch * SLOTS_PER_EPOCH)
+    // Account becomes compressible at the start of the epoch after last_funded_epoch
+    Ok((last_funded_epoch + 1) * SLOTS_PER_EPOCH)

Or update the documentation if the current calculation is correct and get_last_funded_epoch returns the first unfunded epoch.


🏁 Script executed:

#!/bin/bash
# Verify the semantics of get_last_funded_epoch from the compressible library
ast-grep --pattern 'fn get_last_funded_epoch($$$) {
  $$$
}'

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Find get_last_funded_epoch definition in light_compressible module
rg -n "fn get_last_funded_epoch" --type rust

Length of output: 180


🏁 Script executed:

#!/bin/bash
# Find documentation files about rent
fd -e md | rg -i "rent|compressible"

Length of output: 251


🏁 Script executed:

#!/bin/bash
# Check how compressible_slot is used in sync_accounts
rg -n -A5 -B5 "compressible_slot" forester/src/compressible/state.rs

Length of output: 3146


🏁 Script executed:

#!/bin/bash
# Look for CLAUDE.md files for context on rent calculations
find . -name "CLAUDE.md" -type f | head -20

Length of output: 503



---

🏁 Script executed:

```shell
#!/bin/bash
# Get the implementation of get_last_funded_epoch from account_rent.rs
sed -n '180,220p' program-libs/compressible/src/rent/account_rent.rs

Length of output: 1183


🏁 Script executed:

#!/bin/bash
# Check the compression_info implementation too (might be different)
sed -n '140,180p' program-libs/compressible/src/compression_info.rs

Length of output: 1311


🏁 Script executed:

#!/bin/bash
# Read the RENT.md documentation
cat program-libs/compressible/docs/RENT.md

Length of output: 7148


🏁 Script executed:

#!/bin/bash
# Check CLAUDE.md for rent calculation context
cat program-libs/compressible/CLAUDE.md

Length of output: 2141


Fix off-by-one error in epoch-to-slot conversion for compressibility check.

Your review correctly identifies an off-by-one error. Here's what I found:

The get_last_funded_epoch function returns the last epoch that is funded (when epochs exist). If last_funded_epoch = 5, then epochs 0–5 have paid rent.

According to the rent system documentation, accounts become compressible when they lack rent for the current epoch + 1. For our example, that's epoch 6, which spans slots [6 * SLOTS_PER_EPOCH, 7 * SLOTS_PER_EPOCH). The account should become compressible at the start of epoch 6 (slot 6 * 432000).

Current implementation error:

  • compressible_slot = 5 * 432000
  • Check: state.compressible_slot < current_slot
  • At slot 5 * 432000 + 1 (still within epoch 5), the condition becomes true
  • Result: Account marked compressible during its last funded epoch ✗

Your suggested fix improves this but has a one-slot gap:

  • compressible_slot = (last_funded_epoch + 1) * SLOTS_PER_EPOCH = 6 * 432000
  • Account marked compressible at slot 6 * 432000 + 1 instead of 6 * 432000

The correct fix:

-    // Convert to slot
-    Ok(last_funded_epoch * SLOTS_PER_EPOCH)
+    // Account becomes compressible at the start of the epoch following the last funded epoch
+    // "Last funded slot" is the final slot of the last paid epoch: (last_funded_epoch + 1) * SLOTS_PER_EPOCH - 1
+    Ok((last_funded_epoch + 1) * SLOTS_PER_EPOCH - 1)

This ensures the account transitions to compressibility at the exact slot when rent coverage ends, aligning with the rent system semantics.

🤖 Prompt for AI Agents
In forester/src/compressible/state.rs around lines 15 to 49, the epoch-to-slot
conversion causes an off-by-one so accounts become compressible one slot late;
change the returned compressible slot to (last_funded_epoch + 1) *
SLOTS_PER_EPOCH - 1 so the condition state.compressible_slot < current_slot
becomes true at the exact first slot of the first unfunded epoch (i.e., compute
last_funded_epoch_plus_one = last_funded_epoch + 1 and return
last_funded_epoch_plus_one * SLOTS_PER_EPOCH - 1).

Comment on lines +525 to +546
// Verify both compressible accounts were closed
println!("Verifying compressible accounts are closed...");

let account_bootstrap = rpc
.get_account(compressible_account_bootstrap)
.await
.unwrap();
assert!(
account_bootstrap.is_none() || account_bootstrap.unwrap().lamports == 0,
"Compressible account (bootstrap) should be closed"
);
println!("Compressible account (bootstrap) successfully closed");

let account_subscriber = rpc
.get_account(compressible_account_subscriber)
.await
.unwrap();
assert!(
account_subscriber.is_none() || account_subscriber.unwrap().lamports == 0,
"Compressible account (subscriber) should be closed"
);
println!("Compressible account (subscriber) successfully closed");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Account closure verification may be overly permissive.

The verification checks account.is_none() || account.unwrap().lamports == 0. While this handles timing edge cases where an account with 0 lamports hasn't been garbage-collected yet, it means the test passes even if the account still exists on-chain with 0 lamports.

If the intent is to verify full account closure (deletion), consider tightening the assertion to check only account.is_none() after a brief wait period. However, the current implementation is acceptable if you want to be tolerant of GC timing.

Apply this diff if you want stricter verification:

-    assert!(
-        account_bootstrap.is_none() || account_bootstrap.unwrap().lamports == 0,
-        "Compressible account (bootstrap) should be closed"
-    );
+    assert!(
+        account_bootstrap.is_none(),
+        "Compressible account (bootstrap) should be closed (deleted from chain)"
+    );

And similarly for account_subscriber.

📝 Committable suggestion

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

Suggested change
// Verify both compressible accounts were closed
println!("Verifying compressible accounts are closed...");
let account_bootstrap = rpc
.get_account(compressible_account_bootstrap)
.await
.unwrap();
assert!(
account_bootstrap.is_none() || account_bootstrap.unwrap().lamports == 0,
"Compressible account (bootstrap) should be closed"
);
println!("Compressible account (bootstrap) successfully closed");
let account_subscriber = rpc
.get_account(compressible_account_subscriber)
.await
.unwrap();
assert!(
account_subscriber.is_none() || account_subscriber.unwrap().lamports == 0,
"Compressible account (subscriber) should be closed"
);
println!("Compressible account (subscriber) successfully closed");
// Verify both compressible accounts were closed
println!("Verifying compressible accounts are closed...");
let account_bootstrap = rpc
.get_account(compressible_account_bootstrap)
.await
.unwrap();
assert!(
account_bootstrap.is_none(),
"Compressible account (bootstrap) should be closed (deleted from chain)"
);
println!("Compressible account (bootstrap) successfully closed");
let account_subscriber = rpc
.get_account(compressible_account_subscriber)
.await
.unwrap();
assert!(
account_subscriber.is_none(),
"Compressible account (subscriber) should be closed (deleted from chain)"
);
println!("Compressible account (subscriber) successfully closed");
🤖 Prompt for AI Agents
In forester/tests/e2e_test.rs around lines 525 to 546, the test currently allows
either account to be None or exist with 0 lamports which is permissive; change
the verification to assert the account is fully deleted by polling with a short
retry loop (e.g., sleep+retry up to a timeout) for each compressible account and
then assert account.is_none(); apply the same tighter check for both
compressible_account_bootstrap and compressible_account_subscriber so the test
only passes when the account is actually removed from-chain.

Comment on lines +659 to +661
TreeType::Unknown => {
panic!("TreeType::Unknown is not supported for get_initial_merkle_tree_state - compression trees have no merkle tree state to fetch")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Defensive panic for Unknown tree type is acceptable but could be type-safe.

The panic provides a clear message explaining why TreeType::Unknown (compression trees) cannot be used with this function. Since the function signature returns a tuple rather than Result, panic is the only error mechanism available.

However, this could be prevented at compile time by using a more restrictive type (e.g., an enum that excludes Unknown, or a type parameter constraint).

Consider a type-safe approach if this pattern is used widely:

enum MerkleTreeType {
    StateV1,
    StateV2,
    AddressV1,
    AddressV2,
}

impl From<MerkleTreeType> for TreeType {
    fn from(t: MerkleTreeType) -> TreeType {
        match t {
            MerkleTreeType::StateV1 => TreeType::StateV1,
            MerkleTreeType::StateV2 => TreeType::StateV2,
            MerkleTreeType::AddressV1 => TreeType::AddressV1,
            MerkleTreeType::AddressV2 => TreeType::AddressV2,
        }
    }
}

Then change the signature to accept MerkleTreeType instead of TreeType, making it impossible to pass Unknown.

🤖 Prompt for AI Agents
In forester/tests/e2e_test.rs around lines 659-661, the code panics for
TreeType::Unknown; replace this runtime panic with a compile-time guarantee by
introducing a new enum (e.g., MerkleTreeType) that contains only valid merkle
tree variants (StateV1, StateV2, AddressV1, AddressV2), implement
From<MerkleTreeType> for TreeType to map those variants, then change the
function signature to accept MerkleTreeType instead of TreeType and update all
call sites to pass a MerkleTreeType (or convert where appropriate); this removes
the need for the panic because Unknown can no longer be represented at the
parameter type level.

@sergeytimoshin sergeytimoshin merged commit 4c7b4c9 into main Nov 14, 2025
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants