Skip to content

Comments

chore: light client add more tests#2307

Open
ananas-block wants to merge 1 commit intomainfrom
jorrit/test-light-client-interface
Open

chore: light client add more tests#2307
ananas-block wants to merge 1 commit intomainfrom
jorrit/test-light-client-interface

Conversation

@ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Feb 20, 2026

Summary by CodeRabbit

  • Tests
    • Improved token state validation testing with comprehensive field assertions.
    • Expanded batch account lookup test coverage with additional verification scenarios.
    • Added unit tests for indexer configuration defaults and retry behavior.
    • Added tests for proof packing functionality with various context combinations.
    • Added comprehensive test coverage for transaction size splitting and batch management.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

This PR adds comprehensive unit test coverage across five modules including token state validation, indexer batch operations, configuration defaults, proof packing logic, and transaction size handling. No functional runtime code changes are introduced; all modifications are test-only additions with improved assertion coverage.

Changes

Cohort / File(s) Summary
Token and Indexer Tests
forester/tests/test_compressible_ctoken.rs, forester/tests/test_indexer_interface.rs
Enhanced token state assertions to validate full Token struct fields instead of individual properties; expanded batch lookup test from 2 to 4 accounts with detailed ATA validation and lamport verification.
Configuration Tests
sdk-libs/client/src/indexer/config.rs
Added unit tests validating RetryConfig defaults (num_retries: 10, delay_ms: 400, max_delay_ms: 8000) and IndexerRpcConfig initialization with slot assignment.
Proof Packing Tests
sdk-libs/client/src/interface/pack.rs
Added extensive test suite covering minimal proof packing, CPI context handling, state tree indexing, and cross-verification between pack_proof and pack_proof_for_mints functions with TreeInfo integration checks.
Transaction Size Tests
sdk-libs/client/src/interface/tx_size.rs
Added comprehensive tests for split_by_tx_size covering empty input, single/multiple instruction batching, overflow errors with payload verification, and end-to-end buffer sizing validation against PACKET_DATA_SIZE.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #2251: Modifies compressible token tests and creates on-chain decompressed mints with adjusted token-account assertions.

Suggested labels

ai-review

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

🧪 A tapestry of tests now weaves so tight,
Four accounts batch, and token fields in sight,
Proofs pack cleanly, transactions align,
With configs confirmed—the coverage design! ✨

🚥 Pre-merge checks | ✅ 3
✅ 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 'chore: light client add more tests' accurately summarizes the main change—adding unit tests across multiple modules without functional logic changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jorrit/test-light-client-interface

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

❤️ Share

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

@ananas-block
Copy link
Contributor Author

@CodeRabbit review this pr pls

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

@ananas-block: I'll review the PR for you now. Let me analyze the changes and provide feedback.


🧠 Learnings used
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/anchor/README.md:0-0
Timestamp: 2026-01-10T19:25:03.366Z
Learning: Applies to basic-operations/anchor/**/*.test.ts : TypeScript tests must demonstrate client-side interaction with compressed accounts using 'lightprotocol/stateless.js'

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: counter/anchor/README.md:0-0
Timestamp: 2026-01-10T19:25:21.661Z
Learning: Applies to counter/anchor/**/*.test.ts : Demonstrate client-side interaction with compressed accounts using `lightprotocol/stateless.js` and `lightprotocol/zk-compression-cli` libraries in TypeScript tests

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-light-token-test/README.md:0-0
Timestamp: 2026-01-22T17:20:14.942Z
Learning: Applies to sdk-tests/sdk-light-token-test/**/tests/**/*.rs : Add comprehensive integration tests using `light-program-test` framework for testing CPI operations

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/program-test/README.md:0-0
Timestamp: 2026-01-29T22:54:48.916Z
Learning: Use `light-program-test` for fast test execution with unit/integration tests for Solana programs or client code

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/CLAUDE.md:0-0
Timestamp: 2026-01-22T18:38:05.279Z
Learning: Supporting library unit tests should run with `cargo test` for light-program-test, light-client, light-sparse-merkle-tree, light-token-types, and light-token packages

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: account-comparison/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:01.412Z
Learning: Applies to account-comparison/programs/**/tests/test_compressed_account.rs : Include Light Protocol tests in test_compressed_account.rs to verify compressed account operations using LightAccount primitives

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/client/README.md:0-0
Timestamp: 2026-02-07T17:54:56.345Z
Learning: Applies to sdk-libs/client/**/*.rs : Use the `light_client` crate modules (`rpc::LightClient`, `indexer::Indexer`, `local_test_validator::spawn_validator`) for interacting with Light Protocol

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk/nullifier/README.md:0-0
Timestamp: 2026-01-15T02:04:23.014Z
Learning: Use Light CLI for testing and validation - install via 'npm install -g lightprotocol/zk-compression-cli'

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: zk/zk-id/README.md:0-0
Timestamp: 2026-01-15T02:04:37.101Z
Learning: TypeScript tests require a running local validator with Light Protocol

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/native/README.md:0-0
Timestamp: 2026-01-10T19:25:12.548Z
Learning: Require light cli version 0.24.0+, solana cli version 2.1.16+, and Node.js with npm for testing
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
forester/tests/test_indexer_interface.rs (1)

518-599: ⚠️ Potential issue | 🟡 Minor

Batch test no longer covers the "not-found" path

The previous version of Test 3 apparently included accounts that would return None (e.g., compressed_mint_pda which is fully compressed and has no on-chain representation). The updated test uses only hot accounts, so the code path where getMultipleAccountInterfaces returns a None entry for a missing/cold account is no longer exercised anywhere in this test.

Consider keeping at least one entry that is expected to be None (e.g., &compressed_mint_pda) to ensure the batch endpoint handles mixed hot/missing results correctly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@forester/tests/test_indexer_interface.rs` around lines 518 - 599, The batch
test no longer checks the "not-found" path; modify the batch_addresses passed to
photon_indexer.get_multiple_account_interfaces to include &compressed_mint_pda
(e.g., [ &decompressed_mint_pda, &compressible_token_account,
&compressed_mint_pda, &bob_ata, &charlie_ata ] or swap into the existing 4-item
vector), then update the assertions on batch_response.value to expect a None
(i.e., .as_ref() should be None) for the compressed_mint_pda slot and shift the
subsequent assertions for bob_ata/charlie_ata to their new indices so the test
verifies a mixed hot/missing result set.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@forester/tests/test_compressible_ctoken.rs`:
- Around line 328-346: The current assert_eq! uses extensions:
account_state.account.extensions.clone(), which tautologically makes the
extensions field always match; update the test to make a real assertion: either
remove the extensions field from the expected Token literal and keep the
existing assert!(account_state.account.extensions.is_some()) check, or replace
that field with the concrete expected extensions value (e.g., the known
CompressibleToken extension data) and assert equality against it; locate the
Token struct construction in test_compressible_ctoken.rs (the assert_eq!
comparing account_state.account) and modify the extensions handling accordingly.

In `@forester/tests/test_indexer_interface.rs`:
- Around line 520-527: The comment above the batch_addresses vector is stale and
mentions "compressed mint PDA (not found)" and "compressed mint seed pubkey"
which no longer match the actual items; update the comment to accurately
describe the current contents: decompressed_mint_pda,
compressible_token_account, bob_ata, and charlie_ata (both on-chain hot
accounts). Locate the comment near batch_addresses and replace the old
descriptions with a brief, correct list referencing decompressed_mint_pda,
compressible_token_account, bob_ata, and charlie_ata.

In `@sdk-libs/client/src/interface/tx_size.rs`:
- Around line 196-199: The comment next to max_size in tx_size.rs miscounts
instruction accounts: each instruction adds a third key created via
AccountMeta::new(...), so replace the misleading "accounts(compact+32*2)" part
with "accounts(compact+32*3)" and update the byte math to reflect header(3) +
accounts(compact+32*3) + blockhash(32) + ixs + sigs ≈ 212 bytes for
one-instruction tx (hence max_size = 250 still allows one but not two); update
the inline numbers to show ~212 for one and ~290 for two so the comment matches
the actual test logic using max_size.

---

Outside diff comments:
In `@forester/tests/test_indexer_interface.rs`:
- Around line 518-599: The batch test no longer checks the "not-found" path;
modify the batch_addresses passed to
photon_indexer.get_multiple_account_interfaces to include &compressed_mint_pda
(e.g., [ &decompressed_mint_pda, &compressible_token_account,
&compressed_mint_pda, &bob_ata, &charlie_ata ] or swap into the existing 4-item
vector), then update the assertions on batch_response.value to expect a None
(i.e., .as_ref() should be None) for the compressed_mint_pda slot and shift the
subsequent assertions for bob_ata/charlie_ata to their new indices so the test
verifies a mixed hot/missing result set.

Comment on lines 328 to 346
assert_eq!(
account_state.account.owner,
owner_keypair.pubkey().to_bytes()
account_state.account,
Token {
mint: mint.to_bytes().into(),
owner: owner_keypair.pubkey().to_bytes().into(),
amount: 0,
delegate: None,
state: AccountState::Initialized,
is_native: None,
delegated_amount: 0,
close_authority: None,
account_type: ACCOUNT_TYPE_TOKEN_ACCOUNT,
extensions: account_state.account.extensions.clone(),
}
);
assert!(
account_state.account.extensions.is_some(),
"compressible token account should have extensions"
);
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

Tautological extensions comparison in assert_eq!

Line 340 sets extensions: account_state.account.extensions.clone(), so that field trivially matches and contributes nothing to the equality assertion. The test looks as though it's verifying the extensions value, but it's only verifying all the other fields.

The separate is_some() guard on lines 343–346 is the sole real assertion for extensions. To make the intent clear:

🔧 Suggested refactor
 assert_eq!(
     account_state.account,
     Token {
         mint: mint.to_bytes().into(),
         owner: owner_keypair.pubkey().to_bytes().into(),
         amount: 0,
         delegate: None,
         state: AccountState::Initialized,
         is_native: None,
         delegated_amount: 0,
         close_authority: None,
         account_type: ACCOUNT_TYPE_TOKEN_ACCOUNT,
-        extensions: account_state.account.extensions.clone(),
+        // extensions is not asserted here; verified separately below
+        ..account_state.account.clone()
     }
 );

Or, if Token supports a field-by-field comparison without struct-literal syntax, exclude extensions entirely and keep the dedicated is_some() check:

+assert!(account_state.account.extensions.is_some(), "compressible token account should have extensions");
 assert_eq!(account_state.account.amount, 0);
 assert_eq!(account_state.account.state, AccountState::Initialized);
 // … individual field assertions …
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@forester/tests/test_compressible_ctoken.rs` around lines 328 - 346, The
current assert_eq! uses extensions: account_state.account.extensions.clone(),
which tautologically makes the extensions field always match; update the test to
make a real assertion: either remove the extensions field from the expected
Token literal and keep the existing
assert!(account_state.account.extensions.is_some()) check, or replace that field
with the concrete expected extensions value (e.g., the known CompressibleToken
extension data) and assert equality against it; locate the Token struct
construction in test_compressible_ctoken.rs (the assert_eq! comparing
account_state.account) and modify the extensions handling accordingly.

Comment on lines +520 to +527
// Include: decompressed mint PDA, compressible token account, compressed mint PDA (not found),
// and the compressed mint seed pubkey (not a known on-chain account).
let batch_addresses = vec![
&decompressed_mint_pda,
&compressible_token_account,
&bob_ata,
&charlie_ata,
];
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

Stale comment describes the wrong accounts

The comment at lines 520–521 still refers to the previous batch contents (compressed mint PDA (not found) and compressed mint seed pubkey), but the actual batch_addresses now uses bob_ata and charlie_ata — both fully on-chain hot accounts.

✏️ Suggested fix
-    // Include: decompressed mint PDA, compressible token account, compressed mint PDA (not found),
-    // and the compressed mint seed pubkey (not a known on-chain account).
+    // Include: decompressed mint PDA (on-chain CMint), compressible token account (on-chain),
+    // Bob's ATA (on-chain), and Charlie's ATA (on-chain).
     let batch_addresses = vec![
📝 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
// Include: decompressed mint PDA, compressible token account, compressed mint PDA (not found),
// and the compressed mint seed pubkey (not a known on-chain account).
let batch_addresses = vec![
&decompressed_mint_pda,
&compressible_token_account,
&bob_ata,
&charlie_ata,
];
// Include: decompressed mint PDA (on-chain CMint), compressible token account (on-chain),
// Bob's ATA (on-chain), and Charlie's ATA (on-chain).
let batch_addresses = vec![
&decompressed_mint_pda,
&compressible_token_account,
&bob_ata,
&charlie_ata,
];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@forester/tests/test_indexer_interface.rs` around lines 520 - 527, The comment
above the batch_addresses vector is stale and mentions "compressed mint PDA (not
found)" and "compressed mint seed pubkey" which no longer match the actual
items; update the comment to accurately describe the current contents:
decompressed_mint_pda, compressible_token_account, bob_ata, and charlie_ata
(both on-chain hot accounts). Locate the comment near batch_addresses and
replace the old descriptions with a brief, correct list referencing
decompressed_mint_pda, compressible_token_account, bob_ata, and charlie_ata.

Comment on lines +196 to +199
// Each instruction has 1 account + 10 bytes data. Estimate:
// header(3) + accounts(compact+32*2) + blockhash(32) + ixs + sigs ~ 200 bytes
// Set max_size=250 to allow one instruction per tx but not two.
let max_size = 250usize;
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

Inaccurate account-count estimate in comment

The inline comment says accounts(compact+32*2), implying 2 keys (payer + program_id). Each instruction also contributes a third key via AccountMeta::new(Pubkey::new_unique(), false), so the real account list is [payer, program_id, account] = 3 × 32 = 96 bytes, giving ~212 bytes per single-instruction tx — not ~200. The test logic and assertions are still correct since 212 < 250 (one fits) and ~290 bytes for two (split forced), but the comment formula misleads future readers.

✏️ Suggested comment fix
-        // Each instruction has 1 account + 10 bytes data. Estimate:
-        //   header(3) + accounts(compact+32*2) + blockhash(32) + ixs + sigs ~ 200 bytes
-        // Set max_size=250 to allow one instruction per tx but not two.
+        // Each instruction has 1 account (non-signer) + 10 bytes data. Estimate per single tx:
+        //   header(3) + accounts(compact+3×32=97) + blockhash(32) + ix(~14) + sigs(65) ≈ 211 bytes
+        //   Two instructions share no accounts → ≈ 290 bytes.
+        // max_size=250 allows one instruction per batch but not two → 3 batches for 3 instructions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk-libs/client/src/interface/tx_size.rs` around lines 196 - 199, The comment
next to max_size in tx_size.rs miscounts instruction accounts: each instruction
adds a third key created via AccountMeta::new(...), so replace the misleading
"accounts(compact+32*2)" part with "accounts(compact+32*3)" and update the byte
math to reflect header(3) + accounts(compact+32*3) + blockhash(32) + ixs + sigs
≈ 212 bytes for one-instruction tx (hence max_size = 250 still allows one but
not two); update the inline numbers to show ~212 for one and ~290 for two so the
comment matches the actual test logic using max_size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant