Skip to content

feat: light program 1 byte discriminator#2302

Merged
SwenSchaeferjohann merged 7 commits intomainfrom
jorrit/test-light-program-1-byte-discriminator
Feb 20, 2026
Merged

feat: light program 1 byte discriminator#2302
SwenSchaeferjohann merged 7 commits intomainfrom
jorrit/test-light-program-1-byte-discriminator

Conversation

@ananas-block
Copy link
Contributor

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

Description

  1. Custom Discriminator Support in Pinocchio Macros
  • Added parse_pinocchio_discriminator() function to parse #[light_pinocchio(discriminator = [...])] attribute
  • Supports variable-length discriminators (1-8 bytes) with validation and padding to 8-byte format
  • Added light_pinocchio attribute to #[proc_macro_derive(LightPinocchioAccount)]
  1. OneByteRecord Account Type
  • New PDA type with 1-byte on-chain discriminator ([1u8])
  • Added to ProgramAccounts enum as first-class variant
  • Includes dedicated accounts, processor, and state modules
  1. Compression/Decompression Updates
  • Updated compress.rs to handle variable-length discriminators in PDA initialization
  • Updated SDK interface PDA compression/decompression methods for discriminator handling
  1. create_all Instruction Extended
  • Added OneByteRecord as third PDA in create_all instruction
  • Updated CreateAllAccounts struct and processor to accommodate 3 PDAs
  1. Stress Test Enhanced with Randomization
  • New HotSet struct for randomly selecting which accounts decompress each iteration (70% per account)
  • Added rand dependency to dev-dependencies
  • Accounts decompress in randomized order with Mint always first
  • Mint required when ATA or Vault is hot
  1. Test Coverage
  • New test_create_one_byte_record.rs integration test for OneByteRecord creation
  • Updated test_create_all.rs to verify OneByteRecord through all 4 phases (creation, compression, decompression, verification)

Summary by CodeRabbit

  • New Features

    • Support for custom discriminators via a new attribute for the LightPinocchio path
    • Variable-length discriminator handling and compile-time collision checks for the Pinocchio backend
  • Documentation

    • Added docs describing the custom-discriminator workflow and attribute usage
  • Tests

    • Added tests for valid/invalid discriminator lengths and misuse on incompatible types
  • Bug Fixes

    • Serialization layout and size validations updated to use dynamic discriminator length

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

Adds support for variable-length, custom discriminators for LightPinocchio accounts via a new light_pinocchio attribute, parses/validates 1–8 byte discriminators, emits dynamic LIGHT_DISCRIMINATOR_SLICE, and switches compression/decompression and dispatch logic to use prefix-aware, dynamic discriminator handling with collision checks.

Changes

Cohort / File(s) Summary
Macro Derive Attribute
sdk-libs/macros/src/lib.rs
Expose new attribute light_pinocchio on LightPinocchioAccount derive macro declaration.
Discriminator Parsing & Tests
sdk-libs/macros/src/light_pdas/account/derive.rs
Add parse_pinocchio_discriminator(attrs) to parse/validate 1–8 byte #[light_pinocchio(discriminator = [...])]; integrate into derive flow to emit LightDiscriminator impl and LIGHT_DISCRIMINATOR_SLICE; emit compile-time errors for misuse; add unit tests covering valid/invalid cases.
Compression Dispatch & Collision Checks
sdk-libs/macros/src/light_pdas/program/compress.rs
Replace fixed 8-byte discriminator checks with prefix-based guards using LIGHT_DISCRIMINATOR_SLICE; add generate_discriminator_collision_checks (public) to emit const-time collision assertions for Pinocchio; update COMPRESSED_SIZE and size validations to use dynamic prefix length.
Codegen Integration
sdk-libs/macros/src/light_pdas/program/instructions.rs
Invoke generate_discriminator_collision_checks during instruction codegen and include those checks alongside existing size validations.
Serialization / PDA Layout
sdk-libs/sdk-types/src/interface/program/compression/pda.rs, sdk-libs/sdk-types/src/interface/program/decompression/pda.rs
Change PDA serialization/deserialization to use LIGHT_DISCRIMINATOR_SLICE length (dynamic) for writing and offsets instead of a fixed 8-byte prefix.
Manifest
Cargo.toml
Minor manifest/metadata adjustments reflected (small lines changed).

Sequence Diagram(s)

sequenceDiagram
    participant DeriveMacro as Macro (derive)
    participant Codegen as Compress Generator
    participant Backend as CodegenBackend/Pinocchio
    participant Runtime as SDK Types (compression/decompression)

    DeriveMacro->>DeriveMacro: parse `#[light_pinocchio(discriminator=[...])]`
    DeriveMacro-->>Codegen: emit LightDiscriminator + LIGHT_DISCRIMINATOR_SLICE
    Codegen->>Backend: generate dispatch + generate_discriminator_collision_checks
    Backend-->>Codegen: backend-specific tokens (Pinocchio checks)
    Codegen-->>Runtime: emit compression/decompression code using LIGHT_DISCRIMINATOR_SLICE
    Runtime->>Runtime: serialize/deserialize using dynamic discriminator prefix length
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

ai-review

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

✨ Tiny slices line the way, eight no longer king,
Macros hum and checks assert—prefixes now sing.
Pinocchio badges, short and neat, collide no more,
Bytes find order at the gate and softly close the door.

🚥 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 accurately summarizes the main feature: support for 1-byte discriminators in light programs, which is the central change across macro definitions, PDA compression/decompression, and integration tests.
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-program-1-byte-discriminator

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/test-light-program-1-byte-discriminator branch from ddfd0de to e1fde1a Compare February 19, 2026 19:49
@ananas-block ananas-block changed the title test: light program 1 byte discriminator feat: light program 1 byte discriminator Feb 19, 2026
@ananas-block
Copy link
Contributor Author

@CodeRabbit pls review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

@ananas-block: I'll review the changes in this PR. Based on the PR title, this appears to be adding support for 1-byte discriminators for light programs, which aligns with the codebase's goal of supporting multiple discriminator sizes (1 byte for native programs, 4 bytes for system-style programs, and 8 bytes for Anchor programs).

I'll examine the implementation details, verify the correctness of the 1-byte discriminator logic, and ensure it integrates properly with the existing discriminator infrastructure.


🧠 Learnings used
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/instruction-decoder-derive/CLAUDE.md:0-0
Timestamp: 2026-01-22T17:20:27.830Z
Learning: Support multiple discriminator sizes: 1 byte for native programs with simple instruction indices, 4 bytes for system-style programs (little-endian u32), and 8 bytes for Anchor programs (SHA256 prefix, default)

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: create-and-update/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:38.625Z
Learning: Applies to create-and-update/**/programs/**/src/**/*.rs : Define compressed account state structs with 8-byte discriminators derived via `LightDiscriminator` hash of struct name

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: read-only/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:48.012Z
Learning: Applies to read-only/**/*.rs : Derive 8-byte discriminator via `LightDiscriminator` and store in separate discriminator field, not in data bytes

Learnt from: CR
Repo: Lightprotocol/distributor PR: 0
File: programs/merkle-distributor/CLAUDE.md:0-0
Timestamp: 2026-01-11T01:05:19.378Z
Learning: Applies to programs/merkle-distributor/**/state/*.rs : Use `LightDiscriminator` derive for compressed account state structs (e.g., ClaimStatus)

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/sdk/README.md:0-0
Timestamp: 2026-01-29T22:55:10.519Z
Learning: Applies to sdk-libs/sdk/**/*.rs : Use `LightDiscriminator` derive macro to derive a compressed account discriminator

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/instruction-decoder-derive/CLAUDE.md:0-0
Timestamp: 2026-01-22T17:20:27.830Z
Learning: Support two syntax forms for specifying explicit discriminators: integer form #[discriminator = 5] for 1-byte and 4-byte modes, and array form #[discriminator(26, 16, 169, 7, 21, 202, 242, 25)] for 8-byte mode with custom discriminators

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/src/**/*.rs : Use `LightDiscriminator` derive macro for compressed account type identification

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/account-pinocchio/README.md:0-0
Timestamp: 2026-02-04T00:56:26.117Z
Learning: Applies to sdk-libs/account-pinocchio/**/*.rs : Define `LightDiscriminator` and `LightHasherSha` derives on all state structs in Pinocchio Light Account programs

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

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: counter/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:31.226Z
Learning: Applies to counter/**/{anchor,native,pinocchio}/src/**/*.rs : Use LightDiscriminator derive macro to generate 8-byte discriminator from CounterAccount struct name hash
✅ 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.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

@ananas-block: I'll review the changes for the 1-byte discriminator support for light programs. The review will examine the implementation to ensure proper integration with the existing discriminator infrastructure that supports multiple sizes (1 byte for native programs, 4 bytes for system-style programs, and 8 bytes for Anchor programs).


🧠 Learnings used
Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: basic-operations/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:21.240Z
Learning: Applies to basic-operations/**/{anchor,native}/**/src/**/*.rs : Use `LightDiscriminator` derive macro for compressed account type identification

Learnt from: CR
Repo: Lightprotocol/distributor PR: 0
File: programs/merkle-distributor/CLAUDE.md:0-0
Timestamp: 2026-01-11T01:05:19.378Z
Learning: Applies to programs/merkle-distributor/**/state/*.rs : Use `LightDiscriminator` derive for compressed account state structs (e.g., ClaimStatus)

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

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: read-only/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:48.012Z
Learning: Applies to read-only/**/*.rs : Derive 8-byte discriminator via `LightDiscriminator` and store in separate discriminator field, not in data bytes

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: counter/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:31.226Z
Learning: Applies to counter/**/{anchor,native,pinocchio}/src/**/*.rs : Use LightDiscriminator derive macro to generate 8-byte discriminator from CounterAccount struct name hash

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/sdk/README.md:0-0
Timestamp: 2026-01-29T22:55:10.519Z
Learning: Applies to sdk-libs/sdk/**/*.rs : Use `LightDiscriminator` derive macro to derive a compressed account discriminator

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/sdk-pinocchio/README.md:0-0
Timestamp: 2026-01-29T22:54:54.354Z
Learning: Applies to sdk-libs/sdk-pinocchio/**/*.rs : Export `LightDiscriminator` trait with derive macro support (requires `light-account` feature)

Learnt from: CR
Repo: Lightprotocol/program-examples PR: 0
File: create-and-update/CLAUDE.md:0-0
Timestamp: 2026-01-10T19:26:38.625Z
Learning: Applies to create-and-update/**/programs/**/src/**/*.rs : Define compressed account state structs with 8-byte discriminators derived via `LightDiscriminator` hash of struct name

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/account-pinocchio/README.md:0-0
Timestamp: 2026-02-04T00:56:26.117Z
Learning: Applies to sdk-libs/account-pinocchio/**/*.rs : Define `LightDiscriminator` and `LightHasherSha` derives on all state structs in Pinocchio Light Account programs

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/CLAUDE.md:0-0
Timestamp: 2026-01-31T16:39:11.741Z
Learning: Applies to sdk-libs/macros/**/*.rs : Use `#[derive(LightDiscriminator)]` derive macro to automatically generate unique 8-byte discriminators for account types

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/instruction-decoder-derive/CLAUDE.md:0-0
Timestamp: 2026-01-22T17:20:27.830Z
Learning: Support multiple discriminator sizes: 1 byte for native programs with simple instruction indices, 4 bytes for system-style programs (little-endian u32), and 8 bytes for Anchor programs (SHA256 prefix, default)

Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/instruction-decoder-derive/CLAUDE.md:0-0
Timestamp: 2026-01-22T17:20:27.830Z
Learning: Support two syntax forms for specifying explicit discriminators: integer form #[discriminator = 5] for 1-byte and 4-byte modes, and array form #[discriminator(26, 16, 169, 7, 21, 202, 242, 25)] for 8-byte mode with custom discriminators
✅ 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: 4

Caution

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

⚠️ Outside diff range comments (2)
sdk-libs/sdk-types/src/interface/program/compression/pda.rs (1)

95-95: ⚠️ Potential issue | 🟡 Minor

Stale comment — discriminator is no longer always 8 bytes.

Line 95 says "includes 8-byte discriminator" but the code on lines 100-103 now writes a variable-length discriminator via LIGHT_DISCRIMINATOR_SLICE. The comment should reflect this.

📝 Suggested fix
-        // Serialize updated account data back (includes 8-byte discriminator)
+        // Serialize updated account data back (includes discriminator prefix)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk-libs/sdk-types/src/interface/program/compression/pda.rs` at line 95,
Update the stale comment that says "includes 8-byte discriminator" to reflect
the variable-length discriminator now used; mention that serialization includes
the discriminator provided by LIGHT_DISCRIMINATOR_SLICE (not always 8 bytes).
Locate the comment above the serialization step where updated account data is
written and replace the fixed-size wording with wording like "includes
discriminator from LIGHT_DISCRIMINATOR_SLICE (variable length)" so it accurately
describes the behavior of the serialization logic that writes the discriminator.
sdk-libs/macros/src/lib.rs (1)

366-398: 🧹 Nitpick | 🔵 Trivial

Doc comment doesn't mention the new light_pinocchio attribute for custom discriminators.

The LightPinocchioAccount derive now accepts #[light_pinocchio(discriminator = [...])] to override the default 8-byte SHA256 discriminator, but the doc block doesn't document this. Users will have to discover it elsewhere.

📝 Suggested doc addition
 /// ## Requirements
 ///
 /// - The `compression_info` field must be non-Option `CompressionInfo` type
 /// - The `compression_info` field must be first or last field in the struct
 /// - Struct should be `#[repr(C)]` for predictable memory layout
 /// - Use `[u8; 32]` instead of `Pubkey` for address fields
+///
+/// ## Custom discriminator
+///
+/// Use `#[light_pinocchio(discriminator = [1u8])]` to override the default
+/// 8-byte SHA256 discriminator with a shorter custom discriminator (e.g. 1 byte).
+/// Types with short discriminators must be declared last in `ProgramAccounts` enums
+/// to avoid prefix-matching collisions during dispatch.
 #[proc_macro_derive(LightPinocchioAccount, attributes(compress_as, skip, light_pinocchio))]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk-libs/macros/src/lib.rs` around lines 366 - 398, Update the doc comment
for the LightPinocchioAccount derive macro to document the new
#[light_pinocchio(discriminator = [...])] attribute: explain that you can supply
an 8-byte array to override the default 8-byte SHA256 discriminator, show the
attribute syntax (e.g., #[light_pinocchio(discriminator = [0x01,0x02,...])]),
and note it applies to the LightPinocchioAccount derive
(proc_macro_derive(LightPinocchioAccount)) so users know how to provide custom
discriminators when deriving the macro.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk-libs/macros/src/light_pdas/account/derive.rs`:
- Around line 833-910: Add a unit test that verifies discriminators longer than
8 bytes are rejected: create a test (e.g.
test_light_pinocchio_custom_discriminator_too_long_rejected) that calls
derive_light_pinocchio_account with an input annotated
#[light_pinocchio(discriminator = [1,2,3,4,5,6,7,8,9])] and assert that
result.is_err() (optionally checking the error mentions max length); this uses
the same pattern as test_light_pinocchio_custom_discriminator and
test_light_pinocchio_custom_discriminator_empty_rejected so you can reuse the
parse_quote structure and assertions to ensure derive_light_pinocchio_account
enforces the 8-byte maximum.
- Around line 195-197: The code silently truncates discriminator byte arrays
longer than 8 bytes causing a mismatch between LIGHT_DISCRIMINATOR (fixed
[u8;8]) and LIGHT_DISCRIMINATOR_SLICE; add an explicit upper-bound check in
parse_pinocchio_discriminator to validate that the provided discriminator length
is <= 8 and return an error (or panic) if it exceeds 8 bytes, ensuring callers
(and the attribute parser) reject values like [1,2,...,9] instead of truncating;
reference parse_pinocchio_discriminator, LIGHT_DISCRIMINATOR,
LIGHT_DISCRIMINATOR_SLICE and InAccountInfo.discriminator when adding the
validation.

In `@sdk-libs/macros/src/light_pdas/program/compress.rs`:
- Around line 344-354: The zero-copy dispatch slices pod_bytes without ensuring
the data buffer contains the full POD; update the check in the block that uses
<#name as `#account_crate`::LightDiscriminator>::LIGHT_DISCRIMINATOR_SLICE so that
you verify data.len() >= __disc_len + core::mem::size_of::<#name>() before
creating pod_bytes and calling bytemuck::from_bytes; if the buffer is too short,
return an appropriate error instead of proceeding (mirror the error-handling
pattern used around prepare_account_for_compression), and apply the same guard
pattern used in generate_dispatch_fn for the earlier 8-byte discriminator case.
- Around line 314-325: Add a runtime check in compress_dispatch that validates
the enum variant discriminators (the values referenced by
LIGHT_DISCRIMINATOR_SLICE) are ordered from longest to shortest so no shorter
discriminator is a prefix of a later longer one; if the check fails return a
clear error (e.g., InvalidDiscriminatorOrder) or panic with a message pointing
users to reorder variants. Locate the check near the dispatch
construction/iteration in compress_dispatch and iterate the discriminators to
ensure each subsequent discriminator length is <= the previous (and optionally
check prefix conflicts), failing fast on violation. Also update the README and
examples to explicitly document the requirement that non-standard (short)
discriminator variants must be declared last and show a short example of correct
ordering.

---

Outside diff comments:
In `@sdk-libs/macros/src/lib.rs`:
- Around line 366-398: Update the doc comment for the LightPinocchioAccount
derive macro to document the new #[light_pinocchio(discriminator = [...])]
attribute: explain that you can supply an 8-byte array to override the default
8-byte SHA256 discriminator, show the attribute syntax (e.g.,
#[light_pinocchio(discriminator = [0x01,0x02,...])]), and note it applies to the
LightPinocchioAccount derive (proc_macro_derive(LightPinocchioAccount)) so users
know how to provide custom discriminators when deriving the macro.

In `@sdk-libs/sdk-types/src/interface/program/compression/pda.rs`:
- Line 95: Update the stale comment that says "includes 8-byte discriminator" to
reflect the variable-length discriminator now used; mention that serialization
includes the discriminator provided by LIGHT_DISCRIMINATOR_SLICE (not always 8
bytes). Locate the comment above the serialization step where updated account
data is written and replace the fixed-size wording with wording like "includes
discriminator from LIGHT_DISCRIMINATOR_SLICE (variable length)" so it accurately
describes the behavior of the serialization logic that writes the discriminator.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk-libs/macros/src/light_pdas/account/derive.rs`:
- Around line 839-937: Add a new test to cover an intermediate-length
discriminator (e.g., 4 bytes) to verify padding logic: create a test function
(e.g., test_light_pinocchio_custom_discriminator_4_bytes) that calls
derive_light_pinocchio_account with #[light_pinocchio(discriminator =
[10,20,30,40])] and assert result.is_ok(); then inspect the generated token
stream string to assert LIGHT_DISCRIMINATOR is padded to 8 bytes
(10,20,30,40,0,0,0,0) and LIGHT_DISCRIMINATOR_SLICE is exactly the 4-byte slice
(&[10,20,30,40]), using the same output.contains(...) pattern as the existing
tests to locate these symbols in the generated output.

Copy link
Contributor

@SwenSchaeferjohann SwenSchaeferjohann left a comment

Choose a reason for hiding this comment

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

lgtm, added one question

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk-libs/macros/src/light_pdas/program/compress.rs`:
- Around line 314-325: The compile-time assertion that checks discriminator
prefix relationships is misleading: it rejects any prefix or duplicate pair so
reordering cannot fix collisions; update the user-facing error text emitted by
the const assertion to clearly state that discriminators must be unique and not
be prefixes of one another (mentioning exact duplicates), and revise the
documentation around LIGHT_DISCRIMINATOR_SLICE / the ProgramAccounts enum /
LightProgramPinocchio to remove the suggestion that declaring shorter
discriminators last will resolve collisions and instead state the actual
invariant (no prefix relationships allowed). Locate the const assertion and its
panic/message near the discriminator-checking code and replace the message with
a concise instruction to change one of the discriminator bytes, and edit the
nearby doc comment to reflect the stronger, enforced invariant.

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.

Caution

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

⚠️ Outside diff range comments (1)
sdk-libs/macros/src/light_pdas/program/compress.rs (1)

525-565: 🧹 Nitpick | 🔵 Trivial

Pinocchio size validation correctly uses dynamic discriminator length.

For completeness: the non-Pinocchio paths (Lines 545, 557) hardcode 8 for the discriminator component. This is correct today because Anchor discriminators are always 8 bytes, but the enum dispatch path at Line 401 now reads LIGHT_DISCRIMINATOR_SLICE.len() dynamically. If Anchor ever supports variable-length discriminators, the size check would silently diverge from dispatch. Consider aligning the non-Pinocchio paths to also use LIGHT_DISCRIMINATOR_SLICE.len() for forward-compatibility, or adding a brief comment explaining the 8 assumption.

♻️ Optional: align non-pinocchio size checks with dispatch for consistency
             } else if info.is_zero_copy {
                 // For Pod types, use core::mem::size_of for size calculation
                 quote! {
                     const _: () = {
-                        const COMPRESSED_SIZE: usize = 8 + core::mem::size_of::<#qualified_type>();
+                        // Anchor discriminators are always 8 bytes.
+                        const COMPRESSED_SIZE: usize = 8 + core::mem::size_of::<#qualified_type>();
                         if COMPRESSED_SIZE > 800 {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk-libs/macros/src/light_pdas/program/compress.rs` around lines 525 - 565,
The size checks for non-Pinocchio branches use a hardcoded 8 for the
discriminator, which diverges from the enum dispatch that uses <#qualified_type
as `#account_crate`::LightDiscriminator>::LIGHT_DISCRIMINATOR_SLICE.len(); update
the two quote! blocks in the info.is_zero_copy and the Borsh/compressed branch
to compute COMPRESSED_SIZE using that same LIGHT_DISCRIMINATOR_SLICE.len()
instead of 8 (i.e., const COMPRESSED_SIZE: usize = <#qualified_type as
`#account_crate`::LightDiscriminator>::LIGHT_DISCRIMINATOR_SLICE.len() + ...), or
alternatively add a short comment next to the `8` explaining the 8-byte
discriminator assumption if you prefer not to change behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@sdk-libs/macros/src/light_pdas/program/compress.rs`:
- Around line 525-565: The size checks for non-Pinocchio branches use a
hardcoded 8 for the discriminator, which diverges from the enum dispatch that
uses <#qualified_type as
`#account_crate`::LightDiscriminator>::LIGHT_DISCRIMINATOR_SLICE.len(); update the
two quote! blocks in the info.is_zero_copy and the Borsh/compressed branch to
compute COMPRESSED_SIZE using that same LIGHT_DISCRIMINATOR_SLICE.len() instead
of 8 (i.e., const COMPRESSED_SIZE: usize = <#qualified_type as
`#account_crate`::LightDiscriminator>::LIGHT_DISCRIMINATOR_SLICE.len() + ...), or
alternatively add a short comment next to the `8` explaining the 8-byte
discriminator assumption if you prefer not to change behavior.

---

Duplicate comments:
In `@sdk-libs/macros/src/light_pdas/program/compress.rs`:
- Around line 340-352: The bounds-checking logic around the discriminator and
POD bytes is correct so no code change is needed; leave the block in compress.rs
(the snippet using __disc_slice, __disc_len, __expected_len, pod_bytes, and
prepare_account_for_compression) as-is because it validates data.len() >=
__expected_len before slicing and returns early to avoid panics.

@SwenSchaeferjohann SwenSchaeferjohann merged commit 6434c7b into main Feb 20, 2026
24 checks passed
@SwenSchaeferjohann SwenSchaeferjohann deleted the jorrit/test-light-program-1-byte-discriminator branch February 20, 2026 18:04
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.

2 participants