Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions programs/system/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# Light System Program

## Summary

- Core validation and coordination layer for Light Protocol
- Verifies ZK proofs for compressed account state transitions
- Manages CPI context for multi-program transactions
- Coordinates with account-compression program via CPI
- Handles SOL compression/decompression
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

Fix markdown formatting for consistency.

Multiple markdown formatting issues flagged by linter:

  • Missing blank lines around headings (lines 9, 15, 20, 144, 153, 174)
  • Code blocks without language specifiers (lines 76, 99)
  • Code blocks not surrounded by blank lines (lines 16, 76, 99, 154)

These issues affect readability and consistency with markdown best practices.

📝 Suggested formatting fixes
  1. Add blank lines before headings (lines 9, 15, 20, 144, 153, 174):
- - Handles SOL compression/decompression
+ - Handles SOL compression/decompression
+ 
  ## Used In
  1. Add language specifiers to code blocks (lines 76, 99):
- ```
+ ```text
  # Run all system program tests
  1. Add blank lines around code blocks (lines 16, 76, 99, 154):
  - **Compressed Token Program** - All compressed token operations (mint, transfer, burn) invoke this program via CPI
+ 
  **Example transaction flow:**

Also applies to: 15-16, 20-20, 76-76, 99-99, 144-144, 153-154, 174-174

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

9-9: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
In `@programs/system/CLAUDE.md` at line 9, The markdown in CLAUDE.md needs spacing
and fence fixes: add a blank line before the heading that currently reads
"Handles SOL compression/decompression" (and similarly add blank lines before
headings at the other flagged positions), ensure every fenced code block is
surrounded by a blank line (fix blocks at the positions flagged) and add
language specifiers (use "text" for the plain shell/example blocks) to the
fenced code blocks currently missing them; locate these edits by searching for
the heading text "Handles SOL compression/decompression" and the three fenced
code blocks shown in the diff and adjust spacing and fence headers accordingly.


## Used In

The Light System Program is invoked by:

- **Compressed Token Program** - All compressed token operations (mint, transfer, burn) invoke this program via CPI
- **Custom Anchor Programs** - Programs using Light SDK invoke this for compressed PDA operations via `InvokeCpi` or `InvokeCpiWithAccountInfo`
- **Direct Clients** - For simple compressed SOL transfers using the `Invoke` instruction
- **Multi-Program Transactions** - Any transaction requiring multiple programs to coordinate via shared CPI context

**Example transaction flow:**
1. Program A calls `InvokeCpiWithAccountInfo` with `first_set_context=true` to write to CPI context
2. Program B calls `InvokeCpiWithAccountInfo` with `set_context=true` to append additional data
3. Program C calls `InvokeCpiWithAccountInfo` with `execute=true` to execute the combined state transition with a single ZK proof

Comment on lines +11 to +24
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the structure of programs/system directory
find programs/system -type f -name "*.md" | head -20
echo "---"
# Check if docs directory exists
ls -la programs/system/ 2>/dev/null | grep -E "^d"

Repository: Lightprotocol/light-protocol

Length of output: 897


🏁 Script executed:

#!/bin/bash
# Search for InvokeCpiWithAccountInfo in the codebase to find its actual implementation
rg "InvokeCpiWithAccountInfo" --type rust -A 5 -B 2 | head -100

Repository: Lightprotocol/light-protocol

Length of output: 7792


🏁 Script executed:

#!/bin/bash
# Also search for the parameter names mentioned in the example
rg "first_set_context|set_context.*execute" --type rust -B 3 -A 3 | head -100

Repository: Lightprotocol/light-protocol

Length of output: 9050


🏁 Script executed:

#!/bin/bash
# Read the INVOKE_CPI_WITH_ACCOUNT_INFO.md documentation
cat programs/system/docs/invoke_cpi/INVOKE_CPI_WITH_ACCOUNT_INFO.md

Repository: Lightprotocol/light-protocol

Length of output: 7118


🏁 Script executed:

#!/bin/bash
# Read the CPI_CONTEXT.md documentation
cat programs/system/docs/CPI_CONTEXT.md

Repository: Lightprotocol/light-protocol

Length of output: 8482


🏁 Script executed:

#!/bin/bash
# Search for "execute" parameter in the context of CPI/InvokeCpiWithAccountInfo
rg "execute" --type rust programs/system/src -B 2 -A 2 | head -80

Repository: Lightprotocol/light-protocol

Length of output: 1682


Correct the multi-program transaction flow example to accurately reflect the CompressedCpiContext state machine.

The example transaction flow describes a valid use case, and the referenced documentation files do exist. However, line 23 contains an inaccuracy: there is no execute=true parameter. According to the CPI_CONTEXT.md documentation, the final invocation should have both first_set_context and set_context set to false (or omitted, since false is the default), not execute=true. Update the example to show:

Program C calls `InvokeCpiWithAccountInfo` with `first_set_context=false` and `set_context=false` to execute the combined state transition with a single ZK proof

This accurately reflects the three-state machine: First Set (clear and write), Set Context (append), and Execute (both flags false).

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

15-15: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


16-16: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
In `@programs/system/CLAUDE.md` around lines 11 - 24, Update the example
transaction flow to match the CompressedCpiContext state machine: replace the
incorrect "execute=true" in the Program C step with a call to
InvokeCpiWithAccountInfo where first_set_context=false and set_context=false (or
omit both since false is default) to represent the Execute state; reference the
CompressedCpiContext semantics (see CPI_CONTEXT.md) and keep the other steps
(Program A: first_set_context=true, Program B: set_context=true) unchanged.

## Documentation

**Navigation Guide:** [docs/CLAUDE.md](docs/CLAUDE.md)

**Core Concepts:**
- [docs/PROCESSING_PIPELINE.md](docs/PROCESSING_PIPELINE.md) - 19-step processing flow (the heart of the program)
- [docs/CPI_CONTEXT.md](docs/CPI_CONTEXT.md) - Multi-program transaction coordination
- [docs/ACCOUNTS.md](docs/ACCOUNTS.md) - CpiContextAccount layouts and structures
- [docs/INSTRUCTIONS.md](docs/INSTRUCTIONS.md) - Instruction discriminators and error codes

**Instruction Details:**
- [docs/init/](docs/init/) - CPI context account initialization
- [docs/invoke/](docs/invoke/) - Direct invocation
- [docs/invoke_cpi/](docs/invoke_cpi/) - CPI invocation modes

## Key Sections

### Accounts

**CpiContextAccount (Version 2):**
- Stores instruction data across multiple CPI invocations
- Enables multi-program transactions with single ZK proof
- Default capacity: 14020 bytes (configurable via initialization parameters)
- Associated with a specific state Merkle tree

**See:** [docs/ACCOUNTS.md](docs/ACCOUNTS.md)

### Instructions

**CPI Context Management (2):**
- `InitializeCpiContextAccount` - Create new CPI context account
- `ReInitCpiContextAccount` - Migrate from version 1 to version 2

**Direct Invocation (1):**
- `Invoke` - Process compressed accounts for single program (no CPI)

**CPI Invocation (3):**
- `InvokeCpi` - Standard CPI invocation (Anchor mode)
- `InvokeCpiWithReadOnly` - CPI with read-only account support
- `InvokeCpiWithAccountInfo` - CPI with dynamic account configuration (V2 mode)

**See:** [docs/INSTRUCTIONS.md](docs/INSTRUCTIONS.md) for complete list with discriminators

### Source Code Structure

```
programs/system/src/
├── lib.rs # [ENTRY] Instruction dispatch, process_instruction()
├── constants.rs # Discriminators, program ID
├── errors.rs # Error definitions (6000-6066)
├── context.rs # Wrapped instruction data context
├── utils.rs # Helper functions
├── accounts/
│ ├── mod.rs # Account traits and exports
│ ├── init_context_account.rs # CPI context account initialization
│ ├── account_checks.rs # Account validation helpers
│ ├── account_traits.rs # Traits for account access
│ ├── mode.rs # AccountMode (Anchor/V2)
│ └── remaining_account_checks.rs # Remaining account validation
├── invoke/
│ ├── mod.rs
│ ├── instruction.rs # InvokeInstruction accounts
│ └── verify_signer.rs # Authority signature check
├── invoke_cpi/
│ ├── mod.rs
│ ├── instruction.rs # InvokeCpiInstruction (Anchor mode)
│ ├── instruction_v2.rs # InvokeCpiInstructionV2 (V2 mode)
│ ├── processor.rs # CPI invocation processing
│ └── verify_signer.rs # CPI signer check (PDA derivation)
├── processor/
│ ├── mod.rs
│ ├── process.rs # [CORE] Main processing pipeline (19 steps)
│ ├── cpi.rs # CPI to account-compression program
│ ├── verify_proof.rs # ZK proof verification
│ ├── sum_check.rs # Lamport conservation check
│ ├── sol_compression.rs # SOL compress/decompress
│ ├── read_only_account.rs # Read-only account verification
│ ├── read_only_address.rs # Read-only address verification
│ ├── create_address_cpi_data.rs # Address derivation and CPI data
│ ├── create_inputs_cpi_data.rs # Input account processing
│ └── create_outputs_cpi_data.rs # Output account processing
├── cpi_context/
│ ├── mod.rs
│ ├── state.rs # CpiContextAccount (V1 and V2)
│ ├── process_cpi_context.rs # CPI context processing logic
│ ├── account.rs # CpiContextInAccount, CpiContextOutAccount
│ ├── address.rs # CpiContextNewAddressParamsAssignedPacked
│ └── instruction_data_trait.rs # Trait for instruction data access
└── account_compression_state/
├── mod.rs
├── state.rs # State Merkle tree wrappers
├── address.rs # Address Merkle tree wrappers
└── queue.rs # Queue wrappers
```

## Key Features

### 1. ZK Proof Verification
Verifies zero-knowledge proofs that validate:
- Input compressed account inclusion in state Merkle trees
- New address non-inclusion in address Merkle trees
- Read-only account inclusion
- Read-only address inclusion

### 2. CPI Context Management
Enables multiple programs to share a single ZK proof:
- First program writes instruction data to CPI context account
- Additional programs append their data
- Final program executes with combined data and one proof
- Significant savings in compute units and instruction data size

### 3. Multi-Mode Support
- **Invoke Mode:** Direct invocation for user-owned accounts
- **InvokeCpi Mode (Anchor):** CPI for program-owned accounts with Anchor-style account layout
- **V2 Mode:** CPI with dynamic account configuration - accounts passed via instruction data instead of fixed layout, reducing transaction size

### 4. SOL Compression
- Compress: Transfer SOL from user account to Sol Pool PDA, create compressed account
- Decompress: Extract compressed SOL, transfer from Sol Pool PDA to recipient

### 5. Read-Only Support
- Verify compressed accounts exist without modifying them
- Verify addresses exist without creating new ones
- Useful for authorization and multi-account validations

## Processing Pipeline

The 19-step processing flow (`src/processor/process.rs`) is the core of the program:

1. **Allocate CPI Data** - Pre-allocate memory for account-compression CPI
2. **Deserialize Accounts** - Parse and validate Merkle tree accounts
3. **Process Addresses** - Derive new addresses, verify read-only addresses
4. **Process Outputs** - Hash output accounts, validate indices
5. **Process Inputs** - Hash input accounts, create transaction hash
6. **Sum Check** - Verify lamport conservation (inputs + compress = outputs + decompress)
7. **SOL Compress/Decompress** - Transfer SOL to/from Sol Pool PDA
8. **Verify Read-Only** - Verify read-only accounts by index
9. **Verify ZK Proof** - Validate zero-knowledge proof covering all inputs/outputs/addresses
10. **Transfer Fees** - Pay network, address, and rollover fees
11. **Copy CPI Context** - Copy outputs for indexing (when using CPI context)
12. **CPI Account Compression** - Execute state transition via CPI to account-compression program

**See:** [docs/PROCESSING_PIPELINE.md](docs/PROCESSING_PIPELINE.md) for detailed step-by-step breakdown
Comment on lines +150 to +167
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

🧩 Analysis chain

🏁 Script executed:

# First, locate the PROCESSING_PIPELINE.md file
find programs/system -name "PROCESSING_PIPELINE.md" -type f

Repository: Lightprotocol/light-protocol

Length of output: 115


🏁 Script executed:

# Also check the CLAUDE.md file to see its full content
cat -n programs/system/CLAUDE.md | head -200

Repository: Lightprotocol/light-protocol

Length of output: 10269


🏁 Script executed:

# Search for step numbers in the docs directory
find programs/system/docs -type f -name "*.md" | head -20

Repository: Lightprotocol/light-protocol

Length of output: 571


🏁 Script executed:

# Check the detailed PROCESSING_PIPELINE.md to count the actual steps
cat -n programs/system/docs/PROCESSING_PIPELINE.md

Repository: Lightprotocol/light-protocol

Length of output: 17920


Update step count or clarify that this is a simplified overview.

Line 152 states "The 19-step processing flow" but lists only 12 steps (lines 154–166). The detailed PROCESSING_PIPELINE.md does contain 19 discrete steps, but this summary groups related steps together. Clarify whether this section should enumerate all 19 steps or note that this is a high-level summary.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

153-153: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


154-154: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
In `@programs/system/CLAUDE.md` around lines 150 - 167, The header currently
misstates "The 19-step processing flow" while the list in the "Processing
Pipeline" section (referencing src/processor/process.rs) shows 12 grouped steps;
update the text to either list all 19 discrete steps from
docs/PROCESSING_PIPELINE.md or change the sentence to indicate this is a
high-level summary (e.g., "A high-level 12-step summary of the 19-step
processing flow") and add a clarifying pointer to docs/PROCESSING_PIPELINE.md;
make the change near the "Processing Pipeline" section heading to ensure
consistency between the step count and the enumerated items.


## Error Codes

| Range | Category |
|-------|----------|
| 6000-6005 | Sum check and computation errors |
| 6006-6007 | Address errors |
| 6008-6012 | SOL compression/decompression errors |
| 6013-6019 | Validation errors |
| 6020-6028 | CPI context errors |
| 6029-6066 | Additional validation and processing errors |

**See:** [docs/INSTRUCTIONS.md](docs/INSTRUCTIONS.md) for complete list

## Testing

**Integration tests:** `program-tests/system-test/`

Tests are located in `program-tests/` because they depend on `light-test-utils` for instruction execution assertions and Solana runtime setup.

```bash
# Run all system program tests
cargo test-sbf -p system-test

# Run specific test with debugging (use long tail to see all Solana logs)
RUST_BACKTRACE=1 cargo test-sbf -p system-test -- --test test_name --nocapture 2>&1 | tail -500
```

**SDK tests:** `sdk-tests/`

```bash
# Native SDK tests
cargo test-sbf -p sdk-native-test

# Anchor SDK tests
cargo test-sbf -p sdk-anchor-test

# Token SDK tests
cargo test-sbf -p sdk-token-test
```

## Dependencies

**Program Libraries:**
- `light-account-checks` - Account validation utilities
- `light-compressed-account` - Compressed account types and instruction data
- `light-batched-merkle-tree` - Batched Merkle tree operations
- `light-hasher` - Poseidon hashing
- `light-verifier` - ZK proof verification
- `light-zero-copy` - Zero-copy serialization

**External:**
- `pinocchio` - Efficient Solana program framework
- `borsh` - Binary serialization (legacy CPI context V1)

## Program ID

```
SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7
```

## Related Programs

- **Account Compression Program** - Owns and manages Merkle tree accounts
- **Compressed Token Program** - Uses this program for all token operations
- **Registry Program** - Forester access control and protocol configuration
Loading