Skip to content

fix: sdks#1998

Merged
ananas-block merged 3 commits intomainfrom
jorrit/fix-sdks-v0.15.0
Oct 20, 2025
Merged

fix: sdks#1998
ananas-block merged 3 commits intomainfrom
jorrit/fix-sdks-v0.15.0

Conversation

@ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Oct 20, 2025

Summary by CodeRabbit

  • New Features

    • Added Merkle tree support with root reading capabilities and new validation constants.
    • Expanded public API exports for proof handling.
    • Added optional feature for merkle-tree functionality.
  • Bug Fixes

    • Corrected file path formatting for program loading.
  • Chores

    • Removed duplicate build configuration entries.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Changes add merkle-tree feature support to the SDK with new constants, public exports, and module additions. Also includes minor fixes to test configurations, path formatting in setup utilities, and removal of duplicate build script exclusion flags.

Changes

Cohort / File(s) Summary
Build and Feature Configuration
scripts/format.sh, sdk-libs/sdk/Cargo.toml
Removed duplicate cargo clippy exclusion flag; added new merkle-tree feature gating light-concurrent-merkle-tree/solana dependency
Public API Exports
sdk-libs/sdk/src/instruction/mod.rs
Expanded compressed_proof re-export to include both CompressedProof and ValidityProof
Module and Constants
sdk-libs/sdk/src/lib.rs, sdk-libs/sdk-types/src/constants.rs
Added feature-gated merkle_tree module to crate root; introduced new ADDRESS_TREE_V2 public constant
Merkle Tree Implementation
sdk-libs/sdk/src/merkle_tree.rs
New module v1 with read_state_merkle_tree_root() function and state tree discriminator/metadata length constants for concurrent Merkle tree root retrieval
Test and Setup Utilities
sdk-libs/program-test/src/indexer/test_indexer.rs, sdk-libs/program-test/src/utils/setup_light_programs.rs
Updated proof retrieval flag in test indexer; corrected file path formatting for NOOP program loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Mixed complexity across configuration changes, API exports, new module logic with validation, and test updates. Most changes are straightforward additions and fixes, though the merkle tree module introduces validation logic requiring verification.

Possibly related PRs

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

🐰 Merkle trees now bloom in features bright,
With roots and proofs aligned just right,
Constants dance and exports play,
While little fixes clear the way!
A forest grows in our SDK's might ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The pull request title "fix: sdks" is extremely vague and generic, failing to convey meaningful information about the changeset. While the changes do relate to SDKs (including path fixes, feature additions, merkle tree functionality, and public API exports), the title uses a non-descriptive term that doesn't indicate what aspect of the SDKs was addressed or fixed. A developer scanning the git history would not understand what this PR accomplishes based on the title alone, similar to examples like "misc updates" that are too generic to be useful. Consider revising the title to be more specific about the primary change. For example, if merkle tree functionality is the main focus, a title like "feat: add merkle tree module and CompressedProof export" would be clearer. Alternatively, if this is primarily a collection of fixes, specify the key fixes involved (e.g., "fix: path formatting and add merkle tree support to SDKs"). The goal is to ensure the title clearly communicates the main purpose of the changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a97e9f1 and 500a093.

📒 Files selected for processing (1)
  • sdk-libs/sdk/src/merkle_tree.rs (1 hunks)

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 ananas-block force-pushed the jorrit/fix-sdks-v0.15.0 branch from 14fd6c1 to 79880dd Compare October 20, 2025 17:22
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

🧹 Nitpick comments (1)
sdk-libs/sdk/src/merkle_tree.rs (1)

22-29: Consider extracting the magic number 2400 to a named constant.

The hardcoded value 2400 appears multiple times and represents the maximum root history length. Consider defining it as a constant like STATE_MERKLE_TREE_MAX_ROOTS: usize = 2400 for better maintainability.

Apply this diff to extract the constant:

     pub const STATE_MERKLE_TREE_DISCRIMINATOR: [u8; 8] = [172, 43, 172, 186, 29, 73, 219, 84];
     pub const STATE_MERKLE_TREE_ACCOUNT_METADATA_LEN: usize = 224;
+    pub const STATE_MERKLE_TREE_MAX_ROOTS: usize = 2400;

     /// Reads a root from the concurrent state merkle tree by index
     pub fn read_state_merkle_tree_root(
         account_info: &AccountInfo,
         root_index: u16,
     ) -> Result<[u8; 32], ProgramError> {
-        if root_index as usize >= 2400 {
+        if root_index as usize >= STATE_MERKLE_TREE_MAX_ROOTS {
             msg!(
                 "Invalid root index: {} greater than max root index {}",
                 root_index,
-                2400
+                STATE_MERKLE_TREE_MAX_ROOTS
             );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4de2eca and a97e9f1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • scripts/format.sh (0 hunks)
  • sdk-libs/program-test/src/indexer/test_indexer.rs (1 hunks)
  • sdk-libs/program-test/src/utils/setup_light_programs.rs (1 hunks)
  • sdk-libs/sdk-types/src/constants.rs (1 hunks)
  • sdk-libs/sdk/Cargo.toml (2 hunks)
  • sdk-libs/sdk/src/instruction/mod.rs (1 hunks)
  • sdk-libs/sdk/src/lib.rs (1 hunks)
  • sdk-libs/sdk/src/merkle_tree.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • scripts/format.sh
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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:

  • sdk-libs/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-11T21:59:25.222Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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:

  • sdk-libs/sdk/src/merkle_tree.rs
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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:

  • sdk-libs/sdk/src/instruction/mod.rs
📚 Learning: 2025-10-16T06:33:19.426Z
Learnt from: CR
PR: Lightprotocol/light-protocol#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:

  • sdk-libs/sdk/src/lib.rs
🧬 Code graph analysis (2)
sdk-libs/sdk/src/merkle_tree.rs (1)
program-libs/account-checks/src/checks.rs (1)
  • check_owner (135-143)
sdk-libs/sdk/src/instruction/mod.rs (1)
js/stateless.js/src/state/types.ts (2)
  • CompressedProof (373-386)
  • ValidityProof (397-410)
⏰ 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). (9)
  • GitHub Check: lint
  • GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
  • GitHub Check: system-programs (anchor & pinocchio, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -p sdk...
  • GitHub Check: system-programs (token test, ["cargo-test-sbf -p sdk-token-test"])
  • GitHub Check: system-programs (native, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v1-native-t...
  • GitHub Check: stateless-js-v1
  • GitHub Check: cli-v2
  • GitHub Check: cli-v1
  • GitHub Check: stateless-js-v2
🔇 Additional comments (7)
sdk-libs/program-test/src/utils/setup_light_programs.rs (1)

72-72: Critical bug fix: Directory separator added.

This correctly adds the missing / separator in the path construction, making it consistent with all other program paths in this function (lines 54, 60, 66, 79). Without this fix, the path would be malformed (e.g., /path/to/binspl_noop.so), causing the NOOP program to fail loading at line 74.

sdk-libs/sdk-types/src/constants.rs (1)

42-42: LGTM!

The new ADDRESS_TREE_V2 constant follows the established naming and formatting conventions.

sdk-libs/sdk/src/instruction/mod.rs (1)

52-54: LGTM!

The grouped re-export of both CompressedProof and ValidityProof improves the public API surface and maintains consistency with the module's purpose.

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

148-148: Verify that tests pass with the updated proof retrieval flag.

The change from false to true in get_proof_of_leaf modifies the proof generation behavior. Please confirm that all related tests pass and the change aligns with the intended proof format for this use case.

sdk-libs/sdk/src/lib.rs (1)

155-156: LGTM!

The feature-gated merkle_tree module is correctly declared and appropriately placed within the module hierarchy.

sdk-libs/sdk/Cargo.toml (2)

25-25: LGTM!

The merkle-tree feature is correctly defined and enables the appropriate dependency sub-feature.


49-49: LGTM!

The optional dependency declaration follows the established pattern and correctly uses workspace versioning.

Comment on lines +50 to +53
let data = &account_data[required_size..];
let merkle_tree = ConcurrentMerkleTreeZeroCopy::<Poseidon, 26>::from_bytes_zero_copy(data)?;

Ok(merkle_tree.roots[root_index as usize])
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify bounds safety when accessing merkle_tree.roots.

The function validates root_index < 2400, then accesses merkle_tree.roots[root_index as usize]. Please confirm that ConcurrentMerkleTreeZeroCopy<Poseidon, 26> guarantees a roots array of at least 2400 elements to prevent potential out-of-bounds access.


🏁 Script executed:

#!/bin/bash
# Verify the ConcurrentMerkleTreeZeroCopy type definition and roots array size
rg -A 10 "struct ConcurrentMerkleTreeZeroCopy" --type rust
rg "roots.*\[" --type rust -A 3 | rg "2400|ROOTS"

Length of output: 1813


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Search for ConcurrentMerkleTree struct definition (the inner type)
rg -A 20 "struct ConcurrentMerkleTree[^Z]" --type rust

Length of output: 3300



🏁 Script executed:

#!/bin/bash
# Search for CyclicBoundedVec definition and its size/capacity
rg -A 15 "struct CyclicBoundedVec" --type rust

Length of output: 0



🏁 Script executed:

#!/bin/bash
# Search for CyclicBoundedVec definition or type alias
rg "type CyclicBoundedVec|CyclicBoundedVec.*=" --type rust -B 2 -A 5
# Also check the concurrent-merkle-tree lib.rs for imports
rg "use.*CyclicBoundedVec|mod.*" program-libs/concurrent-merkle-tree/src/lib.rs -A 2

Length of output: 7239



🏁 Script executed:

#!/bin/bash
# Search for CyclicBoundedVec implementation in offset module
rg "pub.*CyclicBoundedVec|impl.*CyclicBoundedVec" --type rust -A 5
# Also search for how roots capacity is set
rg "roots.*capacity|capacity.*2400|ROOTS_LEN" --type rust

Length of output: 4860



🏁 Script executed:

#!/bin/bash
# Find ROOTS constant
rg "const ROOTS|ROOTS\s*=" --type rust -B 2 -A 1
# Look at from_bytes_zero_copy implementation
rg -A 30 "pub fn from_bytes_zero_copy\(" program-libs/concurrent-merkle-tree/src/zero_copy.rs | head -50
# Check the actual merkle_tree.rs file around lines 50-53
cat sdk-libs/sdk/src/merkle_tree.rs | head -70 | tail -30

Length of output: 19114



🏁 Script executed:

#!/bin/bash
# Find check_size_constraints implementation
rg -A 20 "fn check_size_constraints" --type rust
# Also search for any validation of roots capacity
rg "roots.*capacity|roots_capacity.*=" --type rust -B 2 -A 2 | grep -A 5 "check_size_constraints\|validate\|assert"

Length of output: 7256


Bounds safety issue confirmed: roots array capacity is not validated.

The concern is valid. The code validates root_index < 2400 but does not guarantee that merkle_tree.roots has capacity >= 2400. The check_size_constraints() only validates that roots_size > 0, leaving a potential out-of-bounds access.

Recommended fix: Add validation in check_size_constraints_new() to ensure roots_size >= 2400 for this use case, or verify at the call site that the deserialized roots capacity meets the requirement before accessing the array.

🤖 Prompt for AI Agents
In sdk-libs/sdk/src/merkle_tree.rs around lines 50 to 53, the code uses
merkle_tree.roots[root_index as usize] after only validating root_index < 2400
but not ensuring merkle_tree.roots has at least that many entries; update the
validation to prevent out-of-bounds access by either (a) adding a size check in
check_size_constraints_new() to require roots_size >= 2400 (and return a clear
error if not), or (b) adding a runtime guard at this call site that verifies
merkle_tree.roots.len() > root_index as usize before indexing and returns an
error if the deserialized roots capacity is insufficient.

@ananas-block ananas-block merged commit adf0406 into main Oct 20, 2025
21 of 22 checks passed
@ananas-block ananas-block deleted the jorrit/fix-sdks-v0.15.0 branch October 20, 2025 22:34
@coderabbitai coderabbitai bot mentioned this pull request Nov 10, 2025
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.

2 participants